linux 串口接收不到0x11、0x13、0x0d

本文详细介绍了Linux下串口编程时遇到的特殊字符处理问题,特别是如何通过设置c_iflag来避免0x0d、0x11和0x13等特殊字符丢失的情况,并给出了具体的代码示例。

网上许多流行的linux串口编程的版本中都没对c_iflag(termios成员变量)这个变量进行有效的设置,这样传送ASCII码时没什么问题,但传送二进制数据时遇到0x0d,0x11和0x13却会被丢掉。不用说也知道,这几个肯定是特殊字符,被用作特殊控制了。关掉ICRNL和IXON选项即可解决。

       c_iflag &= ~(ICRNL | IXON);

0x0d 回车符CR

0x11 ^Q VSTART字符

0x13 ^S VSTOP字符

ICRNL 将输入的CR转换为NL  

IXON 使起动/停止输出控制流起作用

在《UNIX环境高级编程第二版》第18章第11小节看到把终端I/O设置为原始模式(串口通讯就是终端I/O的原始模式)时输入属性设置为

term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

屏蔽了许多属性,怪不得有人说如果是使用串口通讯c_iflag和c_oflag都设置为0就行了!

以下是我的设置的一些重要的串口属性

term.c_cflag |= CLOCAL | CREAD;

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

term.c_oflag &= ~OPOST;

term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

### STM32串口接收0x开头数据失败的解决方案 STM32串口通信中,如果发现无法正确接收以`0x`开头的数据,通常可能是由于以下几个原因导致:中断配置问题、接收缓冲区溢出、特殊字符过滤或硬件故障等。以下是一些可能的解决方案及详细分析。 #### 1. 检查串口中断配置 确保串口中断配置正确,尤其是接收中断的使能和优先级设置。如果中断优先级过低,可能导致数据丢失或延迟处理。此外,需要确认是否启用了正确的中断标志位,例如`USART_IT_RXNE`(接收数据寄存器非空中断)[^1]。 ```c // 使能串口中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); ``` #### 2. 确保接收缓冲区大小足够 如果接收到的数据量较大,而接收缓冲区的大小不足以容纳所有数据,则可能会导致数据丢失或覆盖。建议根据实际需求调整缓冲区大小,并在代码中添加检查逻辑,防止缓冲区溢出[^2]。 ```c #define USART_REC_LEN 256 // 根据实际需求调整缓冲区大小 uint8_t USART_RX_BUF[USART_REC_LEN]; uint16_t USART_RX_STA = 0; if (USART_RX_STA > (USART_REC_LEN - 1)) { USART_RX_STA = 0; // 接收数据错误,重新开始接收 } ``` #### 3. 检查特殊字符过滤逻辑 某些情况下,程序中可能存在对特定字符(如`0x0D`或`0x0A`)的过滤逻辑。这种逻辑可能会导致以`0x`开头的数据被误判为无效数据。例如,在引用中的代码片段中,存在对`0x0D`和`0x0A`的判断逻辑[^3]。如果接收到的数据包含其他`0x`开头的值,但未满足这些条件,可能会被丢弃。 解决方法是修改过滤逻辑,确保不会误判有效数据: ```c if (Res == 0x0D) { USART_RX_STA |= 0x4000; // 接收到回车,置标志位 } else if (Res == 0x0A) { USART_RX_STA |= 0x8000; // 接收到换行,完成接收 } else { USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res; // 存储普通字符 USART_RX_STA++; } ``` #### 4. 检查波特率设置 波特率不匹配是导致串口通信异常的常见原因之一。如果发送端和接收端的波特率设置不同,可能会导致数据接收失败或错误。确保两端的波特率一致,并根据实际需求选择合适的波特率值。 ```c // 配置波特率为115200 USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate = 115200; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStruct); ``` #### 5. 使用空闲中断接收模式 如果需要接收不定长的数据包,可以考虑使用串口空闲中断模式。在这种模式下,当检测到一段时间内没有新数据到达时,触发中断并结束当前数据包的接收。 ```c void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) { // 空闲中断 uint16_t len = USART_RX_STA & 0x3FFF; USART_ClearITPendingBit(USART1, USART_IT_IDLE); // 清除空闲中断标志 USART_RX_STA |= 0x8000; // 标记接收完成 } } ``` #### 6. 检查硬件连接 最后,还需要检查硬件连接是否正常。包括但不限于: - 串口引脚是否正确连接。 - 是否存在信号干扰或噪声。 - 发送端和接收端的电平是否匹配。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值