Linux串口编程

Linux串口编程

  117人阅读   评论(0)   收藏   举报

最近使用了linux的串口,整理了一下应用程序调用的API,希望将来有用。

主要有两个文件SerDrive.h盒SerDrive.c

//=======================================================

SerDrive.h

[html]  view plain copy
  1. #ifndef SERDRIVE_H  
  2. #define SERDRIVE_H  
  3. //=======================  
  4. //串口名字  
  5. #define     TTY0_NAME   "/dev/ttySAC0"  
  6. #define     TTY1_NAME   "/dev/ttySAC1"  
  7. #define     TTY2_NAME   "/dev/ttySAC2"  
  8.   
  9.   
  10. //串口  
  11. #define     TTYS0   1  
  12. #define     TTYS1   2  
  13. #define     TTYS2   3  
  14. //波特率  
  15. #define     BAUD_2400       2400  
  16. #define     BAUD_4800       4800  
  17. #define     BAUD_9600       9600  
  18. #define     BAUD_115200     115200  
  19. #define     BAUD_460800     460800  
  20. //奇偶校验位  
  21. #define     PARITY_ODD    'O' //奇数  
  22. #define     PARITY_EVEN   'E' //偶数  
  23. #define     PARITY_NONE   'N' //无奇偶校验位  
  24. //停止位  
  25. #define     STOP_BIT_1     1  
  26. #define     STOP_BIT_2     2  
  27. //数据位  
  28. #define     DATA_BIT_7     7  
  29. #define     DATA_BIT_8     8  
  30. //========================================  
  31. //串口API  
  32.   
  33. /*打开串口函数*/  
  34. int open_port(int fd,int comport);  
  35. //串口配置的函数  
  36. int set_opt(int fd,int nSpeed, int nBits,  
  37.             char nEvent, int nStop);  
  38. //从串口中读取数据  
  39. int read_datas_tty(int fd,char *rcv_buf,int TimeOut,int Len);  
  40. //向串口传数据  
  41. int send_data_tty(int fd, char *send_buf,int Len);  
  42.   
  43.   
  44. //==============  
  45. #endif // SERDRIVE_H  

//*****************************************************

SerDrive.c

