linux 串口编程实现代码

来源:互联网 发布:新加坡巴士软件下载 编辑:程序博客网 时间:2024/05/16 08:07

在看本程序时先阅读http://blog.csdn.net/u013711616/article/details/52190901,方便对linux串口编程有更好的理解。已下两个代码都是测试通过的。

代码一,所有的设备信息可选

/*************************************************************************    > File Name: uart.c    > Author:    >程序测试完好,能实现一次性读取所有串口内容,特测保存。请勿修改 ************************************************************************/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<termios.h>#include<string.h>#include <errno.h>int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop){     struct termios newtio,oldtio;     if (tcgetattr(fd,&oldtio) != 0)      {         perror("SetupSerial 1");         return -1;     }     bzero( &newtio, sizeof( newtio ) );     newtio.c_cflag  |=  CLOCAL | CREAD; //CLOCAL:忽略modem控制线  CREAD:打开接受者     newtio.c_cflag &= ~CSIZE; //字符长度掩码。取值为:CS5,CS6,CS7或CS8     switch (nBits)     {         case 7:             newtio.c_cflag |= CS7;             break;        case 8:            newtio.c_cflag |= CS8;            break;     }     switch (nEvent)     {        case 'O':            newtio.c_cflag |= PARENB; //允许输出产生奇偶信息以及输入到奇偶校验            newtio.c_cflag |= PARODD;  //输入和输出是奇及校验            newtio.c_iflag |= (INPCK | ISTRIP); // INPACK:启用输入奇偶检测;ISTRIP:去掉第八位            break;        case 'E':            newtio.c_iflag |= (INPCK | ISTRIP);            newtio.c_cflag |= PARENB;            newtio.c_cflag &= ~PARODD;            break;        case 'N':             newtio.c_cflag &= ~PARENB;            break;     }     switch (nSpeed)     {         case 2400:            cfsetispeed(&newtio, B2400);            cfsetospeed(&newtio, B2400);            break;        case 4800:            cfsetispeed(&newtio, B4800);            cfsetospeed(&newtio, B4800);            break;        case 9600:            cfsetispeed(&newtio, B9600);            cfsetospeed(&newtio, B9600);            break;        case 115200:            cfsetispeed(&newtio, B115200);            cfsetospeed(&newtio, B115200);            break;        default:            cfsetispeed(&newtio, B9600);            cfsetospeed(&newtio, B9600);        break;     }     if (nStop == 1)     {         newtio.c_cflag &=  ~CSTOPB; //CSTOPB:设置两个停止位,而不是一个     }     else if (nStop == 2)     {         newtio.c_cflag |=  CSTOPB;     }     newtio.c_cc[VTIME]  = 0; //VTIME:非cannoical模式读时的延时,以十分之一秒位单位     newtio.c_cc[VMIN] = 0; //VMIN:非canonical模式读到最小字符数     //tcflush(fd,TCIFLUSH); // 改变在所有写入 fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃。     tcflush(fd, TCIOFLUSH);     if((tcsetattr(fd,TCSANOW,&newtio))!=0) //TCSANOW:改变立即发生     {         perror("com set error");         return -1;     }     printf("set done!\n\r");     return 0;}ssize_t tread(int fd, void *buf, size_t nbytes, unsigned int timout){    int   nfds;    fd_set  readfds;    struct timeval  tv;    tv.tv_sec = timout;    tv.tv_usec = 0;    FD_ZERO(&readfds);    FD_SET(fd, &readfds);    nfds = select(fd+1, &readfds, NULL, NULL, &tv);    if (nfds <= 0)     {        if (nfds == 0)            errno = ETIME;        return(-1);    }    return(read(fd, buf, nbytes));}ssize_t treadn(int fd, void *buf, size_t nbytes, unsigned int timout){    size_t      nleft;    ssize_t     nread;    nleft = nbytes;    while (nleft > 0)    {        if ((nread = tread(fd, buf, nleft, timout)) < 0)         {            if (nleft == nbytes)                return(-1); /* error, return -1 */            else                break;      /* error, return amount read so far */        } else if (nread == 0)         {            break;          /* EOF */        }        nleft -= nread;        buf += nread;    }    return(nbytes - nleft);      /* return >= 0 */}int main(void){    int fd1,nset,ret;    char buf[100]={"test com data!...........\n"};    char buf1[100];    fd1 = open( "/dev/ttyATH0",  O_RDWR|O_NOCTTY|O_NDELAY);    if (fd1 == -1)        exit(1);    printf("open  ttyATH0 success!!\n");    nset = set_opt(fd1, 9600, 8, 'N', 1);    if (nset == -1)        exit(1);    printf("SET  ttyATH0 success!!\n");    int idx = 0;    while (1)    {         printf("0!\n");        memset(buf1, 0, sizeof(buf1));        idx = strlen(buf);        ret = write(fd1, buf, idx);        if (ret >= idx)        {            printf("write success len = %d!  wait data receive\n", ret);        }        printf("1!!\n");        int retv = -1;        //read with timeout        unsigned int timeout = 2;        retv = treadn(fd1, buf1, ret, timeout);        if (retv > 0)        {            printf("nread: %d\n", retv);            buf1[retv] = '\0';            printf("redatad: nread = %s\n", buf1);        }        printf("2!!!\n");        sleep(2);    }    close(fd1);    return 0;}

代码二,串口参数不可选择

