STM32CubeMX串口中断偶校验问题
原创
©著作权归作者所有:来自51CTO博客作者天外飞仙CUG的原创作品,请联系作者获取转载授权,否则将追究法律责任
STM32CubeMX是一款非常方便的工具软件。但是在使用时也会存在一些问题。比如,最近调试昆仑通态触摸屏与单片机的串口通讯,波特率为9600,数据位8位,偶校验,1位停止位。使用STM32CubeMx设置参数如下:

需要注意的是,STM32的数据位是包含校验位的,所以数据位要选择9位。
生成代码后,添加相关的接收中断程序,参考《STM32CubeMX之串口通信》。但实际测试时,发现接收的第一个字节总是0。经过单步调试跟踪发现,串口接收发生了Over-Run错误,进入了以下程序,导致接收错误。

之后改为自己写的中断接收程序后,没有出现错误,说明该软件生成的代码还是有一定的局限性的。自己编写的代码如下:
首先,初始化完成后,打开串口接收中断:
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//打开接收中断
然后,在串口中断中,屏蔽软件生成的中断函数,添加自己的中断程序:
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
//HAL_UART_IRQHandler(&huart1);//屏蔽系统生成的中断函数
/* USER CODE BEGIN USART1_IRQn 1 */
uint32_t isrflags = USART1->SR;
uint32_t cr1its = USART1->CR1;
if(USART1->SR & UART_IT_RXNE)//串口接收中断
{
__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);
if(Uart1.RxFlag!=2)
{
Uart1.RxBuf[Uart1.RxCnt]=USART1->DR;
Uart1.RxCnt++;
if(Uart1.RxCnt>300)
{
Uart1.RxCnt=299;
}
Uart1.RxFlag=1;
Uart1.uart_tick=0;
}
}
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))//发送中断
{
USART1->DR = Uart1.TxBuf[Uart1.TxCnt];
Uart1.TxCnt++;
if(Uart1.TxCnt == Uart1.TxNum)
{
Uart1.TxCnt=0;
__HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
}
}
if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))//发送完成中断
{
__HAL_UART_DISABLE_IT(&huart1, UART_IT_TC);
Uart1.TxFlag = 0;
CLR_DE1;
}
/* USER CODE END USART1_IRQn 1 */
}
中断函数中包含了发送中断部分,需要中断发送数据时,将数据放在Uart1.TxBuf中,设置发送长度Uart1.TxNum,并使能串口发送中断即可:
Uart1.TxNum]
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);
STM32CubeMx生成的程序通过牺牲效率而尽可能实现不同系列芯片的通用性,相比而言,自己编写中断程序效率要高很多,当系统资源有限或者需要单片机低速运行时,就需要自己编写相关程序,以实现程序的高效运行。
