STM32CubeMX是一款非常方便的工具软件。但是在使用时也会存在一些问题。比如,最近调试昆仑通态触摸屏与单片机的串口通讯,波特率为9600,数据位8位,偶校验,1位停止位。使用STM32CubeMx设置参数如下:

STM32CubeMX串口中断偶校验问题_单片机

      需要注意的是,STM32的数据位是包含校验位的,所以数据位要选择9位。


      生成代码后,添加相关的接收中断程序,参考《​​STM32CubeMX之串口通信​​》。但实际测试时,发现接收的第一个字节总是0。经过单步调试跟踪发现,串口接收发生了Over-Run错误,进入了以下程序,导致接收错误。

STM32CubeMX串口中断偶校验问题_串口_02

     之后改为自己写的中断接收程序后,没有出现错误,说明该软件生成的代码还是有一定的局限性的。自己编写的代码如下:

    首先,初始化完成后,打开串口接收中断:


__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生成的程序通过牺牲效率而尽可能实现不同系列芯片的通用性,相比而言,自己编写中断程序效率要高很多,当系统资源有限或者需要单片机低速运行时,就需要自己编写相关程序,以实现程序的高效运行。

     


STM32CubeMX串口中断偶校验问题_串口_03