Chinaunix首页 | 论坛 | 博客
  • 博客访问: 233597
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 781
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-08 10:41
个人简介

爱莉清

文章分类

全部博文(80)

文章存档

2018年(1)

2017年(18)

2016年(49)

2015年(7)

2014年(5)

我的朋友

分类: LINUX

2016-03-10 10:43:21


.串口概述
 常见数据通信方式:并行通信,串行通信
 UART的主要操作:
   >数据发送及接受
   >产生中断
   >产生波特率
   >Loopback模式
    >红外模式
   >自动流控模式
   串口参数的配置主要包括:波特率、数据位、停止位、流控协议。
 linux中的串口设备文件放于/de/目录下,串口一,串口二分别为"/dev/ttyS0","/dev/ttyS1".在linux下操作串口与操作文件相同.
.串口详细配置
 包括:波特率、数据位、校验位、停止位等。串口设置由下面的结构体实现:
      struct termios
      {
 tcflag_t  c_iflag;  //input flags
 tcflag_t  c_oflag;  //output flags
 tcflag_t  c_cflag;  //control flags
 tcflag_t  c_lflag;  //local flags
 cc_t      c_cc[NCCS]; //control characters
      }; 
        该结构体中c_cflag最为重要,可设置波特率、数据位、校验位、停止位。在设置波特率时需要在数字前加上'B',

如B9600,B15200.使用其需通过“与”“或”操作方式:



 输入模式c_iflag成员控制端口接收端的字符输入处理:

.串口控制函数
 Tcgetattr 取属性(termios结构)
 Tcsetattr 设置属性(termios结构)
 cfgetispeed 得到输入速度
 Cfgetospeed 得到输出速度
 Cfsetispeed 设置输入速度
 Cfsetospeed 设置输出速度
 Tcdrain  等待所有输出都被传输
 tcflow  挂起传输或接收
 tcflush  刷清未决输入和/或输出
 Tcsendbreak 送BREAK字符
 tcgetpgrp 得到前台进程组ID
 tcsetpgrp 设置前台进程组ID


.串口配置流程
 1>保存原先串口配置,用tcgetattr(fd,&oldtio)函数
  struct termios newtio,oldtio;
    tcgetattr(fd,&oldtio);
 2>激活选项有CLOCAL和CREAD,用于本地连接和接收使用
   newtio.c_cflag | = CLOCAL | CREAD;
 3>设置波特率,使用函数cfsetispeed、cfsetospeed
         cfsetispeed(&newtio,B115200);
    cfsetospeed(&newtio,B115200); 
 4>设置数据位,需使用掩码设置
    newtio.c_cflag &= ~CSIZE;
   newtio.c_cflag |= CS8;
 5>设置奇偶校验位,使用c_cflag和c_iflag.
   设置奇校验:
  newtio.c_cflag |= PARENB;
  newtio.c_cflag |= PARODD;
  newtio.c_iflag |= (INPCK | ISTRIP);
   设置偶校验:
  newtio.c_iflag |= (INPCK|ISTRIP);
  newtio.c_cflag |= PARENB;
  newtio.c_cflag |= ~PARODD;
 6>设置停止位,通过激活c_cflag中的CSTOPB实现。若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。
  newtio.c_cflag &= ~CSTOPB;
 7>设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时,可设为0:
    newtio.c_cc[VTIME] = 0;
  newtio.c_cc[VMIN]  = 0;
 8>处理要写入的引用对象
   tcflush函数刷清(抛弃)输入缓存(终端驱动程序已接收到,但用户程序尚未读)或输出缓存(用户程序已经写,但尚未发送).
  int tcflush(int filedes,int quene)
  quene数应当是下列三个常数之一:
    *TCIFLUSH  刷清输入队列
    *TCOFLUSH  刷清输出队列
    *TCIOFLUSH 刷清输入、输出队列
  例如:tcflush(fd,TCIFLUSH);
 9>激活配置。在完成配置后,需要激活配置使其生效。使用tcsetattr()函数:
  int tcsetattr(int filedes,int opt,const struct termios *termptr);
   opt使我们可以指定在什么时候新的终端属性才起作用,
  *TCSANOW:更改立即发生
  *TCSADRAIN:发送了所有输出后更改才发生。若更改输出参数则应使用此选项
  *TCSAFLUSH:发送了所有输出后更改才发生。更进一步,在更改发生时未读的
             所有输入数据都被删除(刷清).
   例如: tcsetattr(fd,TCSANOW,&newtio);
.串口使用详解
.打开串口
 fd = open("/dev/ttyS0",O_RDWR | O_NOCTTY | O_NDELAY);
 参数--O_NOCTTY:通知linux系统,这个程序不会成为这个端口的控制终端.
              O_NDELAY:通知linux系统不关心DCD信号线所处的状态(端口的另一端是否激活或者停止).
 然后恢复串口的状态为阻塞状态,用于等待串口数据的读入,用fcntl函数:
  fcntl(fd,F_SETFL,0);  //F_SETFL:设置文件flag为0,即默认,即阻塞状态
 接着测试打开的文件描述符是否应用一个终端设备,以进一步确认串口是否正确打开.
  isatty(STDIN_FILENO);
.读写串口
 串口的读写与普通文件一样,使用read,write函数


