STM32L0 串口uart通讯 USART1_IRQHandler

本文详细记录了STM32开发中遇到的USART1_IRQHandler中断无法正常触发的问题及解决方案。通过调整HAL_UART_MspInit函数内的配置,成功启用了USART1的中断功能,并实现了数据接收。

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

使用stm32 cubx 生成工程后 发现USART1_IRQHandler 中断不能进入。

下面这段代码进不去:

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 */
  HAL_UART_Receive_IT(&huart1, recive_buf, 10);
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
  /* USER CODE END USART1_IRQn 1 */
}

 

于是添加红色部分,能够进入中断,完成数据接收

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
//            SET_BIT(USART1->ICR, USART_ICR_TCCF);   /* ȥԽTCע̍ΪԉҪ־ */
//    SET_BIT(USART1->RQR, USART_RQR_RXFRQ);  /* ȥԽRXNEޓ˕Ҫ־ */
//    SET_BIT(USART1->CR1, USART_CR1_RXNEIE); /* ʹŜPE. RXޓ˜א׏ */
  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
  else if(uartHandle->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspInit 0 */

  /* USER CODE END USART2_MspInit 0 */
    /* USART2 clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration    
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspInit 1 */

    SET_BIT(USART2->ICR, USART_ICR_TCCF);   /* 清除TC发送完成标志*/
    SET_BIT(USART2->RQR, USART_RQR_RXFRQ);  /*־清除RXNE接收标志*/
    SET_BIT(USART2->CR1, USART_CR1_RXNEIE); /* 使能PERX接收中断*/

        
  /* USER CODE END USART2_MspInit 1 */
  }
}

### 修改或重写 USART1_IRQHandler 函数 在 STM32串口中断处理中,`USART1_IRQHandler` 是用于处理 USART1 中断的核心函数。通常情况下,该函数由开发环境自动生成并绑定到中断向量表中。如果需要对其进行修改或重写,则需遵循以下原则: #### 1. **基本结构** `USART1_IRQHandler` 函数的主要功能是检测当前发生的中断事件,并执行相应的回调逻辑。以下是其典型实现框架: ```c void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET && // 判断接收缓冲区非空中断标志是否被置位 __HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_RXNE) != RESET) { // 确认接收中断已使能 uint8_t data = huart1.Instance->DR; // 读取接收到的数据 ProcessReceivedData(data); // 调用用户定义的处理函数 } if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) != RESET && // 判断传输完成中断标志是否被置位 __HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_TC) != RESET) { // 确认传输完成中断已使能 HAL_UART_TxCpltCallback(&huart1); // 执行传输完成后的回调 } } ``` 上述代码片段展示了如何分别处理接收中断和传输完成中断。 --- #### 2. **具体实现细节** ##### 接收中断处理 当发生接收中断时,程序应从 `USART_DR` 寄存器中读取数据。由于硬件会在读取 `USART_DR` 后自动清除接收中断标志[^2],因此无需额外编写清零操作。 ```c if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET && __HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_RXNE) != RESET) { uint8_t received_data = huart1.Instance->DR; HandleIncomingByte(received_data); } ``` ##### 发送完成中断处理 当发送完成后,可以触发特定的回调函数来通知应用程序。这可以通过检查 `UART_FLAG_TC` 和对应的中断源状态来实现。 ```c if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) != RESET && __HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_TC) != RESET) { HAL_UART_TxCpltCallback(&huart1); } ``` ##### 错误中断处理 为了增强系统的鲁棒性,还需要考虑错误中断的情况(如帧错误、溢出错误等)。这些错误可通过检查相应标志位来捕获。 ```c if ((__HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) != RESET) || // 溢出错误 (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_NE) != RESET)) { // 噪声错误 ErrorHandlingFunction(); } ``` --- #### 3. **注意事项** - 如果使用 HAL 库初始化了串口,但未开启中断,则需要手动调用 `HAL_UART_Receive_IT()` 或其他类似的 API 来启动中断机制[^3]。 - 若项目涉及浮点运算或其他特殊需求,可能需要启用 MicroLIB 支持[^4]。此时应在工程设置中勾选相关选项,并提供必要的定义。 --- ### 完整示例代码 以下是一个完整的 `USART1_IRQHandler` 实现示例: ```c #include "stm32f1xx_hal.h" // 用户定义的全局变量或缓冲区 uint8_t RxBuffer[10]; volatile uint8_t RxIndex = 0; void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET && __HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_RXNE) != RESET) { RxBuffer[RxIndex++] = huart1.Instance->DR; // 存储接收到的数据 if (RxIndex >= sizeof(RxBuffer)) { // 缓冲区满则停止接收 HAL_UART_DisableIT_RXNE(&huart1); } } if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) != RESET && __HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_TC) != RESET) { HAL_UART_TxCpltCallback(&huart1); // 调用传输完成回调 } if ((__HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) != RESET) || (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_NE) != RESET)) { ErrorRoutine(); // 处理错误情况 } } // 自定义错误处理函数 void ErrorRoutine(void) { while(1); // 进入死循环等待调试 } ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值