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库手册提供的配置方式

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

stm32f4_奇怪的bug_串口数据错乱,一个串口收到另一个串口的数据_第1张图片

 

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

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

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

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

stm32f4_奇怪的bug_串口数据错乱,一个串口收到另一个串口的数据_第2张图片

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);		//使能接收中断
}

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

你可能感兴趣的:(STM8/STM32,stm32,串口)