STM32串口DMA+空闲中断接收数据-基于CubeMX创建

串口空闲中断(UART_IT_IDLE):串口接收数据,超过一个字节的时间内没有再接收到数据的时候发生的

好处:与传统的判断'\r','\n'为结束位相比,空闲中断判断串口数据接收完毕准确且迅速

缺点:串口持续不断的发送数据时,无法进入空闲中断。因此需要间隔一个字节以上的时间,间歇式的发送数据。这个缺点在正常使用中,根本不是问题

下面进入主题


打开STM32CubeMX,配置如下:

STM32串口DMA+空闲中断接收数据-基于CubeMX创建_第1张图片

STM32串口DMA+空闲中断接收数据-基于CubeMX创建_第2张图片

STM32串口DMA+空闲中断接收数据-基于CubeMX创建_第3张图片

程序中配置:

usart.c文件中创建接收数组和处理函数:

#define USART1_RX_MAX 2148

uint8_t Rxbuf[USART1_RX_MAX];

uint16_t Rxlen=0;

void Usart_Receive_Data(UART_HandleTypeDef *huart)
{
    if(RESET != __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))   //判断是否是空闲中断
    {
         //清除空闲中断标志(否则会一直不断进入中断)
         __HAL_UART_CLEAR_IDLEFLAG(huart);                     
         //计算接收到的数据量
         Rxlen = (USART1_RX_MAX) - (__HAL_DMA_GET_COUNTER(&hdma_usart1_rx));
         //停止接收
         HAL_UART_DMAStop(huart);

    }
}

这里需要注意添加: HAL_UART_DMAStop(huart);//停止接收

不添加的话,DMA接收不会停止,重新开启DMA接收,RX缓存将不会从0开始接收数据

stm32f1xx_it.c文件中调用Usart_Receive_Data()

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 */
  Usart_Receive_Data(&huart1);//调用函数
  /* USER CODE END USART1_IRQn 1 */
}

main.c文件中的main()函数中开启空闲中断启动DMA

main()函数中,判断Rxlen大于0,则开始处理串口数据:

int main(void)
{
    //初始化
    __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//开启空闲中断
    HAL_UART_Receive_DMA(&huart1,Rxbuf,USART1_RX_MAX);    //启动DMA接收
    while(1)
    {
        if(Rxlen>0){
            //处理串口数据
            //清空串口缓存并Rxlen=0
            memset(Rxbuf,0,USART1_RX_MAX);
            Rxlen=0;
            //重新开启DMA接收   
            HAL_UART_Receive_DMA(&huart1,Rxbuf,USART1_RX_MAX);    //启动DMA接收     
        }    
    }
}

你可能感兴趣的:(STM32问题集锦,stm32,单片机,嵌入式硬件)