Linux C++ 串口通信 及封装动态库(.so)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sz76211822/article/details/80895929

头文件:

#ifndef __SERIAL_H__
#define __SERIAL_H__

enum COMPORT
{
    COM0 = 0,
    COM1,
    COM2,
    COM3,
    ttyUSB0,
    ttyUSB1,
    ttyUSB2
};

#ifdef __cplusplus
    extern "C"{
#endif

    //功能: 打开串口
    //index 参考COMPORT
    int serial_OpenPort(int index);

    //功能:设置串口通信参数
    //fd:打开串口后返回的文件句柄
    //speed是波特率,参数如下:
			//0:B2400;
			//1:B4800;
			//2:B9600;
			//3:B19200;
			//4:B38400;
			//5:B57600;
			//6:B115200;
    //databits数据位:
			//0:5位
			//1:6位
			//2:7位
			//3:8位
    //stopbits停止位:
                        //1:1位
                        //2:2位
    //stopbits校验位:
                        //0:无校验
                        //1:奇校验
                        //2:偶校验
    int serial_SetPara(int fd, int speed, int databits, int stopbits, int parity);

    //功能:向串口发送数据
    //fd:打开串口后返回的文件句柄
    //data:已经分配好的缓冲数组,用于存放即将发送的串口数据
    //datalength:缓冲区的数据长度
    int serial_WriteData(int fd, const char *data, int datalength);

    //功能: 读取串口数据
    //fd:打开串口后返回的文件句柄
    //data:已经分配好的缓冲数组,用于接收串口数据
    //datalength:每次最多读取多少个字节
    int serial_ReadData(int fd, unsigned char *data, int datalength);

    //功能:关闭串口
    //fd:打开串口后返回的文件句柄
    void serial_ClosePort(int fd);


#ifdef __cplusplus
    }
#endif
#endif

源文件:

#include "serial.h"

#include  <stdio.h>

#include  <stdlib.h>

#include  <unistd.h>

#include  <sys/types.h>

#include  <sys/signal.h>

#include  <sys/stat.h>

#include  <fcntl.h>

#include  <termios.h>

#include  <errno.h>

#include  <limits.h>

#include  <string.h>



int serial_BaudRate(int baudrate)

{

    switch(baudrate)

    {

    case 0:

        return (B2400);

    case 1:

        return (B4800);

    case 2:

        return (B9600);

    case 3:

        return (B19200);

    case 4:

        return (B38400);

    case 5:

        return (B57600);

    case 6:

        return (B115200);

    default:

        return (B9600);

    }

}



int serial_SetPara(int serialfd, int speed, int databits, int stopbits, int parity)

{

    struct termios termios_new;

    bzero(&termios_new, sizeof(termios_new));//µÈŒÛÓÚmemset(&termios_new,sizeof(termios_new));

    cfmakeraw(&termios_new);//ŸÍÊÇœ«ÖÕ¶ËÉèÖÃΪԭʌģʜ

    termios_new.c_cflag = serial_BaudRate(speed);

    termios_new.c_cflag |= CLOCAL | CREAD;

  //  termios_new.c_iflag = IGNPAR | IGNBRK;



    termios_new.c_cflag &= ~CSIZE;

    switch (databits)

    {

    case 0:

        termios_new.c_cflag |= CS5;

        break;

    case 1:

        termios_new.c_cflag |= CS6;

        break;

    case 2:

        termios_new.c_cflag |= CS7;

        break;

    case 3:

        termios_new.c_cflag |= CS8;

        break;

    default:

        termios_new.c_cflag |= CS8;

        break;

    }



    switch (parity)

    {

    case 0:  				//as no parity

        termios_new.c_cflag &= ~PARENB;    //Clear parity enable

      //  termios_new.c_iflag &= ~INPCK; /* Enable parity checking */  //add by fu

        break;

    case 1:

        termios_new.c_cflag |= PARENB;     // Enable parity

        termios_new.c_cflag &= ~PARODD;

        break;

    case 2:

        termios_new.c_cflag |= PARENB;

        termios_new.c_cflag |= ~PARODD;

        break;

    default:

        termios_new.c_cflag &= ~PARENB;   // Clear parity enable

        break;

    }

    switch (stopbits)// set Stop Bit

    {

    case 1:

        termios_new.c_cflag &= ~CSTOPB;

        break;

    case 2:

        termios_new.c_cflag |= CSTOPB;

        break;

    default:

        termios_new.c_cflag &= ~CSTOPB;

        break;

    }

    tcflush(serialfd, TCIFLUSH); // Çå³ýÊäÈ뻺Žæ

    tcflush(serialfd, TCOFLUSH); // Çå³ýÊä³ö»ºŽæ

    termios_new.c_cc[VTIME] = 1;   // MINÓë TIME×éºÏÓÐÒÔÏÂËÄÖÖ£º1.MIN = 0 , TIME =0  ÓÐREADÁ¢ŒŽ»ØŽ« ·ñÔòŽ«»Ø 0 ,²»¶ÁÈ¡ÈκÎ×ÖÔª

    termios_new.c_cc[VMIN] = 1;  //    2¡¢ MIN = 0 , TIME >0  READ Ž«»Ø¶ÁµœµÄ×ÖÔª,»òÔÚÊ®·ÖÖ®Ò»ÃëºóŽ«»ØTIME ÈôÀŽ²»Œ°¶ÁµœÈκÎ×ÖÔª,ÔòŽ«»Ø0

    tcflush (serialfd, TCIFLUSH);  //    3¡¢ MIN > 0 , TIME =0  READ »áµÈŽý,Ö±µœMIN×ÖÔª¿É¶Á

    return tcsetattr(serialfd, TCSANOW, &termios_new);  //    4¡¢ MIN > 0 , TIME > 0 ÿһžñ×ÖÔªÖ®ŒäŒÆʱÆ÷ŒŽ»á±»Æô¶¯ READ »áÔÚ¶ÁµœMIN×ÖÔª,Ž«»ØÖµ»ò

}



