Linux系统下串口接收数据,部分特殊字符丢失的解决方法
2008-11-19 10:33
489 查看
最近在linux系统中写了个串口接收程序,发送端依次从0x00~0xFF发送字符,但接收端某些字符老接收不到,分析及其解决方法如下:
一、只接收到数据:
05 06 07 08 09 0a
解决此问题之前我们先看终端I/O的两种输入处理模式:
(1) 规范方式输入处理。在这种方式中,终端输入以行为单位进行处理。对于每个读要求,
终端驱动程序最多返回一行。
(2) 非规范方式输入处理。输入字符不以行为单位进行装配。
如果不作特殊处理,则默认方式是规范方式。例如:若s h e l l的标准输入、输出是终端,在
用r e a d和w r i t e将标准输入复制到标准输出时,终端以规范方式进行工作,每次r e a d最多返回一行。处理整个屏幕的程序,例如v i编辑程序使用非规范方式,其原因是其命令是由不以新行符终止的一个或几个字符组成的。另外,该编辑程序使用了若干特殊字符作为编辑命令,所以它也不希望系统对特殊字符进行处理。例如, C t r l - D字符通常是终端的文件结束符,但在v i中它是向下滚动半个屏幕的命令。
0x0a即'/n',以NL来表示,也就是说类似按了enter键,本行数据才输出,所以必须修改,将终端设置在 非规范方式输入处理。
在<termios.h>中,有如下定义
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};
c_iflag由终端设备驱动程序用来控制输入特性(剥除输入字节的第8位,允许输
入奇偶校验等等)
c_oflag则控制输出特性(执行输出处理,将新行映照为C R / L F等)
c_cflag影响到UART串行线(忽略调制解调器的状态线,每个字符的一个或两个停止位等等),
c_lflag影响驱动程序和用户之间的界面(回送的开或关,可视的擦除符,允许终端产生的信
号,对后台作业输出的控制停止信号等)。
修改非规范方式输入处理,如下:struct termios options;
tcgetattr( fd,&options)
options.c_lflag &= ~(ICANON );
通过修改c_lflag本地模式,将ICANON属性去掉,ICANON就是规范化方式。
二、接收到数据:
04 05 06 07 08 09 0a 0b 0c 0a 0e 0f
10 11 12 1d 1e 1f ……
其余数据全正确
03以前的数据全部没有,而0x03相当于 ^c, 即CTRL+C, ^c, ^?由ISIG来控制,那么去除该控制,应该就可以显示03了,再次修改为:
options.c_lflag &= ~(ICANON |ISIG);
三、接收到数据:
00 01 02 03 04 05 06 07 08 09 0a 0b
0c 0a 0e 0f ……
其余数据全部正确
看,0d变成了0a
c_iflag模式中,有ICRNL项,IGNCR项,将两者去掉:
options.c_iflag &= ~(ICRNL|IGNCR)
至此:串口能接收到所有的数据。
一、只接收到数据:
05 06 07 08 09 0a
解决此问题之前我们先看终端I/O的两种输入处理模式:
(1) 规范方式输入处理。在这种方式中,终端输入以行为单位进行处理。对于每个读要求,
终端驱动程序最多返回一行。
(2) 非规范方式输入处理。输入字符不以行为单位进行装配。
如果不作特殊处理,则默认方式是规范方式。例如:若s h e l l的标准输入、输出是终端,在
用r e a d和w r i t e将标准输入复制到标准输出时,终端以规范方式进行工作,每次r e a d最多返回一行。处理整个屏幕的程序,例如v i编辑程序使用非规范方式,其原因是其命令是由不以新行符终止的一个或几个字符组成的。另外,该编辑程序使用了若干特殊字符作为编辑命令,所以它也不希望系统对特殊字符进行处理。例如, C t r l - D字符通常是终端的文件结束符,但在v i中它是向下滚动半个屏幕的命令。
0x0a即'/n',以NL来表示,也就是说类似按了enter键,本行数据才输出,所以必须修改,将终端设置在 非规范方式输入处理。
在<termios.h>中,有如下定义
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};
c_iflag由终端设备驱动程序用来控制输入特性(剥除输入字节的第8位,允许输
入奇偶校验等等)
c_oflag则控制输出特性(执行输出处理,将新行映照为C R / L F等)
c_cflag影响到UART串行线(忽略调制解调器的状态线,每个字符的一个或两个停止位等等),
c_lflag影响驱动程序和用户之间的界面(回送的开或关,可视的擦除符,允许终端产生的信
号,对后台作业输出的控制停止信号等)。
修改非规范方式输入处理,如下:struct termios options;
tcgetattr( fd,&options)
options.c_lflag &= ~(ICANON );
通过修改c_lflag本地模式,将ICANON属性去掉,ICANON就是规范化方式。
二、接收到数据:
04 05 06 07 08 09 0a 0b 0c 0a 0e 0f
10 11 12 1d 1e 1f ……
其余数据全正确
03以前的数据全部没有,而0x03相当于 ^c, 即CTRL+C, ^c, ^?由ISIG来控制,那么去除该控制,应该就可以显示03了,再次修改为:
options.c_lflag &= ~(ICANON |ISIG);
三、接收到数据:
00 01 02 03 04 05 06 07 08 09 0a 0b
0c 0a 0e 0f ……
其余数据全部正确
看,0d变成了0a
c_iflag模式中,有ICRNL项,IGNCR项,将两者去掉:
options.c_iflag &= ~(ICRNL|IGNCR)
至此:串口能接收到所有的数据。
相关文章推荐
- Linux系统下串口接收数据,部分特殊字符丢失的解决方法 .
- 『PHP』UTF8编码页面存入GBK数据时使用iconv遇到无法转码的字符时中断内容丢失及解决方法
- Ajax传递的数据包含特殊字符时的解决方法
- AJAX POST数据中有特殊符号导致数据丢失的解决方法
- infobright导入数据遇到特殊字符报错的解决方法
- infobright导入数据遇到特殊字符报错的解决方法
- 动网:关于部分论坛用户发帖、回帖时报错“数据中含有非法字符。您的用户名并不存在,或者您的论坛密码错误,或者您的帐号已被管理员锁定。” 及“您没有发表新主题的权限”解决方法
- AJAX POST数据中有特殊符号导致数据丢失的解决方法
- 2410 winCE驱动在发送的同时,接收数据有所丢失---解决方法
- AJAX处理 POST数据中有特殊符号导致数据丢失的解决方法
- 关于java接收前台$.ajax格式为多维json数组数据为null的原因及解决方法
- SPCOMM接收遇到0x13串口死掉的解决方法
- Android studio中出现非法字符时的部分解决方法
- Spring 的优秀工具类盘点,第 2 部分: 特殊字符转义和方法入参检测工具类
- MFC串口发送数据大于128数据出错的解决办法(发送0xFE接收得到0x3F等问题)
- Spring 的优秀工具类盘点,第 2 部分: 特殊字符转义和方法入参检测工具类
- JQuery的选择器对控件ID含有特殊字符的解决方法-涨姿势了!
- url 传递参数(特殊字符)解决方法
- 用GCDAsyncSocket解决AsyncSocket读取数据时丢失部分消息
- STM---串口发送数据,第一个数据无法发送的解决方法