/*************************************************************************    > File Name: uart.c    > Author:  ************************************************************************/#include <stdio.h> #include <stdlib.h>  #include <unistd.h>#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h>  #include <errno.h> #include <pthread.h>#include <string.h>#include <semaphore.h>#define UART_DEVNAME    "/dev/ttyATH0"// Uart file descriptorstatic int uartFD = -1;// 初始化静态锁static pthread_mutex_t uartMutex = PTHREAD_MUTEX_INITIALIZER;ssize_t tread(int fd, void *buf, size_t nbytes, unsigned int timout);ssize_t treadn(int fd, void *buf, size_t nbytes, unsigned int timout);int writemsg(int fd);void* create_uart_server_thread(void *ptr);int main(int argc, char *argv[]){    int retv = -1;    pthread_t pid;    retv = pthread_create(&pid, NULL, create_uart_server_thread, NULL);    if (retv < 0)    {        printf("create thread failed!!\n");    }    //main loop    while(1)    {        usleep(1000);    }    return 0;}ssize_t tread(int fd, void *buf, size_t nbytes, unsigned int timout){    int   nfds;    fd_set  readfds;    struct timeval  tv;    tv.tv_sec = timout;    tv.tv_usec = 0;    FD_ZERO(&readfds);    FD_SET(fd, &readfds);    nfds = select(fd+1, &readfds, NULL, NULL, &tv);    if (nfds <= 0)     {        if (nfds == 0)            errno = ETIME;        return(-1);    }    return(read(fd, buf, nbytes));}ssize_t treadn(int fd, void *buf, size_t nbytes, unsigned int timout){    size_t      nleft;    ssize_t     nread;    nleft = nbytes;    while (nleft > 0)    {        if ((nread = tread(fd, buf, nleft, timout)) < 0)         {            if (nleft == nbytes)                return(-1); /* error, return -1 */            else                break;      /* error, return amount read so far */        } else if (nread == 0)         {            break;          /* EOF */        }        nleft -= nread;        buf += nread;    }    return(nbytes - nleft);      /* return >= 0 */}int writemsg(int fd){    unsigned char packet[128] = {0, };    unsigned char padded[7]= {0,};    unsigned char MAC[6] = { 0x01,0x00, 0x00, 0xAC, 0xA3, 0xDC};    memcpy(packet+20, MAC, 6);    packet[26] = 'Z';    packet[27] = 'H';    packet[28] = 'A';    packet[29] = 'O';    packet[30] = 0x01;    packet[31] = 0x02;    packet[32] = 0x13;    packet[33] = 0x04;    packet[34] = 0x05;    memcpy(packet+35, padded, 7);    return write(fd, packet, 42);}/* *create_uart_server_thread(); */void* create_uart_server_thread(void *ptr){    //New serial port configuration information    struct termios options;retry_uart:    uartFD = -1;    //open uart    uartFD = open(UART_DEVNAME, O_RDWR | O_NOCTTY | O_NDELAY);    if(uartFD == -1)    {        printf("%s Can not open uart %s!\n", __func__, UART_DEVNAME);        usleep(1000);        goto retry_uart;    }    //Save the original serial port configuration    if (tcgetattr(uartFD, &options) != 0)    {        printf("%s tcgetattr failed !\n", __func__);        close(uartFD);        goto retry_uart;    }    memset(&options, 0x0, sizeof(options));    //Enable the receiver and set local mode...    options.c_cflag |= (CLOCAL | CREAD);    // Set the baud rate    cfsetispeed(&options, B115200);    cfsetospeed(&options, B115200);    //Setting stop bits one bit stop    options.c_cflag &= ~CSTOPB;     //set data bits 8 data bits  Mask the character size bits    options.c_cflag |= CS8;    options.c_cflag &= ~CSIZE;    //set The parits  No parity    options.c_cflag &= ~PARENB;     options.c_iflag &= ~INPCK;        //Setting data flow control No flow control    options.c_cflag &= ~CRTSCTS;       //Modify the output mode, raw data output    //使用原始模式(Raw Mode)方式来通讯,修改输出模式,原始数据输出    options.c_oflag &= ~OPOST;    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);    //To disable software flow control simply mask those bits    //防止XON和XOFF字符无法发送    options.c_iflag &= ~(IXON | IXOFF | IXANY);    //Serial port can prevent carriage return and line as the same character    //防止串口能把回车和换行当成同一个字符(防止发送字符0x0d,在接收端变成0x0a)    options.c_iflag &= ~(INLCR | ICRNL | IGNCR);    options.c_oflag &= ~(ONLCR | OCRNL);    //Setting the minimum wait time and receive characters    options.c_cc[VTIME] = 0;    options.c_cc[VMIN] = 0;    // Flush Input Stream buffer    tcflush(uartFD, TCIOFLUSH);     //Enable configure    if (tcsetattr(uartFD, TCSANOW, &options) != 0)    {        printf("%s: Uart set failed!\n", __func__);        close(uartFD);        goto retry_uart;       }      printf("%s: UART open Ok!\n", __func__);      unsigned char ubuff[128] = {0, };    unsigned int ulen = 0;    //uart process    while(1)    {        unsigned char rxbuf[128] = {0, };        int readn = 0;        int writen = -1;        int idx = 0;        //lock         pthread_mutex_lock(&uartMutex);        //write        writen = writemsg(uartFD);        if( writen < 42)        {            printf("%s: write failed! writen = %02d\n", __func__, writen);            close(uartFD);            pthread_mutex_unlock(&uartMutex);            goto retry_uart;        }        printf("write success len = %d!  wait data receive\n", writen);        //read        unsigned int timeout = 2;        readn = treadn(uartFD, rxbuf, writen, timeout);        if (readn < 0)        {            printf("%s: read failed! readn = %02d\n", __func__, readn);            close(uartFD);            pthread_mutex_unlock(&uartMutex);            goto retry_uart;        }        //unlock        pthread_mutex_unlock(&uartMutex);        for (idx = 0; idx <readn; idx++)        {            printf("%02X ",rxbuf[idx]);        }        printf("\n");    }    close(uartFD);    return 0;}
0 0
原创粉丝点击