int serial_WriteData(int fd,const char *data, int datalength )//index Žú±íŽ®¿ÚºÅ 0 Ž®¿Ú/dev/ttyAMA1 ......

{

    if(fd < 0){ return -1;}

    int len = 0, total_len = 0;//modify8.

    for (total_len = 0; total_len < datalength;)

    {

        len = 0;

        len = write(fd, &data[total_len], datalength - total_len);

        printf("WriteData fd = %d ,len =%d,data = %s\n", fd, len, data);

        if (len > 0)

        {

            total_len += len;

        }

        else if(len <= 0)

        {

            len = -1;

            break;

        }

    }

    return len;

}



int serial_ReadData(int fd,unsigned char *data, int datalength)

{

    if(fd <0){ return -1;}

    int len = 0;

    memset(data, 0, datalength);



    int max_fd = 0;

    fd_set readset = {0};

    struct timeval tv = {0};



    FD_ZERO(&readset);

    FD_SET((unsigned int)fd, &readset);

    max_fd = fd + 1;

    tv.tv_sec = 0;

    tv.tv_usec = 1000;

    if (select(max_fd, &readset, NULL, NULL, &tv) < 0)

    {

        printf("ReadData: select error\n");

    }

    int nRet = FD_ISSET(fd, &readset);

    if (nRet)

    {

        len = read(fd, data, datalength);

    }

    return len;

}



void serial_ClosePort(int fd)

{

    struct termios termios_old;

    if(fd > 0)

    {

        tcsetattr(fd, TCSADRAIN, &termios_old);

        ::close (fd);

    }

}



int  serial_OpenPort(int index)

{

    char *device;

    switch(index)

    {

        case COM0:  device="/dev/ttyAMA0";  break;

        case COM1:  device="/dev/ttyAMA1";  break;

        case COM2:  device="/dev/ttyAMA2";  break;

        case COM3:  device="/dev/ttyAMA3";  break;

        case ttyUSB0:  device="/dev/ttyUSB0";  break;

        case ttyUSB1:  device="/dev/ttyUSB1";  break;

        case ttyUSB2:  device="/dev/ttyUSB2";  break;

        default: device="/dev/ttyAMA2"; break;

    }



    int fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);//O_RDWR | O_NOCTTY | O_NDELAY   //O_NONBLOCK

    if (fd < 0){

        return -1;

    }

    struct termios termios_old;

    tcgetattr(fd, &termios_old);

    return fd;

}

编译:

g++ serial.h serial.cpp -fPIC -shared -o libserial.so

demo:https://download.csdn.net/download/sz76211822/10515829

猜你喜欢

转载自blog.csdn.net/sz76211822/article/details/80895929