• stm32f4_奇怪的bug_串口数据错乱,一个串口收到另一个串口的数据


    1、开发环境简介

    芯片型号:stm32f407igt6

    官方库函数:HAL库

    2、bug现象描述和原因推测

    使用了2个串口,一个是串口5-波特率115200,一个是串口4-波特率9600,但是串口4时不时会收到上一次发给串口5的数据。不是同一个串口,而且波特率都不一样,为什么呢?

    原因推测:

    a.应用层面代码错误,接收缓存共用了内存空间?

    b.串口配置有误触发的内部混乱?

    3、排除推测a

    检查代码,各用各的缓存,没写错。

    而且串口4是因为进入了接收中断,所以才收到数据,而这个中断标志位是stm32f4产生的。

    串口4在实际没有收到数据的情况下,中断被触发了,并且收到了另一个串口,串口5的数据。

    4、更改接收IO口的配置解决

    4.1、HAL库手册提供的配置方式

    完完全全按照要求配的,不行。

     

    4.2、接收IO口上拉改为无上下拉

    接收IO口上拉改为无上下拉,串口4就正常了。

    因为是时不时出现,考虑可能只是降低bug复现概率,所以运行了一晚上,都是正常的,大概两万次吧,一次都没出现了,但是:

    • 官方要求是是要配置上拉的;
    • 从原理上说,串口空闲高电平,接收是应该上拉;
    • 还碰巧找到另一个人也遇到类似的问题,也是一个串口收到另一个串口数据,但是他是改成上拉之后解决的。

    5、附串口配置代码

    5.1、HAL库内部调用的MspInit

    1. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
    2. {
    3. GPIO_InitTypeDef GPIO_InitStruct;
    4. if(huart->Instance==HC05_USARTx){
    5. /* 串口外设时钟使能 */
    6. HC05_USARTx_RCC_CLK_ENABLE();
    7. /* GPIO外设时钟使能 */
    8. HC05_USARTx_GPIO_ClK_ENABLE();
    9. GPIO_InitStruct.Pin = HC05_USARTx_Tx_PIN;
    10. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    11. GPIO_InitStruct.Pull = GPIO_NOPULL;
    12. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    13. GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
    14. HAL_GPIO_Init(HC05_USARTx_PORT, &GPIO_InitStruct);
    15. GPIO_InitStruct.Pin = HC05_USARTx_Rx_PIN;
    16. GPIO_InitStruct.Pull = GPIO_NOPULL; //成功
    17. //GPIO_InitStruct.Pull = GPIO_PULLUP; //失败
    18. HAL_GPIO_Init(HC05_USARTx_PORT, &GPIO_InitStruct);
    19. /* USART1_IRQn interrupt configuration */
    20. HAL_NVIC_SetPriority(HC05_USART_IRQn, 1,0);
    21. HAL_NVIC_EnableIRQ(HC05_USART_IRQn);
    22. }
    23. }

    5.2、外部的串口初始化函数

    1. void HC05_USARTx_Init(void)
    2. {
    3. husartx_HC05.Instance = HC05_USARTx;
    4. husartx_HC05.Init.BaudRate = HC05_USARTx_BAUDRATE;
    5. husartx_HC05.Init.WordLength = UART_WORDLENGTH_8B;
    6. husartx_HC05.Init.StopBits = UART_STOPBITS_1;
    7. husartx_HC05.Init.Parity = UART_PARITY_NONE;
    8. husartx_HC05.Init.Mode = UART_MODE_TX_RX;
    9. husartx_HC05.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    10. husartx_HC05.Init.OverSampling = UART_OVERSAMPLING_16;
    11. HAL_UART_Init(&husartx_HC05);
    12. /* 配置串口中断并使能,需要放在HAL_UART_Init函数后执行修改才有效 */
    13. //__HAL_UART_CLEAR_FLAG(&husartx_HC05,USART_FLAG_IDLE); // 清除空闲中断标志
    14. __HAL_UART_ENABLE_IT(&husartx_HC05,UART_IT_IDLE); // 使能空闲中断
    15. __HAL_UART_ENABLE_IT(&husartx_HC05,UART_IT_RXNE); //使能接收中断
    16. }

    看起来是解决了,但是不理解为什么,欢迎留言讨论。

  • 相关阅读:
    Vue将Element Plus 进行自定义封装
    03_Java数组与方法
    阿里巴巴一面 :十道经典面试题解析
    Python连接Neo4j工具比较 Neo4j Driver、py2neo
    【Leetcode HOT100】积最大子数组 c++
    虚拟数字人简介
    02-git创建版本库
    【老生谈算法】matlab特定人语音识别算法——语音识别算法
    电通出席2024年世界经济论坛(WEF),重申推动可持续发展创新和人才培育的承诺
    Java 网络编程
  • 原文地址:https://blog.csdn.net/E2242/article/details/132742467