C语言串口驱动程序

来源:互联网 发布:大数据图标 编辑:程序博客网 时间:2024/05/17 01:35

驱动层屏蔽了硬件细节,个人猜测,几乎所有移植好的系统的串口,都可以用一样的代码来操作,至少2440和树莓派是通用的。

分享代码如下:

[cpp] view plain copy
  1. #include <sys/types.h>  
  2. #include <sys/stat.h>  
  3. #include <fcntl.h>  
  4. #include <termios.h>  
  5. #include <errno.h>  
  6. #include <ctype.h>  
  7. #include <stdio.h>  
  8. #include <stdlib.h>  
  9. #include <string.h>  
  10. #include <time.h>  
  11. #include <unistd.h>  
  12. #include"pthread.h"  
  13. #include "serial.h"  
  14.   
  15.   
  16. struct serial_config serialread;  
  17.   
  18. static int serial_fd;  
  19.   
  20. int speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,  
  21.            B38400, B19200, B9600, B4800, B2400, B1200, B300};  
  22.   
  23. int name_arr[] = {230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,  
  24.           38400, 19200, 9600, 4800, 2400, 1200, 300};  
  25.   
  26. //-----------------------------------------------  
  27. //打印配置文件serial.cfg的内容  
  28. //-----------------------------------------------  
  29. void print_serialread()  
  30. {  
  31.     printf("serialread.dev is %s\n",serialread.serial_dev);  
  32.     printf("serialread.speed is %d\n",serialread.serial_speed);  
  33.     printf("serialread.databits is %d\n",serialread.databits);  
  34.     printf("serialread.stopbits is %d\n",serialread.stopbits);  
  35.     printf("serialread.parity is %c\n",serialread.parity);  
  36. }  
  37.   
  38. //-----------------------------------------------  
  39. //读取serial.cfg文件并进行配置  
  40. //-----------------------------------------------  
  41. void readserialcfg()  
  42. {  
  43.     FILE *serial_fp;  
  44.     char j[10];  
  45.       
  46.     printf("readserailcfg\n");  
  47.   
  48.     serial_fp = fopen("./serial.cfg","r");  
  49.     if(NULL == serial_fp)  
  50.     {  
  51.         printf("can't open serial.cfg");  
  52.     }  
  53.     else  
  54.     {  
  55.         fscanf(serial_fp, "DEV=%s\n", serialread.serial_dev);  
  56.   
  57.         fscanf(serial_fp, "SPEED=%s\n", j);  
  58.         serialread.serial_speed = atoi(j);  
  59.   
  60.         fscanf(serial_fp, "DATABITS=%s\n", j);  
  61.         serialread.databits = atoi(j);  
  62.   
  63.         fscanf(serial_fp, "STOPBITS=%s\n", j);  
  64.         serialread.stopbits = atoi(j);  
  65.   
  66.         fscanf(serial_fp, "PARITY=%s\n", j);  
  67.         serialread.parity = j[0];  
  68.     }  
  69.   
  70.     fclose(serial_fp);  
  71. }  
  72.   
  73. //-----------------------------------------------  
  74. //设置波特率  
  75. //-----------------------------------------------  
  76. void set_speed(int fd)  
  77. {  
  78.     int i;  
  79.     int status;  
  80.     struct termios Opt;  
  81.     struct termios oldOpt;  
  82.     tcgetattr(fd, &oldOpt);  
  83. //  printf("serialread.speed is %d\n",serialread.serial_speed);  
  84.     for( i = 0; i < sizeof(speed_arr)/sizeof(int); i++)  
  85.     {  
  86.         if(serialread.serial_speed == name_arr[i])  
  87.         {  
  88.             tcflush(fd, TCIOFLUSH);  
  89.             cfsetispeed(&Opt, speed_arr[i]);  
  90.             cfsetospeed(&Opt, speed_arr[i]);  
  91.             status = tcsetattr(fd, TCSANOW, &Opt);  
  92.             if(status != 0)  
  93.             {  
  94.                 perror("tcsetattr fd1");  
  95.                 return;  
  96.             }  
  97.             tcflush(fd, TCIOFLUSH);  
  98.         }  
  99.     }  
  100. }  
  101.   
  102.   
  103. //-----------------------------------------------  
  104. //设置其他参数  
  105. //-----------------------------------------------  
  106. int  (int fd)  
  107. {  
  108.     struct termios options;  
  109.     struct termios oldoptions;  
  110.     if(tcgetattr(fd, &oldoptions) != 0)  
  111.     {  
  112.         perror("SetupSerial 1");  
  113.         return(FALSE);  
  114.     }  
  115.   
  116.     options.c_cflag |= (CLOCAL|CREAD);  
  117.     options.c_cflag &=~CSIZE;  
  118. //  printf("serialread.databits is %d\n",serialread.databits);  
  119.     switch(serialread.databits)  
  120.     {  
  121.         case 7:  
  122.             options.c_cflag |= CS7;  
  123.             break;  
  124.         case 8:  
  125.             options.c_cflag |= CS8;  
  126.             break;  
  127.         default:  
  128.             options.c_cflag |= CS8;  
  129.             fprintf(stderr, "Unsupported data size\n");  
  130.             return(FALSE);  
  131.     }  
  132. //  printf("serialread.parity is %c\n",serialread.parity);  
  133.     switch(serialread.parity)  
  134.     {  
  135.         case 'n':  
  136.         case 'N':  
  137.             options.c_cflag &= ~PARENB;  
  138.             options.c_iflag &= ~INPCK;  
  139.             break;  
  140.         case 'o':  
  141.         case 'O':  
  142.             options.c_cflag |= (PARODD | PARENB);  
  143.             options.c_iflag |= INPCK;  
  144.             break;  
  145.         case 'e':  
  146.         case 'E':  
  147.             options.c_cflag |= PARENB;  
  148.             options.c_cflag &= ~PARODD;  
  149.             options.c_iflag |= INPCK;  
  150.             break;  
  151.         default:  
  152.             options.c_cflag &= ~PARENB;  
  153.             options.c_iflag &= ~INPCK;  
  154.             fprintf(stderr, "Unsupported parity\n");  
  155.             return(FALSE);  
  156.     }  
  157. //  printf("serialread.stopbits is %d\n",serialread.stopbits);  
  158.     switch(serialread.stopbits)  
  159.     {  
  160.         case 1:  
  161.             options.c_cflag &= ~CSTOPB;  
  162.             break;  
  163.         case 2:  
  164.             options.c_cflag |= CSTOPB;  
  165.             break;  
  166.         default:  
  167.             options.c_cflag &= ~CSTOPB;  
  168.             fprintf(stderr, "Unsupported stop bits\n");  
  169.             return(FALSE);  
  170.     }  
  171.     if(serialread.parity != 'n')  
  172.         options.c_iflag |= INPCK;  
  173.     options.c_cc[VTIME] = 0;    //150;          //15 seconds  
  174.     options.c_cc[VMIN] = 0;  
  175. #if 1  
  176.     options.c_iflag |= IGNPAR|ICRNL;  
  177.     options.c_oflag |= OPOST;   
  178.     options.c_iflag &= ~(IXON|IXOFF|IXANY);                       
  179. #endif  
  180.     tcflush(fd, TCIFLUSH);  
  181.     if(tcsetattr(fd, TCSANOW, &options) != 0)  
  182.     {  
  183.         perror("SetupSerial 3");  
  184.         return(FALSE);  
  185.     }  
  186.     return(TRUE);  
  187. }  
  188.   
  189. //-----------------------------------------------  
  190. //打开串口设备  
  191. //-----------------------------------------------  
  192. int OpenDev(char *Dev)  
  193. {  
  194.     int fd = open(Dev, O_RDWR, 0);  
  195.     if(-1 == fd)  
  196.     {  
  197.         perror("Can't Open Serial Port");  
  198.         return -1;  
  199.     }  
  200.     else  
  201.         return fd;  
  202. }  
  203.   
  204. //--------------------------------------------------  
  205. //串口初始化  
  206. //--------------------------------------------------  
  207. void serial_init()  
  208. {  
  209.     char *Dev;  
  210.   
  211.     int i;  
  212.   
  213.     readserialcfg();  
  214.     //print_serialread();  
  215.     printf("init serial\n");  
  216.   
  217.     Dev = serialread.serial_dev;  
  218.     //打开串口设备  
  219.     serial_fd = OpenDev(Dev);  
  220.   
  221.     if(serial_fd > 0)  
  222.         set_speed(serial_fd);       //设置波特率  
  223.     else  
  224.     {  
  225.         printf("Can't Open Serial Port!\n");  
  226.         exit(0);  
  227.     }  
  228.     //恢复串口未阻塞状态  
  229.     if (fcntl(serial_fd, F_SETFL, O_NONBLOCK) < 0)  
  230.     {  
  231.         printf("fcntl failed!\n");  
  232.         exit(0);  
  233.     }  
  234.     //检查是否是终端设备  
  235. #if 0   //如果屏蔽下面这段代码,在串口输入时不会有回显的情况,调用下面这段代码时会出现回显现象。  
  236.     if(isatty(STDIN_FILENO)==0)  
  237.     {  
  238.         printf("standard input is not a terminal device\n");  
  239.     }  
  240.     else  
  241.         printf("isatty success!\n");  
  242. #endif  
  243.     //设置串口参数  
  244.     if(set_Parity(serial_fd) == FALSE)  
  245.     {  
  246.         printf("Set parity Error\n");  
  247.         exit(1);  
  248.     }  
  249.   
  250. }  
  251.   
  252. int serial_write(char* cmd, int count)  
  253. {  
  254.     printf("serial write for %d bytes\n",count);  
  255.     return write(serial_fd,cmd,count);  
  256. }  
  257.   
  258. void serial_close()  
  259. {  
  260.     printf("close serial\n");  
  261.     close(serial_fd);  
  262. }  
  263.   
  264. /* 
  265. void serial_rw() 
  266. { 
  267.     int i; 
  268.     char buff[512]; 
  269.      
  270.     int nread,nwrite; 
  271.  
  272.      char buff2[] = "hello!\n"; 
  273.     nwrite = write(serial_fd,buff2,sizeof(buff2)); 
  274.     printf("nwrite=%d\n",nwrite); 
  275.     while(1) 
  276.     { 
  277.         if((nread = read(serial_fd,buff,512))>0) 
  278.         {  
  279.             buff[nread] = '\0'; 
  280. #if 1   //调用这段代码可以实现回显,如果配合上面的回显,就会出现回显两次的情况。 
  281.             write(serial_fd,buff,nread); 
  282. #endif 
  283.             printf("recv:%d\n",nread); 
  284. #if 1 
  285.             for(i=0;i<nread;i++) 
  286.             { 
  287.                 printf("%c",buff[i]); 
  288.             } 
  289.             printf("\n"); 
  290. #else 
  291.             printf("%s",buff); 
  292.             printf("\n"); 
  293. #endif 
  294.         } 
  295.     } 
  296.   
  297.  
  298.  
  299. } 
  300. */  
  301. /* 
  302. int main(int argc, char **argv) 
  303. { 
  304.     serial_init(); 
  305.  
  306.     char cmd[]={0xfc,0x01,0x01,0x02,0x01,0x00,0x03,0x01,0xcf}; 
  307.     write(serial_fd,cmd,sizeof(cmd)); 
  308.     close(serial_fd); 
  309.      
  310.     return 0; 
  311. //  close(serialread.serial_dev); 
  312. //  serial_test(telnum, telmoney); 
  313. } 
  314. */  

当然,还需要对应的头文件:

[cpp] view plain copy
  1. #define FALSE       0  
  2. #define TRUE        1  
  3.   
  4. #define WORDLEN 32  
  5.   
  6. struct serial_config  
  7. {  
  8.     unsigned char serial_dev[WORDLEN];  
  9.     unsigned int serial_speed;  
  10.     unsigned char databits;  
  11.     unsigned char stopbits;  
  12.     unsigned char parity;  
  13. };  
  14.   
  15. void serial_init();  
  16. int serial_write(char* cmd, int count);  
  17. void serial_close();  

以及分离出来的配置文件:

[cpp] view plain copy
  1. DEV=/dev/ttyAMA0  
  2. SPEED=9600  
  3. DATABITS=8  
  4. STOPBITS=1  
  5. PARITY=N  
0 0
原创粉丝点击