[html]  view plain copy
  1. #include "SerDrive.h"  
  2. //===========================================  
  3.   
  4. #include     <stdio.h>      /*标准输入输出定义*/  
  5. #include     <stdlib.h>     /*标准函数库定义*/  
  6. #include     <unistd.h>     /*Unix 标准函数定义*/  
  7. #include     <sys/types.h>  
  8. #include     <sys/stat.h>  
  9. #include     <fcntl.h>      /*文件控制定义*/  
  10. #include     <termios.h>    /*POSIX 终端控制定义*/  
  11. #include     <errno.h>      /*错误号定义*/  
  12.   
  13. //=============================================  
  14. #define DEVICE_TTYS 1  
  15.   
  16.   
  17.   
  18. //=============================================  
  19. /*打开串口函数*/  
  20. int open_port(int fd,int comport)  
  21. {  
  22.   
  23.        if (comport==1)//串口 1  
  24.        {  
  25.             fd = open( TTY0_NAME, O_RDWR|O_NOCTTY|O_NDELAY);  
  26.            if (-1 == fd){  
  27.                    perror("Can't Open Serial Port");  
  28.                    return(-1);  
  29.             }  
  30.        }  
  31.        else if(comport==2)//串口 2  
  32.        {  
  33.             fd = open( TTY1_NAME, O_RDWR|O_NOCTTY|O_NDELAY);  
  34.             if (-1 == fd){  
  35.                    perror("Can't Open Serial Port");  
  36.                    return(-1);  
  37.             }  
  38.        }  
  39.        else if (comport==3)//串口 3  
  40.        {  
  41.   
  42.            fd = open( TTY2_NAME, O_RDWR|O_NOCTTY|O_NDELAY);  
  43.             if (-1 == fd){  
  44.                    perror("Can't Open Serial Port");  
  45.                    return(-1);  
  46.             }  
  47.        }  
  48.     /*恢复串口为阻塞状态*/  
  49.        if(fcntl(fd, F_SETFL, 0)<0)  
  50.             printf("fcntl failed!\n");  
  51.        else  
  52.             printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));  
  53.     /*测试是否为终端设备*/  
  54.        if(isatty(STDIN_FILENO)==0)  
  55.             printf("standard input is not a terminal device\n");  
  56.        else  
  57.             printf("isatty success!\n");  
  58.        printf("fd-open=%d\n",fd);  
  59.        return fd;  
  60. }  
  61. //串口配置的函数  
  62. int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)  
  63. {  
  64.       struct termios newtio,oldtio;  
  65.       /*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/  
  66.       if  ( tcgetattr( fd,&oldtio)  !=  0) {  
  67.              perror("SetupSerial 1");  
  68.              return -1;  
  69.       }  
  70.       bzero( &newtio, sizeof( newtio ) );  
  71.       /*步骤一,设置字符大小*/  
  72.       newtio.c_cflag  |=  CLOCAL | CREAD;  
  73.       newtio.c_cflag &= ~CSIZE;  
  74.       /*设置停止位*/  
  75.       switch( nBits )  
  76.       {  
  77.       case 7:  
  78.              newtio.c_cflag |= CS7;  
  79.              break;  
  80.       case 8:  
  81.              newtio.c_cflag |= CS8;  
  82.              break;  
  83.       }  
  84.       /*设置奇偶校验位*/  
  85.       switch( nEvent )  
  86.       {  
  87.       case 'O': //奇数  
  88.              newtio.c_cflag |= PARENB;  
  89.              newtio.c_cflag |= PARODD;  
  90.              newtio.c_iflag |= (INPCK | ISTRIP);  
  91.              break;  
  92.       case 'E': //偶数  
  93.              newtio.c_iflag |= (INPCK | ISTRIP);  
  94.              newtio.c_cflag |= PARENB;  
  95.              newtio.c_cflag &= ~PARODD;  
  96.              break;  
  97.       case 'N':  //无奇偶校验位  
  98.              newtio.c_cflag &= ~PARENB;  
  99.              break;  
  100.       }  
  101.       /*设置波特率*/  
  102.       switch( nSpeed )  
  103.       {  
  104.       case 2400:  
  105.              cfsetispeed(&newtio, B2400);  
  106.              cfsetospeed(&newtio, B2400);  
  107.              break;  
  108.       case 4800:  
  109.              cfsetispeed(&newtio, B4800);  
  110.              cfsetospeed(&newtio, B4800);  
  111.              break;  
  112.       case 9600:  
  113.              cfsetispeed(&newtio, B9600);  
  114.              cfsetospeed(&newtio, B9600);  
  115.              break;  
  116.       case 115200:  
  117.              cfsetispeed(&newtio, B115200);  
  118.              cfsetospeed(&newtio, B115200);  
  119.              break;  
  120.       case 460800:  
  121.              cfsetispeed(&newtio, B460800);  
  122.              cfsetospeed(&newtio, B460800);  
  123.              break;  
  124.       default:  
  125.              cfsetispeed(&newtio, B9600);  
  126.              cfsetospeed(&newtio, B9600);  
  127.             break;  
  128.       }  
  129.       /*设置停止位*/  
  130.       if( nStop == 1 )  
  131.              newtio.c_cflag &=  ~CSTOPB;  
  132.       else if ( nStop == 2 )  
  133.              newtio.c_cflag |=  CSTOPB;  
  134.       /*设置等待时间和最小接收字符*/  
  135.       newtio.c_cc[VTIME]  = 0;  
  136.       newtio.c_cc[VMIN] = 0;  
  137.       /*处理未接收字符*/  
  138.       tcflush(fd,TCIFLUSH);  
  139.       /*激活新配置*/  
  140.       if((tcsetattr(fd,TCSANOW,&newtio))!=0)  
  141.       {  
  142.              perror("com set error");  
  143.              return -1;  
  144.       }  
  145.       printf("set done!\n");  
  146.       return 0;  
  147. }  
  148. //======================================================  
  149. //从串口中读取数据  
  150. int read_datas_tty(int fd,char *rcv_buf,int TimeOut,int Len)  
  151. {  
  152.         int retval;  
  153.         fd_set rfds;  
  154.         struct timeval tv;  
  155.         int ret,pos;  
  156.         tv.tv_sec = TimeOut/1000;//set the rcv wait time  
  157.         tv.tv_usec = TimeOut%1000*1000;//100000us = 0.1s  
  158.   
  159.         pos = 0;  
  160.         while(1){  
  161.            FD_ZERO(&rfds);  
  162.            FD_SET(fd,&rfds);  
  163.            retval = select(fd+1,&rfds,NULL,NULL,&tv);  
  164.            if(retval ==-1)  
  165.            {  
  166.                 perror("select()");  
  167.                 break;  
  168.            }  
  169.            else if(retval)  
  170.            {  
  171.                 retread(fd,rcv_buf+pos,1);  
  172.                     if(-1 == ret){  
  173.                             break;  
  174.                   }  
  175.   
  176.               pos++;  
  177.               if(Len <= pos){  
  178.                     break;  
  179.               }  
  180.            }  
  181.            else  
  182.            {  
  183.                 break;  
  184.            }  
  185.         }  
  186.   
  187.         return pos;  
  188. }  
  189.   
  190. //向串口传数据  
  191. int send_data_tty(int fd, char *send_buf,int Len)  
  192. {  
  193.     ssize_t ret;  
  194.   
  195.     ret = write(fd,send_buf,Len);  
  196.     if (ret == -1)  
  197.         {  
  198.                 printf ("write device %s error\n", DEVICE_TTYS);  
  199.                 return -1;  
  200.         }  
  201.   
  202.     return 1;  
  203. }  

//**********************************************************************

//调用例子

[html]  view plain copy
  1. #include "SerDrive.h"  
  2. //======================================  
  3. int SerFd = -1;  
  4. void    ProcessInit(int argc, char *argv[])  
  5. {  
  6.     /*打开串口函数*/  
  7.     SerFd = open_port(SerFd,TTYS1);  
  8.     if(0 < SerFd){  
  9.         set_opt(SerFd,BAUD_2400,  
  10.                 DATA_BIT_8, PARITY_NONE, STOP_BIT_1);  
  11.     }else{  
  12.         printf("open_port ERROR !\n");  
  13.     }  
  14. }  
  15.   
  16. int main ( int argc, char *argv[])  
  17. {  
  18.     int nTmp = 0;  
  19.     char Buf[1024];  
  20.     ProcessInit(argc,argv);  
  21.   
  22.     while(1){  
  23.         //从串口中读取数据  
  24.         nTmp = read_datas_tty(SerFd, Buf,100,1024);  
  25.         if(0<nTmp){  
  26.             //printf("rcv len=%d,data:%s\n",nTmp,Buf);  
  27.             //向串口传数据  
  28.             send_data_tty(SerFd, Buf,nTmp);  
  29.         }  
  30.     }  
  31. }  

你可能感兴趣的:(Linux串口编程)