STM32 串口中断接收原理与实战详解:从配置到中断服务函数全流程解析

大家可以从下面主函数推测这是关于什么的代码,其实可以从题目中就可以看到了,没错是串口的中断接收程序,那就在底下评论区把这个代码描述出来

现在具体这个项目快要正式开始了,前面的GPIO我们简单过了一遍,接下来就要过一下串口的内容。

因为我觉得串口这节带了挺多基础的东西,比如端口复用,中断配置,中断服务函数

复制代码
int main()
复制代码
{
复制代码
u8 key;
复制代码
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
复制代码
key_Init();
复制代码
LED_Init();
复制代码
Init_USART1();
复制代码
while(1)
复制代码
{
复制代码
if(usart1_buf.flag == 1)
复制代码
{
复制代码
usart1_buf.flag = 0;
复制代码
if(strcmp((char*)(usart1_buf.buff),"open")){
复制代码
LED_R_ON;
复制代码
}
复制代码
else if(strcmp((char*)(usart1_buf.buff),"close")){
复制代码
LED_R_OFF;
复制代码
}
复制代码
}
复制代码
}
复制代码
}

那么接下来就将串口配置的细节都展示出来,这里我主要将串口的中断服务函数进行解释,其他不懂的,来评论区聊聊。

复制代码
#include "main.h"
复制代码
void Init_USART1()
复制代码
{
复制代码
//RCC_Init
复制代码
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
复制代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
复制代码
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
复制代码
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
复制代码
GPIO_InitTypeDef GPIO_InitStruct = {0};
复制代码
GPIO_StructInit(&GPIO_InitStruct);
复制代码
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
复制代码
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
复制代码
GPIO_InitStruct.GPIO_Speed = GPIO_Medium_Speed;
复制代码
GPIO_Init(GPIOA, &GPIO_InitStruct);
复制代码
USART_InitTypeDef USART_InitStruct = {0};
复制代码
USART_StructInit(&USART_InitStruct);
复制代码
USART_InitStruct.USART_BaudRate = 115200;
复制代码
//	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
复制代码
//	USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
复制代码
//	USART_InitStruct.USART_Parity = USART_Parity_No;
复制代码
//	USART_InitStruct.USART_StopBits = USART_StopBits_1;
复制代码
//	USART_InitStruct.USART_WordLength = USART_WordLength_8b;
复制代码
USART_Init(USART1, &USART_InitStruct);
复制代码
NVIC_InitTypeDef NVIC_InitStruct = {0};
复制代码
NVIC_InitStruct.NVIC_IRQChannel  =USART1_IRQn;
复制代码
NVIC_InitStruct.NVIC_IRQChannelCmd  =ENABLE;
复制代码
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
复制代码
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
复制代码
NVIC_Init(&NVIC_InitStruct);
复制代码
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
复制代码
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
复制代码
USART_Cmd(USART1, ENABLE);
复制代码
}
复制代码
void SendByte(u8 a)
复制代码
{
复制代码
while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE))
复制代码
USART_SendData(USART1,a);
复制代码
}
复制代码
void SendString(u8 *str)
复制代码
{
复制代码
u8 i = 0;
复制代码
while(*str != '\0'){
复制代码
USART_SendData(USART1,*str);
复制代码
str++;
复制代码
}
复制代码
}

在中断函数里

复制代码
typedef struct usart
复制代码
{
复制代码
u8 buff[1024];
复制代码
u8 len;
复制代码
u8 flag;
复制代码
}Usart_ReData;
复制代码
#include"stm32f4xx_it.h"
复制代码
Usart_ReData usart1_buf ;
复制代码
void USART1_IRQHandler()
复制代码
{
复制代码
if(USART_GetITStatus(USART1,USART_IT_RXNE)){
复制代码
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
复制代码
usart1_buf.buff[usart1_buf.len++] = USART_ReceiveData(USART1);
复制代码
}
复制代码
if(USART_GetITStatus(USART1,USART_IT_IDLE)){
复制代码
USART1->SR;
复制代码
USART1->DR;
复制代码
usart1_buf.buff[usart1_buf.len] = '\0';
复制代码
usart1_buf.len = 0;
复制代码
usart1_buf.flag = 1;
复制代码
}
复制代码
}

代码解释

复制代码
typedef struct usart
复制代码
{
复制代码
u8 buff[1024];  // 缓冲区:用于存放接收到的一帧数据,最大 1024 字节
复制代码
u8 len;         // 当前接收到的字节数(长度)
复制代码
u8 flag;        // 数据接收完成标志位(1 表示接收完成)
复制代码
} Usart_ReData;

中断服务函数解释

复制代码
void USART1_IRQHandler()
复制代码
{
复制代码
// 1. 接收非空中断(每接收一个字节触发一次)
复制代码
if(USART_GetITStatus(USART1, USART_IT_RXNE)){
复制代码
USART_ClearITPendingBit(USART1, USART_IT_RXNE); // 清除中断标志位
复制代码
// 将接收到的一个字节存入缓冲区
复制代码
usart1_buf.buff[usart1_buf.len++] = USART_ReceiveData(USART1);
复制代码
}
复制代码
// 2. 空闲中断(接收一帧数据后,串口线空闲会触发)
复制代码
if(USART_GetITStatus(USART1, USART_IT_IDLE)){
复制代码
USART1->SR; // 清除 IDLE 中断标志:读 SR 和 DR
复制代码
USART1->DR;
复制代码
// 在缓冲区尾部加 '\0' 作为字符串结束符(便于后续处理)
复制代码
usart1_buf.buff[usart1_buf.len] = '\0';
复制代码
// 接收长度归零,为下一帧做准备
复制代码
usart1_buf.len = 0;
复制代码
// 设置标志位,通知主程序有新数据
复制代码
usart1_buf.flag = 1;
复制代码
}
复制代码
}
相关推荐
代码游侠18 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
CODECOLLECT1 天前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen1 天前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠1 天前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_1 天前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
深圳市九鼎创展科技1 天前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计1 天前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
小龙报1 天前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业1 天前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能1 天前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微