




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux 下串口编程入门文档选项打印本页将此页作为电子邮件发送级别: 初级左锦(), 副总裁, 南沙资讯科技园2003 年 7 月 03 日Linux 操作系统从一开始就对串行口提供了很好的支持,本文就 Linux 下的串行口通讯编程进行简单的介绍。串口简介串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用。常用的串口是 RS-232-C 接口(又称 EIA RS-232-C)它是在 1970 年由美国电子工业协会(EIA)联合贝尔系统、 调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。它的全名是数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准该标准规定采用一个 25 个脚的 DB25 连接器,对连接器的每个引脚的信号内容加以规定,还对各种信号的电平加以规定。传输距离在码元畸变小于 4% 的情况下,传输电缆长度应为 50 英尺。Linux 操作系统从一开始就对串行口提供了很好的支持,本文就 Linux 下的串行口通讯编程进行简单的介绍,如果要非常深入了解,建议看看本文所参考的Serial Programming Guide for POSIX Operating Systems计算机串口的引脚说明序号信号名称符号流向功能2发送数据TXDDTEDCEDTE发送串行数据3接收数据RXDDTEDCEDTE 接收串行数据4请求发送RTSDTEDCEDTE 请求 DCE 将线路切换到发送方式5允许发送CTSDTEDCEDCE 告诉 DTE 线路已接通可以发送数据6数据设备准备好DSRDTEDCEDCE 准备好7信号地信号公共地8载波检测DCDDTEDCE表示 DCE 接收到远程载波20数据终端准备好DTRDTEDCEDTE 准备好22振铃指示RIDTEDCE表示 DCE 与线路接通,出现振铃回页首串口操作串口操作需要的头文件#include /*标准输入输出定义*/#include /*标准函数库定义*/#include /*Unix 标准函数定义*/#include #include #include /*文件控制定义*/#include /*PPSIX 终端控制定义*/#include /*错误号定义*/回页首打开串口在 Linux 下串口文件是位于 /dev 下的串口一 为 /dev/ttyS0串口二 为 /dev/ttyS1打开串口是通过使用标准的文件打开函数操作:int fd;/*以读写方式打开串口*/fd = open( /dev/ttyS0, O_RDWR);if (-1 = fd) /* 不能打开串口一*/ perror( 提示错误!);回页首设置串口最基本的设置串口包括波特率设置,效验位和停止位设置。串口的设置主要是设置 struct termios 结构体的各成员值。struct termiounsigned short c_iflag;/* 输入模式标志 */unsigned short c_oflag;/* 输出模式标志 */unsigned short c_cflag;/* 控制模式标志*/unsigned short c_lflag;/* local mode flags */unsigned char c_line; /* line discipline */unsigned char c_ccNCC; /* control characters */;设置这个结构体很复杂,我这里就只说说常见的一些设置:波特率设置下面是修改波特率的代码:struct termios Opt;tcgetattr(fd, &Opt);cfsetispeed(&Opt,B19200); /*设置为19200Bps*/cfsetospeed(&Opt,B19200);tcsetattr(fd,TCANOW,&Opt);设置波特率的例子函数:/*brief 设置串口通信速率*param fd 类型 int 打开串口的文件句柄*param speed 类型 int 串口速度*return void*/int speed_arr = B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, ;int name_arr = 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, ;void set_speed(int fd, int speed)int i; int status; struct termios Opt;tcgetattr(fd, &Opt); for ( i= 0; i 0) printf(nLen %dn,nread); buffnread+1 = 0; printf( n%s, buff); /close(fd); / exit (0);参考资料 Serial Programming Guide for POSIX Operating Systems Linux 的源代码 代码下载:代码Linux 串口编程 - 中英文简体对照版(续)时间:2004-08-013.Program Examples示例程序All examples have been derived fromminiterm.c. The type ahead buffer is limited to 255 characters, just like the maximum string length for canonical input processing (or).See the comments in the code for explanation of the use of the different input modes. I hope that the code is understandable. The example for canonical input is commented best, the other examples are commented only where they differ from the example for canonical input to emphasize the differences.The descriptions are not complete, but you are encouraged to experiment with the examples to derive the best solution for your application.Dont forget to give the appropriate serial ports the right permissions (e. g.:chmod a+rw /dev/ttyS1)!所有的示例来自于miniterm.c. The type ahead 缓存器限制在 255 字节的大小, 这与标准输入(canonical input)进程的字符串最大长度相同 (或).代码中的注释解释了不同输入模式的使用以希望这些代码能够易于理解。标准输入程序的示例做了最详细的注解, 其它的示例则只是在不同于标准输入示例的地方做了强调。叙述不是很完整, 但可以激励你对这范例做实验, 以延生出合于你所需应用程序的最佳解.不要忘记赋予串口正确的权限(也就是:chmod a+rw /dev/ttyS1)!3.1.Canonical Input Processing标准输入模式#include #include #include #include #include /* baudrate settings are defined in , which is included by */ 波特率的设置定义在 . 包含在 里#define BAUDRATE B38400/* change this definition for the correct port */ 定义您所需要的串口号#define MODEMDEVICE /dev/ttyS1#define _POSIX_SOURCE 1 /*POSIX compliant source POSIX系统兼容*/#define FALSE 0#define TRUE 1volatile int STOP=FALSE;main() int fd,c, res;struct termios oldtio,newtio;char buf255;/* Open modem device for reading and writing and not as controllingtty because we dont want to get killed if linenoise sends CTRL-C.开启设备用于读写,但是不要以控制 tty 的模式,因为我们并不希望在发送 Ctrl-C后结束此进程*/fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );if (fd 0 and TIME = 0, MIN sets the number of characters to receive before the read is satisfied. As TIME is zero, the timer is not used.If MIN = 0 and TIME 0, TIME serves as a timeout value. The read will be satisfied if a single character is read, or TIME is exceeded (t = TIME *0.1 s). If TIME is exceeded, no character will be returned.If MIN 0 and TIME 0, TIME serves as an inter-character timer. The read will be satisfied if MIN characters are received, or the time between two characters exceeds TIME. The timer is restarted every time a character is received and only becomes active after the first character has been received.If MIN = 0 and TIME = 0, read will be satisfied immediately. The number of characters currently available, or the number of characters requested will be returned. According to Antonino (see contributions), you could issue afcntl(fd, F_SETFL, FNDELAY);before reading to get the same result.By modifyingnewtio.c_ccVTIMEandnewtio.c_ccVMINall modes described above can be tested.在非标准输入模式中,输入的数据并不组合成行,也不会进行erase, kill, delete等输入处理。我们只是用两个参数来控制这种模式的输入行为:c_ccVTIME设定字符输入间隔时间的计时器,而c_ccVMIN设置满足读取函数的最少字节数。MIN 0, TIME = 0:读取函数在读到了MIN值的字符数后返回。MIN = 0, TIME 0:TIME决定了超时值,读取函数在读到一个字节的字符,或者等待读取时间超过TIME(t = TIME * 0.1s)以后返回,也就是说,即使没有从串口中读到数据,读取函数也会在TIME时间后返回。MIN 0, TIME 0:读取函数会在收到了MIN字节的数据后,或者超过TIME时间没收到数据后返回。此计时器会在每次收到字符的时候重新计时,也只会在收到第一个字节后才启动。MIN = 0, TIME = 0:读取函数会立即返回。实际读取到的字符数,或者要读到的字符数,会作为返回值返回。根据Antonino(参考conditions),可以使用fcntl(fd, F_SETFL, FNDELAY),在读取前获得同样的结果。改变了nettio.c_ccVTIME和newtio.c_ccVMIN,就可以测试以上的设置了。#include #include #include #include #include #define BAUDRATE B38400#define MODEMDEVICE /dev/ttyS1#define _POSIX_SOURCE 1 /* POSIX compliant source */#define FALSE 0#define TRUE 1volatile int STOP=FALSE;main() int fd,c, res;struct termios oldtio,newtio;char buf255;fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );if (fd 0) perror(MODEMDEVICE); exit(-1); tcgetattr(fd,&oldtio); /* save current port settings */bzero(&newtio, sizeof(newtio);newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;newtio.c_iflag = IGNPAR;newtio.c_oflag = 0;/* set input mode (non-canonical, no echo,.) */ 设置输入模式为非标准输入 newtio.c_lflag = 0; newtio.c_ccVTIME = 0; /* inter-character timer unused */ / 不是用字符间隔计时器newtio.c_ccVMIN = 5; /* blocking read until 5 chars received */ /收到5个字符数以后,read 函数才返回tcflush(fd, TCIFLUSH);tcsetattr(fd,TCSANOW,&newtio);while (STOP=FALSE) /* loop for input */res = read(fd,buf,255); /* returns after 5 chars have been input */bufres=0; /* so we can printf. */printf(:%s:%dn, buf, res);if (buf0=z) STOP=TRUE; tcsetattr(fd,TCSANOW,&oldtio);3.3.Asynchronous Input异步输入模式#include #include #include #include #include #include #define BAUDRATE B38400#define MODEMDEVICE /dev/ttyS1#define _POSIX_SOURCE 1 /* POSIX compliant source */#define FALSE 0#define TRUE 1volatile int STOP=FALSE;void signal_handler_IO (int status); /* definition of signal handler */ / 定义信号处理程序int wait_flag=TRUE; /* TRUE while no signal received */ / TRUE 代表没有受到信号,正在等待中main() int fd,c, res;struct termios oldtio,newtio;struct sigaction saio;/* definition of signal action */ 定义信号处理的结构char buf255;/* open the device to be non-blocking (read will return immediatly) */ 是用非阻塞模式打开设备 read 函数立刻返回,不会阻塞 fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd 0) perror(MODEMDEVICE); exit(-1); /* install the signal handler before making the device asynchronous */ / 在进行设备异步传输前,安装信号处理程序 saio.sa_handler = signal_handler_IO;saio.sa_mask = 0;saio.sa_flags = 0;saio.sa_restorer = NULL; sigaction(SIGIO,&saio,NULL);/* allow the process to receive SIGIO */ 允许进程接收 SIGIO 信号fcntl(fd, F_SETOWN, getpid(); /* Make the file descriptor asynchronous (the manual page says onlyO_APPEND and O_NONBLOCK, will work with F_SETFL.) */ 设置串口的文件描述符为异步,man上说,只有 O_APPEND 和 O_NONBLOCK 才能使用F_SETFLfcntl(fd, F_SETFL, FASYNC);tcgetattr(fd,&oldtio); /* save current port settings */ /* set new port settings for canonical input processing */ 设置新的串口为标准输入模式newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL |
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论