HAL库使用DMA接收不定长数据三行代码解决问题

CUBEMX配置

开启USART2全局中断

DMA配置如图

代码

HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RECEIVE_DATA,LEN); //重新启动接受
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);        //关闭传输过半中断(要写!!)

将上面代码放入USER CODE 2注释对中,此注释对在main之后,while循环之前

调用HAL_UARTEx_RxEventCallback函数

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    rx_len = LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);  //获取接受数组长度
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RECEIVE_DATA,LEN); //重新启动接受
    __HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);        //关闭传输过半中断(要写!!)
}

这里如果报错没有找到hdma_usart2_rx这个变量

extern DMA_HandleTypeDef hdma_usart2_rx;

将这段代码放入你使用的.c对应的.h文件中即可

拓展理解(只需要DMA接收不定长数据的可以不看)

1、extern DMA_HandleTypeDef hdma_usart2_rx; 使用CubeMX生成会导致改变量定义在usart.c文件中,所以需要继承一下

2、这里HAL_UARTEx_ReceiveToIdle_DMA必须要用HAL_UARTEx_RxEventCallback接收,拓展库的对应拓展库的回调,如果你使用的是HAL_UART_Receive_DMA则需要手动开启以下中断

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);    //空闲中断

之后再USART2_IRQHandle中修改代码,以下代码很简单自己理解一下(总之不如上面简单

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
​
  /* USER CODE END USART2_IRQn 0 */
    HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
    USER_UART_IRQHandler(&huart2);
  /* USER CODE END USART2_IRQn 1 */
}
void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{   // 判断是否是串口2
    if(USART2 == huart2.Instance)                                   
    {   // 判断是否是空闲中断
        if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE))   
        {    // 清除空闲中断标志(否则会一直不断进入中断)
            __HAL_UART_CLEAR_IDLEFLAG(&huart2);
            // 调用中断处理函数
            USAR_UART_IDLECallback(huart);                          
        }
    }
}
extern uint8_t RECEIVE_DATA[LEN];                                                  
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{
    HAL_UART_DMAStop(&huart2);  
    uint8_t data_length  = LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);   
    HAL_UART_Receive_DMA(&huart2, (uint8_t*)RECEIVE_DATA, LEN);                    
}
 

3、介绍一下传输完成中断HAL_UART_RxCpltCallback。一句话:能够进入回调函数HAL_UART_RxCpltCallback的条件之一:接收到的data_buff数据的大小 = 你设定的接收数据的大小此时才能触发串口中断进入回调函数。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值