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
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{GPIO_InitTypeDef GPIO_InitStruct;if(huart->Instance==HC05_USARTx){/* 串口外设时钟使能 */HC05_USARTx_RCC_CLK_ENABLE(); /* GPIO外设时钟使能 */HC05_USARTx_GPIO_ClK_ENABLE(); GPIO_InitStruct.Pin = HC05_USARTx_Tx_PIN;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate = GPIO_AF8_UART4;HAL_GPIO_Init(HC05_USARTx_PORT, &GPIO_InitStruct);GPIO_InitStruct.Pin = HC05_USARTx_Rx_PIN; GPIO_InitStruct.Pull = GPIO_NOPULL; //成功//GPIO_InitStruct.Pull = GPIO_PULLUP; //失败HAL_GPIO_Init(HC05_USARTx_PORT, &GPIO_InitStruct); /* USART1_IRQn interrupt configuration */HAL_NVIC_SetPriority(HC05_USART_IRQn, 1,0);HAL_NVIC_EnableIRQ(HC05_USART_IRQn); }
}
5.2、外部的串口初始化函数
void HC05_USARTx_Init(void)
{ husartx_HC05.Instance = HC05_USARTx;husartx_HC05.Init.BaudRate = HC05_USARTx_BAUDRATE;husartx_HC05.Init.WordLength = UART_WORDLENGTH_8B;husartx_HC05.Init.StopBits = UART_STOPBITS_1;husartx_HC05.Init.Parity = UART_PARITY_NONE; husartx_HC05.Init.Mode = UART_MODE_TX_RX;husartx_HC05.Init.HwFlowCtl = UART_HWCONTROL_NONE;husartx_HC05.Init.OverSampling = UART_OVERSAMPLING_16;HAL_UART_Init(&husartx_HC05);/* 配置串口中断并使能,需要放在HAL_UART_Init函数后执行修改才有效 *///__HAL_UART_CLEAR_FLAG(&husartx_HC05,USART_FLAG_IDLE); // 清除空闲中断标志__HAL_UART_ENABLE_IT(&husartx_HC05,UART_IT_IDLE); // 使能空闲中断 __HAL_UART_ENABLE_IT(&husartx_HC05,UART_IT_RXNE); //使能接收中断
}
看起来是解决了,但是不理解为什么,欢迎留言讨论。