关于HAL库的空闲中断接收串口数据

介绍空闲中断接收串口的两种方法,使用HAL官方提供的函数实现:

方法一:单纯使用空闲中断。

方法二:空闲中断+DMA

方法一:使用空闲中断IDLE来接收不定长数据

使用到的HAL函数是:HAL_UARTEx_ReceiveToIdle_IT。我们通过这个函数来开启空闲接收中断。

HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

参数1是串口句柄,参数2是接收缓存区,参数3是预期接收字节大小(也可以理解为接收的字节最大是多少)。这个函数的作用是:当接收到的数据长度达到 Size 指定的数量,或者UART在接收数据过程中进入空闲状态时,会触发一个中断

我们看一下HAL_UARTEx_ReceiveToIdle_IT函数的源码,我们截取其中一部分来看,如下:

红圈部分:设置空闲中断和接收完成中断。然后是开启接收中断(主要是使能)


然后,当触发中断时,(大家可以自行查看中断服务函数的源码)会执行HAL_UARTEx_RxEventCallback这个回调函数,我们需要重写该函数,在里面实现一些具体功能,然后需要重写开启HAL_UARTEx_ReceiveToIdle_IT,保证下一次接收。Size表示接收一帧数据的长度。

提供一个回调函数例子,供参考:

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
    if(huart->Instance == huart1.Instance){
        printf("%d\n",Size);
    }
    HAL_UARTEx_ReceiveToIdle_IT(&huart1,buf,10);    //重新开启
}

方法二:空闲中断IDLE+DMA来接收数据

首先完成串口接收DMA初始化工作。

使用到的HAL函数是:HAL_UARTEx_ReceiveToIdle_DMA。

HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

这个函数和上面的HAL_UARTEx_ReceiveToIdle_IT函数是类似的,区别是这个函数会开启的DMA接收中断。

在使用过程中,重点是:在调用该函数后,要关闭DMA的半传输完成中断。如果不关闭,那么当接收到一半Size以上长度的数据时,除了产生一次空闲中断,还也会产生一次半传输完成中断,这两个中断都会调用一次HAL_UARTEx_RxEventCallback回调函数,共调用了两次。

提供一个回调函数例子,供参考:

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
    if(huart->Instance == huart1.Instance){
        printf("size:%d\n",Size);
    }
    HAL_UARTEx_ReceiveToIdle_DMA(&huart1,buf,10);    //重新开启
    __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);    //失能DMA本身的半传输中断
}

以上是所有内容,有问题联系微信:cccjw08

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 HAL 库进行串口空闲中断接收不定长数据的方法与使用串口接收中断类似,只不过在串口空闲中断中可以直接获取到接收到的数据长度,无需像串口接收中断那样手动计数。 具体步骤如下: 1. 定义一个全局变量 `uint8_t buffer[MAX_SIZE]`,用于存储接收到的数据。其中 `MAX_SIZE` 是 buffer 的最大长度。 2. 在串口空闲中断回调函数中,获取接收到的数据长度和数据指针,然后将数据存入 buffer 中。比如: ```c void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { uint32_t length = huart->RxXferSize - huart->RxXferCount; uint8_t *data = huart->pRxBuffPtr - length; memcpy(buffer, data, length); // 处理接收到的数据 process_data(buffer, length); HAL_UART_Receive_IT(huart, buffer, MAX_SIZE); } ``` 在上面的代码中,`length` 变量表示接收到的数据长度,`data` 指向接收到的数据。可以使用 `memcpy` 函数将接收到的数据复制到 buffer 中,然后调用 `process_data` 函数进行数据处理。处理完成后,再次调用 `HAL_UART_Receive_IT` 函数,等待接收下一段数据。 3. 在处理接收到的数据时,需要注意数据的长度可能不足 `MAX_SIZE`,需要根据实际接收到的数据长度进行处理。比如: ```c void process_data(uint8_t *data, uint32_t length) { // 处理接收到的数据,长度为 length } ``` 在上面的代码中,`data` 指向接收到的数据,`length` 表示实际接收到的数据长度。可以根据实际情况进行数据处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值