STM32 HAL库的中断接收HAL_UART_Receive_IT 怎么用

本文详细介绍了如何使用STM32 HAL库设置串口中断接收。首先在初始化阶段启用串口2的中断,然后在主循环前开启接收中断,当接收完成时,中断服务函数会调用回调函数进行新数据的处理和下一次接收的启动。整个过程确保了串口接收的实时性和非阻塞特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为HAL库都封装好了,如果想用中断接收,不能在中断里直接读RXD寄存器。

第一步,初始化时使能串口中断

MX_USART2_UART_Init();
     if (HAL_UART_Init(&huart2) != HAL_OK)
            HAL_UART_MspInit(huart);
            		......
    				HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    				HAL_NVIC_EnableIRQ(USART2_IRQn);

第二步,重点,在主循环前开启接收中断HAL_UART_Receive_IT(&huart2, (uint8_t *)rx_buf,1);

这是接收1个字节到rx_buf中

int main(void)
{
  /* Configure the system clock */
  HAL_Init();
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();

  HAL_UART_Receive_IT(&huart2, (uint8_t *)rx_buf,1);
 
  while (1)
  {
    ;
  }
}

第三步,串口启动接收的过程 原理------这一步不需要用户处理

HAL_UART_Receive_IT(&huart2, (uint8_t *)rx_buf,1)---->
调用UART_Start_Receive_IT(huart, pData, Size)---->
配置函数指针 huart->RxISR = UART_RxISR_8BIT;
使能接收中断SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
--------------------------------------------------------------------------------------
当收到数据发生中断的时候会执行这个函数
void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
}

HAL_UART_IRQHandler(&huart2);---huart->RxISR(huart);通过指针调用UART_RxISR_8BIT;---->判断接收完成后,关中断,调用HAL_UART_RxCpltCallback(huart);

第四、启动新的接收

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
      rx_cnt++;
      //把接收到的数据从rx_buf复制到buffer里,然后启动新的一次接收
      HAL_UART_Receive_IT(huart, (uint8_t *)rx_buf,1);
}
<think>好的,我现在需要回答用户关于HAL_UART_ReceiveHAL_UART_Receive_IT的区别及用法的问题。首先,我得确认自己对这些函数的工作原理和HAL的结构有足够的了解。根据用户提供的引用资料,我需要整理出两者的区别,并给出正确的用法步骤。 首先,用户提到的引用[2]和引用[4]提到了HAL_UART_Receive_IT的使用方法,包括初始化和回调函数。而引用[3]则提到了使用HAL_UART_Receive时可能遇到的问题,比如读取不到数据。引用[4]特别指出,使用中断接收需要在主循环前接收中断,并且不能在中断中直接读取寄存器,这说明HAL_UART_Receive_IT中断驱动的。 接下来,我需要区分这两个函数的工作模式。HAL_UART_Receive是阻塞式的,也就是说,当调用这个函数时,程序会一直等待直到接收到指定数量的数据或超时。这可能会影响其他任务的执行,尤其是在实时系统中。而HAL_UART_Receive_IT是非阻塞的,启动后立即返回,数据接收在后台进行,通过中断处理,接收完成后会触发回调函数。 然后,我需要检查这两个函数的用法步骤。根据引用[4],使用HAL_UART_Receive_IT需要先初始化并使能中断,然后在主循环前启动接收。而HAL_UART_Receive则直接调用,并指定超时时间。需要注意的是,HAL_UART_Receive如果在主循环中不恰当使用,可能会导致程序卡住,尤其是在没有超时的情况下。 另外,用户提到的引用[3]中的问题,可能是因为没有正确配置超时时间,或者在调用HAL_UART_Receive时没有处理可能的错误情况。比如,如果超时时间设置过短,可能在数据未完全接收时就返回了,导致数据不完整。 还需要考虑DMA相关的函数,比如HAL_UART_Receive_DMA,但用户的问题主要围绕ReceiveReceive_IT,所以可能不需要深入讨论DMA,但可以简要提及作为扩展。 最后,总结两者的区别,包括阻塞与非阻塞、使用场景、配置步骤以及回调函数的使用。同时,根据用户提供的引用资料,确保引用正确,比如在讨论中断配置时引用[4],在提到函数位置时引用[2]。 可能的相关问题包括如何选择这两种函数,如何处理接收完成后的数据,以及如何调试接收失败的情况。这些问题可以帮助用户进一步理解实际应用中的注意事项。</think>### HAL_UART_ReceiveHAL_UART_Receive_IT的区别及用法 #### 1. **核心区别** - **`HAL_UART_Receive`**:是**阻塞式接收**函数,调用后会占用CPU时间,直到接收到指定长度的数据或超时才会返回[^3][^4]。 - **`HAL_UART_Receive_IT`**:是**非阻塞中断接收**函数,调用后立即返回,数据接收在后台通过中断完成,需配合回调函数处理接收完成事件[^2][^4]。 #### 2. **使用场景** - **阻塞式场景**:适用于简单任务或需要严格同步的场合(如单次接收固定长度数据且无实时性要求)。 - **中断驱动场景**:适用于实时系统或多任务环境,避免阻塞主循环(如持续接收不定长数据)[^4]。 --- #### 3. **用法详解** ##### (1) `HAL_UART_Receive`(阻塞式) ```c // 示例:接收128字节数据,超时时间100ms char buffer[128] = {0}; HAL_StatusTypeDef status = HAL_UART_Receive(&huart2, (uint8_t*)buffer, 128, 100); if (status == HAL_OK) { // 处理接收到的数据 } ``` - **步骤**: 1. 直接调用函数并指定超时时间。 2. 检查返回值`HAL_OK`确认接收成功。 ##### (2) `HAL_UART_Receive_IT`(中断驱动) ```c // 初始化时使能中断 MX_USART2_UART_Init(); HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); // 主循环前启动接收(单字节示例) uint8_t rx_byte; HAL_UART_Receive_IT(&huart2, &rx_byte, 1); // 接收完成回调函数(需用户实现) void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart == &huart2) { // 处理接收到的单字节数据 // 重新启动接收以持续监听 HAL_UART_Receive_IT(&huart2, &rx_byte, 1); } } ``` - **步骤**: 1. 初始化UART并配置中断优先级。 2. 调用`HAL_UART_Receive_IT`启动接收。 3. 在回调函数`HAL_UART_RxCpltCallback`中处理数据并重启接收[^4]。 --- #### 4. **关键注意事项** - **中断配置**:使用`HAL_UART_Receive_IT`前必须使能NVIC中断,否则无法触发回调。 - **超时处理**:`HAL_UART_Receive`若超时时间过短,可能导致接收不完整(需根据波特率调整)[^3]。 - **数据长度**:中断接收通常逐字节处理,需在回调中重新启动接收以持续监听[^4]。 --- #### 5. **性能对比** | 特性 | `HAL_UART_Receive` | `HAL_UART_Receive_IT` | |---------------------|-------------------------|-------------------------| | CPU占用 | 高(阻塞) | 低(后台中断) | | 实时性 | 差 | 高 | | 适用场景 | 单次固定长度数据 | 持续/不定长数据 | ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值