Linux串口编程入门

来源:互联网 发布:淘宝女棉拖 编辑:程序博客网 时间:2024/03/29 18:45

开发环境

Fedora12

GCC 4.4.4

 

Linux的串口编程使用POSIX终端控制函数,关于POSIX终端控制函数的详细情况可以查看:

Serial Programming Guide for POSIX Operating Systems

我的翻译:

POSIX操作系统的串口编程指南

 

相关头文件

termios.h

在/usr/include目录下,包含了POSIX终端控制函数的声明,代码中只包含这个头文件即可。

bit/termios.h

在/usr/include/bit目录下,定义了POSIX终端控制函数所需的数据结构和所有选项的宏定义。

 

打开、关闭串口

[cpp] view plaincopy
  1. int fd=0;  
  2.   
  3. fd=open("/dev/ttyS0",O_RDWR | O_NOCTTY | O_NDELAY);  
  4.   
  5. close(fd);  

O_NOCTTY:如果打开的是终端设备,不会成为进程的控制终端。

O_NDELAY:该程序不关心DCD信号的状态,即另一端的串口是否打开。

 

配置串口

配置串口需要使用termios结构,它包含了串口的所有参数选项,它的定义在bits/termios.h文件中:

[cpp] view plaincopy
  1. typedef unsigned char   cc_t;  
  2. typedef unsigned int    speed_t;  
  3. typedef unsigned int    tcflag_t;  
  4.   
  5. #define NCCS 32  
  6. struct termios  
  7.   {  
  8.     tcflag_t c_iflag;       /* input mode flags */  
  9.     tcflag_t c_oflag;       /* output mode flags */  
  10.     tcflag_t c_cflag;       /* control mode flags */  
  11.     tcflag_t c_lflag;       /* local mode flags */  
  12.     cc_t c_line;            /* line discipline */  
  13.     cc_t c_cc[NCCS];        /* control characters */  
  14.     speed_t c_ispeed;       /* input speed */  
  15.     speed_t c_ospeed;       /* output speed */  
  16.   };  

POSIX标准提供了如下两个函数用于获得和设置串口的属性:

int tcgetattr(int fd,struct termios *);

int tcsetattr(int fd,int actions,const struct termios *);

fd为文件描述符;

tcgetattr将当前串口的参数放在一个termios结构中;

tcsetattr根据termios指针指向的结构设置当前的串口,optional_action有三个可选参数:

TCSANOW:立即进行修改;

TCSADRAIIN:等待当前输出完成后再修改;

TCSAFLUSH:等待当前输出完成后再修改,但丢弃还未从read调用返回的当前可以的任何输入。

 

1)设置波特率

设置波特率不可用直接操作termios结构的c_ispeed和c_ospeed成员,需要用函数cfsetispeed和cfsetospeed分别设置输入和输出的波特率,最好设置为相同:

[cpp] view plaincopy
  1. struct termios options;  
  2.   
  3. speed_t baudrate=0;  
  4.   
  5. .  
  6.   
  7. .  
  8.   
  9. .  
  10.   
  11. tcgetattr(fd,&options);  
  12.   
  13. cfsetispeed(&options,baudrate);  
  14.   
  15. cfsetospeed(&options,baudrate);  
  16.   
  17. tcsetattr(fd,TCSANOW,&options);  
  18.   
  19. tcflush(fd,TCIOFLUSH);  

函数参数baudrate是波特率,它的值可以使用bits/termios.h中的宏定义,常用的有:

#define  B0 0000000 /* hang up */

#define  B4800 0000014

#define  B9600 0000015

#define  B19200 0000016

#define  B38400 0000017

#define  B57600   0010001

#define  B115200  0010002

 

tcflush函数用于清空输入、输出缓冲区,有三个选项:

TCIFLUSH:清空输入

TCOFLUSH:清空输出

TCIOFLUSH:清空输入和输入

 

2)设置数据位、校验位、停止位

这些属性的设置都要修改termios结构中的c_cflag成员变量。

设置数据位:

[cpp] view plaincopy
  1. //五位数据位  
  2.   
  3. options.c_cflag &= ~CSIZE;    
  4.   
  5. options.c_cflag |= CS5;  
  6.   
  7. //六位数据位  
  8.   
  9. options.c_cflag &= ~CSIZE;  
  10.   
  11. options.c_cflag |= CS6;  
  12.   
  13. //七位数据位  
  14.   
  15. options.c_cflag &= ~CSIZE;  
  16.   
  17. options.c_cflag |= CS7;  
  18.   
  19. //八位数据位  
  20.   
  21. options.c_cflag &= ~CSIZE;  
  22.   
  23. options.c_cflag |= CS8;  

 

 

设置奇偶校验位:

[cpp] view plaincopy
  1. //无校验  
  2.   
  3. options.c_cflag &= ~PARENB;  
  4.   
  5. options.c_iflag &= ~INPCK;   
  6.   
  7. //奇校验  
  8.   
  9. options.c_cflag |= PARENB;  
  10.   
  11. options.c_cflag &= ~PARODD;  
  12.   
  13. options.c_iflag |= INPCK;    
  14.   
  15. //偶校验  
  16.   
  17. options.c_cflag |= PARENB;  
  18.   
  19. options.c_cflag |= PARODD;  
  20.   
  21. options.c_iflag |= INPCK;    

如果使能了奇 偶校验,最好用options.c_iflag |= INPCK使能输入奇偶校验。

 

 

设置停止位:

[cpp] view plaincopy
  1. //一位停止位  
  2.   
  3. options.c_cflag &= ~CSTOPB;  
  4.   
  5. //两位停止位  
  6.   
  7. options.c_cflag |= CSTOPB;  
  8.   
  9.    

 

3)设置流控制

 

[cpp] view plaincopy
  1. /无流控制  
  2.   
  3. options.c_iflag &= ~(IXON | IXOFF | IXANY);   //disable software flow control  
  4.   
  5. options.c_cflag &= ~CRTSCTS;  //disable hardware flow control  
  6.   
  7. options.c_cflag |= CLOCAL;  
  8.   
  9. //软件流控制  
  10.   
  11. options.c_cflag &= ~CRTSCTS;  
  12.   
  13. options.c_cflag &= ~CLOCAL;  
  14.   
  15. options.c_iflag |= (IXON | IXOFF | IXANY);  
  16.   
  17. //硬件流控制  
  18.   
  19. options.c_cflag &= ~CLOCAL;  
  20.   
  21. options.c_iflag &= ~(IXON | IXOFF | IXANY);  
  22.   
  23. options.c_cflag |= CRTSCTS;  
  24.   
  25.    

 

4)本地模式

 

选择Canonical Input:

Canonical Input是以行进行操作的。输入的字符被放在一个可以由用户进行交互编辑的缓冲区,直到收到回车(CR)或换行(LF)字符。选择这个模式的话,你需要选择ICANON,ECHO和ECHOE选项:

options.c_lflag |= (ICANON | ECHO | ECHOE);

选择Raw Input:

Raw input 是不做任何处理的。输入字符被收到后就直接传送。你需要取消ICANON、ECHO、ECHOE和ISIG选项来选择Raw Input模式:

options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

如果只是做串口调试,只需接受原始数据,选择Raw Input即可。

 

5)输出模式

输出模式c_oflag中设置,主要用于对串口在Canonical Input模式时输出的特殊字符处理,而对Raw Input模式无效。如果设置了Raw Input,需要取消c_oflag中的OPOST

options.c_oflag &= ~OPOST;

取消OPOST选项时,c_oflag中的其他选项都将被忽略。

原创粉丝点击