#include "usart3.h" uint8_t Usart3_RxPacket[10]; //定义接收数据包数组 uint8_t Usart3_RxFlag; //定义接收数据包标志位 uint8_t Usart3_seshig; void Uart3_Init(void) { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能Usart3,GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOA时钟 //Usart3_TX GPIOB.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA2 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.10 //Usart3_RX GPIOB.11初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PA3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.11 //Usart3 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级4 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 USART_InitStructure.USART_BaudRate = 9600;//串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 USART_Init(USART3, &USART_InitStructure); //初始化串口3 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART3, ENABLE); //使能串口3 } /** *********************************************************** * @brief 对数据进行异或运算 * @param data, 存储数组的首地址 * @param len, 要计算的元素的个数 * @return 异或运算结果 *********************************************************** */ uint8_t CalXorSum(const uint8_t *data, uint32_t len) { uint8_t xorSum = 0; for (uint32_t i = 0; i < len; i++) { xorSum ^= data[i]; } return xorSum; } /** *********************************************************************** 包格式:帧头0 帧头1 数据长度 功能字 指令 异或校验数据 0x55 0xAA 0x02 0x01 0x01 0xFD *********************************************************************** */ void USART3_IRQHandler(void) //串口2中断服务程序 { uint8_t Res; static uint8_t RxState = 0; //当前状态机状态 static uint8_t pRxPacket = 0; //当前接收数据位置 if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(USART3); //读取接收到的数据 switch (RxState) { case 0: if (Res == 0x55) { Usart3_RxPacket[pRxPacket] = Res; //将数据存入数组 pRxPacket++; RxState = 1; } else { pRxPacket = 0; RxState = 0; } break; case 1: if (Res == 0xAA) { Usart3_RxPacket[pRxPacket] = Res; //将数据存入数组 pRxPacket++; RxState = 2; } else { pRxPacket = 0; RxState = 0; } break; case 2: Usart3_RxPacket[pRxPacket] = Res; //将数据存入数组 pRxPacket++; if(pRxPacket >= 6) { if ((uint8_t)CalXorSum(Usart3_RxPacket, 5) != (uint8_t)Usart3_RxPacket[5]) { pRxPacket = 0; RxState = 0; } else { RxState = 0; pRxPacket = 0; Usart3_seshig = 66; Usart3_RxFlag = 1; //接收数据包标志位置1,成功接收一个数据包 } } break; default: break; } USART_ClearITPendingBit(USART3, USART_IT_RXNE); //清除标志位 } } 这里void USART3_IRQHandler(void) 函数是干嘛用的,含义是什么?
时间: 2025-05-26 19:42:19 浏览: 32
### STM32串口中断函数 USART3_IRQHandler 的功能与作用
USART3_IRQHandler 是 STM32 微控制器中的一个中断服务程序,用于处理与 USART3 外设相关的中断事件。当中断条件被触发时(例如接收缓冲区非空 RXNE 或发送完成 TC),CPU 将跳转至该中断向量表对应的地址,并执行此函数内的代码。
#### 中断入口与初步处理
当硬件检测到特定的中断源激活时,会自动调用 `USART3_IRQHandler` 函数[^1]。在此阶段,主要的任务是对当前发生的中断类型进行识别和分类。通常情况下,这一步涉及检查状态寄存器或标志位,以确认具体的中断原因。例如:
```c
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
// 接收缓冲区非空中断
}
```
如果发现是由于接收到新数据而引发的中断,则需要进一步操作这些数据或将它们存储到预定义的位置中去[^3]。
#### 数据传输过程
在某些配置下,可能还会涉及到 DMA 控制器参与的数据搬运任务;而在其他场景里则完全依赖于软件层面逐字节地读取/写入动作来实现通信目的。对于采用 HAL 库初始化后的项目而言,在这里一般不会直接处理复杂的业务逻辑,而是简单通知更高层的应用部分已完成相应的工作项——比如通过回调机制告知上一层级有关接收完毕的消息等[^1]。
另外值得注意的一点是在每次访问完外设之后都需要妥善清理掉相关联待决事项以免造成不必要的重复触发现象[^4]:
```c
// 清除 RXNE 中断标记
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
```
最后但同样重要的是错误管理环节。任何潜在可能出现异常状况的地方都应设有防护措施以防止单元陷入死循环或者丢失有效载荷等情况的发生:
```c
if (USART_GetFlagStatus(USART3, USART_FLAG_ORE) == SET){
// 过载错误处理...
}
```
综上所述,`USART3_IRQHandler` 不仅承担着基础性的信号捕捉职责,还肩负起保障整个通讯链路顺畅运作的重要使命。
```c
void USART3_IRQHandler(void) {
uint8_t data;
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET){
data = USART_ReceiveData(USART3);
/* Process received byte */
// Clear interrupt flag after processing the data.
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
if (USART_GetFlagStatus(USART3, USART_FLAG_ORE)==SET){
// Handle Overrun Error and clear it.
USART_ClearFlag(USART3, USART_FLAG_ORE);
// Optionally discard erroneous character or take corrective action.
}
}
```
### 结论
因此可以看出,`USART3_IRQHandler` 主要负责响应来自 USART3 设备的各种类型的中断请求,并依据实际情况采取合适的行动方案予以应对。无论是简单的字符交换还是更为复杂的信息流控制都可以借助这一核心组件得以顺利完成[^2]。
阅读全文
相关推荐


















