在HAL库的基础上修改串口中断函数,使串口中断接收不定长数据,且不发生丢失现象。

        之前一直用STM32CUBE配置工程,但是一用到USART1的DMA接收中断,或者USART1的接收中断,就会出现问题,在之前的调试中发现USART1的DMA与ADC1的DMA有冲突(原因我也不造啊),后来将USART1的DMA接收中断改成USART1的接收中断,在一个工程里可以使用,另一个工程出现了数据不更新的情况(明明已经将缓冲区的数据全部读取了),感觉HAL库的串口中断很坑(本人水平较低),今天给大家分享一下如何在HAL库(STM32CUBEMX)生成的工程上修改串口函数,使串口中断接收数据不发生丢失,且还能接收不定长的数据。

首先使STM32CUBE里的USART1配置

参数配置都一样

记得配置中断就可以

这里配置好以后在生成的工程里需要以下几点改变

1在USART1.C里的void MX_USART1_UART_Init(void)函数里加入 USART1->CR1|=1<<5;

void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
  USART1->CR1|=1<<5;    //接收缓冲区非空中断使能

}

2、将stm32f1xx_it.c里的void USART1_IRQHandler(void)的内容替换为下面的内容

扫描二维码关注公众号,回复: 5851567 查看本文章

void USART1_IRQHandler(void)
{
       uint8_t res;
      if(huart1.Instance->SR&(1<<5))    //接收到一帧数据
    {    
        res=huart1.Instance->DR; 
        USART_RX_BUF[USART_RX_STA]=res;
        USART_RX_STA++;
        flag_rx=1; //接收数据的标志位
                                                        
    }
    res=USART1->SR;
    res=USART1->DR; 

}

3、写一个将缓冲区 即USART_RX_BUF[]里的数据读出的函数

/*只有将接收缓冲区的数据都读出,才会清空缓冲区*/
void telecontroller_data(void)
{    
      
       uint8_t i;
     if(flag_rx==1)
        {    for(i=0;i<USART_RX_STA;i++)
          { 
                output_data[i]=USART_RX_BUF[i];//将所有数据从缓冲区内读出,USART1_DR才会更新数据。
                printf("%x\r\n",output_data[i]);
            }
            flag_rx=0;
            USART_RX_STA=0;
        }

}

记得将void telecontroller_data(void)放在while(1)里运行

给大家看一下我的成果

猜你喜欢

转载自blog.csdn.net/qq_33374294/article/details/84137683