linux从串口接收数据丢失_Linux下串口编程遇到的接收数据错误及原因

在Linux环境下进行串口编程时遇到了数据接收问题,包括0x0d变为0x0a以及漏收0x11的情况。通过排查排除了硬件和设备问题,深入研究发现是串口配置问题。通过正确设置串口的打开标志、波特率、数据位、停止位和校验位,以及禁用不必要的字符映射和流控制解决了问题。本文详细介绍了Linux串口编程时的常见问题及解决步骤。
摘要由CSDN通过智能技术生成

近日在调试串口的时候发现,另一设备向我ARM板的串口发送0x0d,我接收之后变成了0x0a,这是问题一;另外当对方向我发送一串数据,如果其中有0x11,那么我总是漏收此数,这是问题二。

由于问题莫名其妙,以为是笔记本的USB转232线缆的问题,换,问题依旧。

以为是对方设备的问题,采用串口调试助手模拟通讯设备与ARM板通讯,问题依旧。

无奈才去查看资料,最终得以解决,现总结如下:

1.串口操作需要的头文件

#include //标准输入输出定义

#include //标准函数库定义

#include //Unix标准函数定义

#include #include #include //文件控制定义

#include //POSIX中断控制定义

#include //错误号定义

2.打开串口

串口位于/dev中,可作为标准文件的形式打开,其中:

串口1 /dev/ttyS0

串口2 /dev/ttyS1

代码如下:

intfd;

fd=open(“/dev/ttyS0”, O_RDWR);

if(fd==-1)

{

Perror(“串口1打开失败!”);

}

//else

//fcntl(fd, F_SETFL, FNDELAY);

除了使用O_RDWR标志之外,通常还会使用O_NOCTTY和O_NDELAY这两个标志。

O_NOCTTY:告诉Unix这个程序不想成为“控制终端”控制的程序,不说明这个标志的话,任何输入都会影响你的程序。

O_NDELAY:告诉Unix这个程序不关心DCD信号线状态,即其他端口是否运行,不说明这个标志的话,该程序就会在DCD信号线为低电平时停止。

3.设置波特率

最基本的串口设置包括波特率、校验位和停止位设置,且串口设置主要使用termios.h头文件中定义的termios结构,如下:

struct termios

{

tcflag_t c_iflag; //输入模式标志

tcflag_t c_oflag; //输出模式标志

tcflag_t c_cflag; //控制模式标志

tcflag_t c_lflag; //本地模式标志

cc_t c_line; //line discipline

cc_t c_cc[NCC]; //control characters

}

代码如下:

intspeed_arr[]={ B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };

intname_arr[]={38400,19200,9600,4800,2400,1200,300,38400,19200,9600,4800,2400,1200,300, };

voidSetSpeed(intfd,intspeed)

{

inti;

structtermios Opt;//定义termios结构

if(tcgetattr(fd,&Opt)!=0)

{

perror(“tcgetattr fd”);

return;

}

for(i=0; i

{

if(speed==name_arr[i])

{

tcflush(fd, TCIOFLUSH);

cfsetispeed(&Opt, speed_arr[i]);

cfsetospeed(&Opt, speed_arr[i]);

if(tcsetattr(fd, TCSANOW,&Opt)!=0)

{

perror(“tcsetattr fd”);

return;

}

tcflush(fd, TCIOFLUSH);

}

}

}

注意tcsetattr函数中使用的标志:

TCSANOW:立即执行而不等待数据发送或者接受完成。

TCSADRAIN:等待所有数据传递完成后执行。

TCSAFLUSH:Flush input and output buffers and make the change

4.设置数据位、停止位和校验位

以下是几个数据位、停止位和校验位的设置方法:(以下均为1位停止位)

8位数据位、无校验位:

Opt.c_cflag &= ~PARENB;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS8;

7位数据位、奇校验:

Opt.c_cflag |= PARENB;

Opt.c_cflag |= PARODD;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS7;

7位数据位、偶校验:

Opt.c_cflag |= PARENB;

Opt.c_cflag &= ~PARODD;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS7;

7位数据位、Space校验:

Opt.c_cflag &= ~PARENB;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS7;

代码如下:

intSetParity(intfd,intdatabits,intstopbits,intparity)

{

structtermios Opt;

if(tcgetattr(fd,&Opt)!=0)

{

perror("tcgetattr fd");

returnFALSE;

}

Opt.c_cflag|=(CLOCAL|CREAD);//一般必设置的标志

switch(databits)//设置数据位数

{

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值