Linux串口编程笔记-详细.docx_第1页
Linux串口编程笔记-详细.docx_第2页
Linux串口编程笔记-详细.docx_第3页
Linux串口编程笔记-详细.docx_第4页
Linux串口编程笔记-详细.docx_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

storysnail的Linux串口编程笔记storysnail的Linux串口编程笔记 Author : He YiJun ( QQ:363559089) Develop Team : 7fane Team (,测试网站,到2013年11月底) Editor : Yang QiuXi Art Designer : He YiJun License : 7fane Team License 1.0 Last Update : 2013-03-26 这半个月因肺部感染而不得不暂时终止那令人生厌的中石油巡检工作,闭门在家安静的修养。整月的工钱自然是泡汤了,可却得来了极其珍贵的个人闲暇时光,让我能淋漓尽致的做软件方面的研究,虽是粗茶淡饭,针剂苦药,但可静心埋头于书房,却比天堂还甜美! 恍惚已至月末,工作单位来了音讯,让我一下子从甜美的梦中惊醒,从哪里来,回哪里去,这种如主体思想一样可怕的思维是我挥之不去的梦魇,无奈、不知所措、病弱的身体却不由自主的向那发声的地方靠去! 好了,还是不再发牢骚了,只是个人觉得这种臃肿低效的国企能够存在,本身就是对“国富论”绝佳的嘲讽,我只能用世界是多元的来啊Q一下了! 切入正题,这段时间做GSM/GPRG和GPS的小东西,需要通过串口发送AT指令来控制,以前调试一直在用串口助手和minicom之类的现成软件,可是一点都不爽,为什么不自己写个操作串口的软件,就像在ARM和stm32上一样! 这文章其实只是我的一个笔记,分为两篇,一篇是storysnail的Windows串口编程笔记,另一篇是storysnail的Linux串口编程笔记,由于网上已经有非常多的类似文章,有些长篇大论,有些短小精悍,连我自己都思考过是否有必要再写一篇,但在Ling的鼓动下还是写了! 本篇是Linux串口编程笔记,详细介绍了串口通信会用到的api函数,并提供了一个示例程序,这个示例程序是在EEEPC701的debian系统上编写测试的。一:写串口程序用到的函数 1:Linux与windows串口设备文件名对照操作系统 串口1 串口2 USB/RS-232转换器Windows COM1 COM2 COMX(我的系统上X=4)Linux /dev/ttyS0 /dev/ttyS1 /dev/ttyUSB0 2:写串口程序用到的函数 串行通讯函数定义在termios.h头文件中,所以需要包含该文件。下面是要介绍的函数列表open 打开串口 close 关闭串口read 接收数据write 发送数据fcntl 设置IO为阻塞或非阻塞ioctl 实现POSIX.1 GTI控制界面所有函数功能tcgetattr 读取串口设备的当前属性,保存在termios_p所指向的结构中tcsetattr 设置串口设备的当前属性cfgetospeed 返回输出波特率cfgetispeed 返回输入波特率cfsetispeed 设定输入波特率cfsetospeed 设定输出波特率 2.1open用途:打开串口原型:int open( const char * pathname,int flags);参数说明:pathname: 指向欲打开的文件路径字符串flags 所能使用的标志位: O_RDONLY 以只读方式打开文件 O_WRONLY 以只写方式打开文件 O_RDWR 以可读写方式打开文件。 O_RDONLY、O_WRONLY、O_RDWR标志位是互斥的,不可同时使用,但可与下列的 标志位|运算组合。 O_CREAT 若欲打开的文件不存在则自动建立该文件。 O_EXCL 如果O_CREAT 也被设置,此指令会去检查文件是否存在。文件若不存在则建立该文件, 否则将导致打开文件错误。此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为 符号连接,则会打开文件失败。 O_NOCTTY 表明本程序不是该串口上的“控制终端”。即本程序不受Ctrl+c、Ctrl+z这类 组合键产生的信号影响。 O_TRUNC 若文件存在并且以可写的方式打开时,此标志位会令文件长度清为0, 而原来存于该文件的 资料也会消失。 O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。 O_NONBLOCK 非阻塞模式打开。在打开很多串行端口设备时,open函数有时候会阻塞很长一段 时间.例如当打开一个调制解调器的端口就会阻塞直到DCD信号线有信号电压为止, 如果串口的另一端没有连接任何设备,那么DCD信号线上就不会有信号电压,这会 导致open函数一直阻塞在那里等待DCD信号,导致程序失去响应。使用该选项 程序会忽略DCD信号线上的信号。所以为了无阻塞地打开一个文件但不影响正常的 阻塞IO,必须先用O_NONBLOCK选项调用open函数,然后使用fcntl切换到非阻塞IO 状态。 O_NDELAY 其实和O_NONBLOCK基本相同,所产生的结果都是使I/O变成非阻塞模式,唯一的 一点差别是O_NDELAY会让函数马上返回0,而O_NONBLOCK在读不到数据时会返回-1, 并且设置errno为EAGAIN。在GNU C中O_NDELAY只是为了与BSD的程序兼容,实际上 在fcntl.h中是使用O_NONBLOCK作为宏定义,所以建议现在使用O_NONBLOCK. #define O_NDELAY O_NONBLOCK O_SYNC 以同步的方式打开文件。 O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接,则会令打开文件失败。 O_DIRECTORY如果参数pathname 所指的文件并非为一目录,则会令打开文件失败。特别说明: 关于FNDELAY 还有一个FNDELAY,实际上在fcntl.h中是使用O_NDELAY作为宏定义. #define FNDELAY O_NDELAY举例:#include #include #include #include #include #include int Com_Open(void) int fd = -1; fd = open(/dev/ttyUSB0, O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd = -1) perror(open_port: Unable to open /dev/ttyUSB0); if(Com_SetIOBlockFlag(fd,BLOCK_IO) = -1) printf(IO set errorn); return (fd);2.2close用途:关闭串口原型:int close( int fd);参数说明:fd: 文件描述符,关闭串口后计算机会将DTR信号线设置成低电位,这会告诉另一端的设备你的计算机状态。举例:int Com_Close(int fd) if (fd 0) return -1; if (close(fd) = -1) return -1; printf(close uartnn); return 0;2.3read用途:接收数据原型:ssize_t read(int fd, void *buf, ssize_t nbyte);参数说明:fd: 文件描述符buffer:读取缓冲区number:要读多少个字节,不能大于buf指向的缓冲区大小举例:n = read(fd,buf,sizeof(buf); 2.4write用途:发送数据原型:ssize_t write (int fd,const void * buf,size_t count);参数说明:fd: 文件描述符buffer:写入缓冲区count:要写多少个字节 write函数也会返回发送数据的字节数或者在发生错误的时候返回-1。通常,发送数据最常见的错误就是EIO,当调制解调器或者数据链路将Data Carrier Detect(DCD)信号线弄掉了,就会发生这个错误。而且,直至关闭端口这个情况会一直持续。举例:n = write(fd, ATr, 3);if (n 0TIME = 0 read立即返回0,nbytes 当队列中有大于MIN的字节时,read返回MIN,nbytes 否则read会一直阻塞 TIME 0 TIME没溢出时,read返回MIN,nbytes TIME没溢出时,read返回MIN,nbytes TIME溢出时,read返回1,MIN TIME溢出时,read返回1,MIN 这的TIME是read被阻塞的时间 这个TIME是队列里接收到的字节间的时间, 所以调用者可能会被一直阻塞 三:示例程序 上面介绍了大部分的串口通信会用到的函数和数据结构,Linux上写串口通讯程序时可以选择采用多进程,当然也可以使用Pthread的多线程,不过我的示例程序并没有使用这些,和windows上的示例程序类似,我还是认为这样可以更清晰的展现如何操作串口。/* * main.c Develop Team : 7fane Team Team Leader : He YiJun ( QQ:363559089) Main Programmer : He YiJun Program comments : Ling Ying License : 7fane Team License 1.0 Last Update : 2013-03-25* * 功能说明: * * 更 新:* * 已知问题:* */ #include #include #include #include #include uart-linux.h #define CMD_MAX_LEN 255 /*函数名称:ME_Init()函数功能:设备初始化,其实这个函数只是聋子的耳朵-摆设函数说明:无入口参数:fd:串口设备文件描述符出口参数:成功返回0,失败返回-1调用实例:无*/int ME_Init(int fd) unsigned char ReadBufferCOM_MAX_BUFFER+1; unsigned char WriteBufferCOM_MAX_BUFFER+1; ssize_t rCount = 0; ssize_t wCount = 0; while (1) sleep(1); memset(ReadBuffer,0,COM_MAX_BUFFER+1); rCount = Com_Read(fd,ReadBuffer,COM_MAX_BUFFER); if(rCount 0) printf(Read com: %sn,ReadBuffer); printf(Read com char num: %dn,(int)rCount); if(strstr(char *)ReadBuffer,AT) != NULL) & (strstr(char *)ReadBuffer,OK) != NULL) break; sleep(1); memset(WriteBuffer,0,COM_MAX_BUFFER+1); WriteBuffer0 = A; WriteBuffer1 = T; WriteBuffer2 = 0x0d; WriteBuffer3 = 0; wCount = Com_Write(fd,WriteBuffer,strlen(char *)WriteBuffer); if(wCount 0) printf(Wrote com: %sn,WriteBuffer); printf(Wrote com char num: %dn,(int)wCount); return 0; /*函数名称: main()函数功能:main()函数说明:main()入口参数:无出口参数:0调用实例:无*/int main() unsigned char ReadBufferCOM_MAX_BUFFER+1; unsigned char WriteBufferCOM_MAX_BUFFER+1; char cmdCMD_MAX_LEN+1; ssize_t rCount = 0; ssize_t wCount = 0; int fd = -1; if(fd = Com_Open() = -1) return 0; if(Com_Setup(fd,115200, 8, 1, 0, 0) = -1) Com_Close(fd); return 0; if(ME_Init(fd) = -1) Com_Close(fd); return 0; while (1) memset(cmd,0,CMD_MAX_LEN+1); printf (nEnter Command: ); if (!fgets (cmd, CMD_MAX_LEN,stdin) perror (fget error); exit(1); /* Get rid of the new line at t

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论