STM32 HAL库 USART DMA方式接收任意长度数据

老是看别人的,总是有这样那样的问题,今天mark一下:

1.STM32CubeMX 创建工程,设置USART

添加 DMA RX

中断函数里:

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    uint32_t tmp_flag = 0;
    volatile uint8_t rx_len=0;
    volatile uint32_t temp;

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

// 注意主要代码要放在  HAL_UART_IRQHandler(&huart1) 下面,不然容易出现莫名其妙的问题
    tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
    if((tmp_flag != RESET))//idle标志被置位
    { 
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
        temp = huart1.Instance->SR;  //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
        temp = huart1.Instance->DR; //读取数据寄存器中的数据
        HAL_UART_DMAStop(&huart1); //
        //__HAL_DMA_GET_COUNTER
        temp  = hdma_usart1_rx.Instance->NDTR;// 获取DMA中未传输的数据个数,NDTR寄存器分析见下面
        rx_len =  RX_BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数

        memcpy(usart1_recv.recv_buf,rx1_buffer,rx_len);
        usart1_recv.recv_len = rx_len;
        usart1_recv.flag = 1;// 接受完成标志位置1    

        __HAL_DMA_SET_COUNTER(&hdma_usart1_rx,RX_BUFFER_SIZE);
        HAL_UART_Receive_DMA(&huart1,rx1_buffer,RX_BUFFER_SIZE);
       
     }
  /* USER CODE END USART1_IRQn 1 */
}

 好了,main函数里 ,开启中断

         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//使能idle中断
    HAL_UART_Receive_DMA(&huart1,rx1_buffer,RX_BUFFER_SIZE);//打开DMA接收,数据存入rx_buffer数组中

while循环里,判断

if(usart2_recv.flag)
        {
      
    usart2_recv.flag = 0;//使用你收到的数据吧

  usart1_recv.recv_len,usart1_recv.recv_buf[]

}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用STM32HAL库进行串口DMA接收数据时,可能会出现数据缺失的情况。根据引用\[1\]中的博主的经验,他在使用STM32CubeIDE生成的代码中发现了一些问题,导致串口接收不到数据。为了解决这个问题,他建议稍作修改初始化流程,先初始化DMA,再初始化相关的串口。具体的修改流程如下所示: MX_DMA_Init(); MX_USART1_UART_Init(); MX_UART4_Init(); MX_UART5_Init(); MX_USART2_UART_Init(); MX_USART3_UART_Init(); MX_USART6_UART_Init(); 此外,引用\[2\]中提到了一些整体思路。首先,需要打开串口空闲中断,并开启DMA接收。当串口接收到空闲中断标志后,会跳转到中断函数进行处理。在中断函数中,可以使用__HAL_DMA_GET_COUNTER函数来获取DMA接收剩余的字节数,然后根据实际收到的字节数进行处理。最后,需要重新初始化缓冲区并重新开启DMA接收。 需要注意的是,根据引用\[3\]中的代码,__HAL_DMA_GET_COUNTER函数用于统计DMA接收剩余的字节数。在开始时,DMA接收的字节数是固定的,然后在空闲中断中,通过这个函数可以统计到实际收到的字节数。根据实际情况,可以根据收到的字节数定义合适的变量类型,如uint16_t。 希望以上的信息对你有帮助。如果还有其他问题,请随时提问。 #### 引用[.reference_title] - *1* [stm32HAL库 串口接收不定长数据DMA传输)](https://blog.csdn.net/qq_33954661/article/details/124882073)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [STM32 HAL库 串口DMA接收不定长数据](https://blog.csdn.net/weixin_41872408/article/details/118739340)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值