丙丁先生 发表于 2025-4-25 21:34

如果APM32F107串口中断接收丢包现象成立,那么可能的解决方法分析

如果APM32F107串口中断接收丢包现象成立,那么可能的解决方法分析:APM32F107在串口同时发送和接收的情况下串口接收丢字节,具体表现为偶发进入串口接收中断了,但是USART_FLAG_RXBNE标志位没有触发,导致读不到这个字节进而丢字节,通过计数发现进入中断的次数与实际应该收到的字节数一致。1、发送是阻塞式发送的,没有用发送中断,排除进入的是发送中断的可能。2、出现这种情况时打断点看了,其他的溢出及错误标志位并没有置位,也打印检查了,没有置位。3、排查代码了没有在其他地方主动调用USART_RxDatad读取。4、串口中断优先级已调至最高。5、只接收不发送不会丢字节,挂一晚上都不丢,只要一发送接收就会丢。发送代码:void Uart1_Send(char buf){    uint16_t data_9th = buf;    dog_feed_count_clean(); // 循环清除喂狗变量,超过DOG_PROTECT_TIME_100MS不清除则认为主循环异常,并停止喂狗。    if (g_rParameters.sPort.ucParity == UART_CHK_MARK)    {      data_9th |= (1 << (uart1_data_bit - 1));    }    else if (g_rParameters.sPort.ucParity == UART_CHK_SPACE)    {      data_9th &= ~(1 << (uart1_data_bit - 1));    }    WAIT_TX_EMPTY; // wait data register empty//等待发送完    USART_TxData(USART1, data_9th);}接收中断:void USART1_IRQHandler(void){    uint8_t data;    uint8_t longth = g_sParameters.sPort.ucDataSize;    if (USART_ReadStatusFlag(USART1, USART_FLAG_OVRE) == SET)    {      // 由软件清0,先读取USART_STS寄存器,再读USART_DATA寄存器完成清0。      USART_RxData(USART1);    }    if (USART_ReadStatusFlag(USART1, USART_FLAG_RXBNE) == SET)    {      data = (uint8_t)USART_RxData(USART1); // fetch recv data from buffer      if (g_sParameters.sPort.ucParity != UART_CHK_NONE)      {            data = data & (~(1 << longth)); // 去掉校验位      }      if (AtCmd_enter_mode(0, data) == 1)      {            packet_count = 0;      }      else      {            packet_count = 0;            uart1_rx_ringbuf_push(&uart1_rx_ringbuf, data);            // uart_rec_len ++;      }      usart_recv_total_len++;    }    timer_pack_reset_func();}解释


在APM32F107微控制器上,串口同时进行发送和接收时出现接收丢包的问题,具体表现为偶发进入串口接收中断但`USART_FLAG_RXBNE`标志位未触发,导致无法读取到该字节。以下是对问题的详细解释及可能的解决方案:

问题描述
1. 现象:在串口同时发送和接收数据时,接收端偶尔会丢失字节。具体表现为进入接收中断的次数与实际应接收的字节数一致,但有时`USART_FLAG_RXBNE`标志位未被触发,导致无法读取到该字节。
2. 排查结果:
   发送是阻塞式发送,没有使用发送中断,排除了进入发送中断的可能性。
   其他溢出及错误标志位(如`USART_FLAG_OVRE`)未被置位。
   代码中没有在其他地方主动调用`USART_RxData`读取数据。
   串口中断优先级已调至最高。
   只接收不发送时不会丢字节,挂一晚上都不丢,只要一发送接收就会丢。

可能的原因
1. 发送和接收冲突:在阻塞式发送过程中,可能会占用串口资源,导致接收中断无法及时响应。
2. 中断处理时间过长:如果接收中断处理函数执行时间过长,可能会导致后续的接收中断被延迟或丢失。
3. 硬件资源竞争:发送和接收操作可能涉及到相同的硬件资源(如DMA通道、缓冲区等),导致资源竞争。
4. 时钟配置问题:串口的时钟配置可能不稳定,导致在高负载下出现异常。
5. 软件逻辑问题**:接收中断处理函数中的逻辑可能存在问题,导致某些情况下无法正确处理接收数据。

解决方案
1. 优化发送方式:
    考虑使用非阻塞式发送或发送中断,避免在发送过程中长时间占用串口资源。
    确保发送完成后再进行接收操作,避免资源竞争。

2. 缩短中断处理时间:
    尽量简化接收中断处理函数中的代码,减少不必要的操作。
    如果需要执行复杂操作,可以将数据放入缓冲区,在主循环中处理。

3. 检查硬件资源:
    确保发送和接收操作使用不同的DMA通道或缓冲区,避免资源竞争。
    检查串口的时钟配置,确保在高负载下稳定运行。

4. 增加错误处理:
    在接收中断处理函数中增加对`USART_FLAG_OVRE`等错误标志位的处理,确保在发生错误时能够及时恢复。
    定期检查串口状态,确保通信正常。

5. 调试和日志:
   在关键位置添加日志输出,记录发送和接收的状态,帮助定位问题。
   使用示波器或逻辑分析仪检查串口信号,确保硬件连接正常。

示例代码优化
```c
void Uart1_Send(char buf) {
    uint16_t data_9th = buf;
    dog_feed_count_clean(); // 循环清除喂狗变量,超过DOG_PROTECT_TIME_100MS不清除则认为主循环异常,并停止喂狗。
    if (g_rParameters.sPort.ucParity == UART_CHK_MARK) {
      data_9th |= (1 << (uart1_data_bit - 1));
    } else if (g_rParameters.sPort.ucParity == UART_CHK_SPACE) {
      data_9th &= ~(1 << (uart1_data_bit - 1));
    }

    WAIT_TX_EMPTY; // wait data register empty//等待发送完
    USART_TxData(USART1, data_9th);
}

void USART1_IRQHandler(void) {
    uint8_t data;
    uint8_t longth = g_sParameters.sPort.ucDataSize;
    if (USART_ReadStatusFlag(USART1, USART_FLAG_OVRE) == SET) {
      // 由软件清0,先读取USART_STS寄存器,再读USART_DATA寄存器完成清0。
      USART_RxData(USART1);
    }
    if (USART_ReadStatusFlag(USART1, USART_FLAG_RXBNE) == SET) {
      data = (uint8_t)USART_RxData(USART1); // fetch recv data from buffer
      if (g_sParameters.sPort.ucParity != UART_CHK_NONE) {
            data = data & (~(1 << longth)); // 去掉校验位
      }
      if (AtCmd_enter_mode(0, data) == 1) {
            packet_count = 0;
      } else {
            packet_count = 0;
            uart1_rx_ringbuf_push(&uart1_rx_ringbuf, data);
            // uart_rec_len ++;
      }
      usart_recv_total_len++;
    }
    timer_pack_reset_func();
}
```
总结
通过优化发送方式、缩短中断处理时间、检查硬件资源、增加错误处理以及调试和日志记录,可以有效解决APM32F107在串口同时发送和接收时出现的接收丢包问题。

lemonboard 发表于 2025-4-26 20:03

这个是AI上传上来的解答吗?

心跳回响 发表于 2025-4-27 10:51

如果上流程上面的问题,出现概率应该比较大。
感觉是哪里撞车了,只是没有考虑到

快乐制造机 发表于 2025-4-27 15:49

这种情况确实棘手,通常需要检查硬件连接和软件配置。你的排查很全面,可以尝试优化中断服务程序,减少处理时间,看是否有改善。

丙丁先生 发表于 2025-4-27 19:15

lemonboard 发表于 2025-4-26 20:03
这个是AI上传上来的解答吗?

丙丁先生 发表于 2025-4-27 19:15

心跳回响 发表于 2025-4-27 10:51
如果上流程上面的问题,出现概率应该比较大。
感觉是哪里撞车了,只是没有考虑到 ...

感谢回复。

丙丁先生 发表于 2025-4-27 19:16

快乐制造机 发表于 2025-4-27 15:49
这种情况确实棘手,通常需要检查硬件连接和软件配置。你的排查很全面,可以尝试优化中断服务程序,减少处理 ...

感谢回复。

丙丁先生 发表于 2025-4-27 19:18

根据AI的结论,一步步排查,总能解决问题,这样的过程我屡试不爽。毕竟AI已经读遍世界上所有的书了。

Alden 发表于 2025-4-30 09:43

用DMA和空闲中断可能会好有点
页: [1]
查看完整版本: 如果APM32F107串口中断接收丢包现象成立,那么可能的解决方法分析