main.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include "uart.h"
  3. #include <stdlib.h>
  4. int main()
  5. {
  6.     int fd;
  7.     int nread,i;
  8.     char buff[513]="\n";
  9.     
  10.     
  11.     if(fd = open_port()<0)
  12.     {
  13.         perror("open_port error");
  14.         return;
  15.     }
  16.     if((i=set_opt(fd,38400,8,'N',1))<0)
  17.     {
  18.         perror("set_opt error");
  19.         return;
  20.     }
  21.     printf("\r\nfd=%d\r\n",fd);
  22.         while(1)
  23.         {        
  24.          nread=read(fd,buff,512);

  25.                  printf("\r\nnread=%d,%s\r\n",nread,buff);
  26.                  buff[nread+1] = '\0';
  27.                         printf( "\n%s", buff);
  28.         }
  29.     close(fd);
  30.     
  31.     exit(0);

  32.     return 0;
  33. }



uart.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/types.h>
  4. #include <errno.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <termios.h>
  9. #include <stdlib.h>

  10. #include "uart.h"




  11. int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
  12. {
  13.     unsigned long ulSpeed;
  14.     
  15.     struct termios newtio,lodtio;
  16.     if(tcgetattr(fd,&lodtio))
  17.     {
  18.         perror("SetupSerial fail");
  19.         return -1;
  20.     }
  21.     
  22.     bzero(&newtio, sizeof(newtio));
  23.     newtio.c_cflag |= CLOCAL | CREAD;
  24.     
  25.     switch(nBits)
  26.     {
  27.         case 7:
  28.             newtio.c_cflag |= CS7;
  29.             break;
  30.         case 8:
  31.             newtio.c_cflag |= CS8;
  32.             break;
  33.     }
  34.     
  35.     switch(nEvent)
  36.     {
  37.         case 'O': //奇校验
  38.             newtio.c_cflag |= PARENB;
  39.             newtio.c_cflag |= PARODD;
  40.             newtio.c_cflag |= (INPCK | ISTRIP);
  41.             break;
  42.         case 'E': //偶校验
  43.             newtio.c_cflag |= (INPCK | ISTRIP);
  44.             newtio.c_cflag |= PARENB;
  45.             newtio.c_cflag &= ~PARENB;
  46.             break;
  47.         case 'N': //无校验
  48.             newtio.c_cflag &= ~PARENB;
  49.         
  50.     }
  51.     
  52.     switch(nSpeed)
  53.     {
  54.         case 115200:
  55.             ulSpeed = B115200;
  56.             break;
  57.         case 57600:
  58.             ulSpeed = B57600;
  59.             break;
  60.          case 38400:
  61.              ulSpeed = B38400;
  62.              break;
  63.          case 19200:
  64.              ulSpeed = B19200;
  65.              break;
  66.          case 9600:
  67.              ulSpeed = B9600;
  68.              break;
  69.          case 4800:
  70.              ulSpeed = B4800;
  71.              break;
  72.          case 2400:
  73.              ulSpeed = B2400;
  74.              break;
  75.          case 1800:
  76.              ulSpeed = B1800;
  77.              break;
  78.          case 1200:
  79.              ulSpeed = B1200;
  80.              break;
  81.          case 600:
  82.              ulSpeed = B600;
  83.              break;
  84.          case 300:
  85.              ulSpeed = B300;
  86.              break;
  87.          case 200:
  88.              ulSpeed = B200;
  89.              break;
  90.          case 150:
  91.              ulSpeed = B150;
  92.              break;
  93.          case 134:
  94.              ulSpeed = B134;
  95.              break;
  96.          case 110:
  97.              ulSpeed = B110;
  98.              break;
  99.          case 75:
  100.              ulSpeed = B75;
  101.              break;
  102.          case 50:
  103.              ulSpeed = B50;
  104.              break;
  105.          case 0:
  106.              ulSpeed = B0;
  107.              break;
  108.         default:
  109.               ;
  110.              //printf("set baudrate %d fail, not support this baudrate\n", (int)ulBaudrate);
  111.              break;
  112.              
  113.     }
  114.     cfsetispeed(&newtio, ulSpeed);
  115.     cfsetospeed(&newtio, ulSpeed);
  116.     
  117.     if(nStop==1)
  118.     {
  119.         newtio.c_cflag &= ~CSTOPB;
  120.     }
  121.     else if(nStop==2)
  122.     {
  123.         newtio.c_cflag |= CSTOPB;
  124.     }
  125.     
  126.     newtio.c_cc[VTIME] = 0;
  127.     newtio.c_cc[VMIN] = 0;
  128.     tcflush(fd,TCIFLUSH);
  129.     
  130.     if((tcsetattr(fd,TCSANOW,&newtio))!=0)
  131.     {
  132.         perror("com set error");
  133.         return -1;
  134.     }
  135.     
  136.     printf("set done!\n");
  137.     return 0;
  138. }



  139. int open_port(void)
  140. {
  141.     int fd;
  142.     long vdisable;
  143.   
  144.        fd = open( "/dev/ttyUSB0", O_RDWR);
  145.         if (-1 == fd)
  146.         {
  147.             perror("Can't Open Serial Port");
  148.             return(-1);
  149.         }
  150.         else
  151.         {
  152.             printf("\r\nopen ttyUSB0 .....\r\n");
  153.         }
  154.     
  155.     
  156.     if(fcntl(fd, F_SETFL, 0)<0)
  157.     {
  158.         printf("\r\nfcntl failed!\r\n");
  159.     }
  160.     else
  161.     {
  162.         printf("\r\nfcntl=%d\r\n",fcntl(fd, F_SETFL,0));
  163.     }
  164.     if(isatty(STDIN_FILENO)==0)
  165.     {
  166.         printf("\r\nstandard input is not a terminal device\r\n");
  167.     }
  168.     else
  169.     {
  170.         printf("\r\nisatty success!\r\n");
  171.     }
  172.     printf("\r\nfd-open=%d\r\n",fd);
  173.     return fd;
  174. }


阅读(2241) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~