串口中断函数详解

串口中断函数详解#

ARM cortex_m3 内核支持 256 个中断(16 个内核+240 外部)和可编程 256 级中断优先级的设置。

STM32支持的中断共为84个(16个内核+68个外部),和16级可编程中断优先级的设置。

AIRCR是NIVC配置中一个关键的寄存器,由于STM32有很多中断,要处理这些中断的时候总是需要先后顺序的,所以采用AIRCR寄存器给中断优先级进行分组。

优先组别总用有5组, 0-4,分为抢占优先级和响应优先级(也称为子优先级),使用低字节的高四位来设置中断优先级分组。

例如:当AIRCR寄存器的第八位到第十位都为1时,寄存器的第四位到第七位都是在设置响应优先级,最高可以有0个抢占优先级和16级响应优先级。具体分配如下表:

AIRCR[10: 8] bit[7: 4] 结果
0 111 0:4 0 位抢占优先级, 4 位响应优先级
1 110 1:3 1 位抢占优先级, 3 位响应优先级
2 101 2:2 2 位抢占优先级, 2 位响应优先级
3 100 3:1 3 位抢占优先级, 1 位响应优先级
4 011 4:0 4 位抢占优先级, 0 位响应优先级

在使用NVIC初始化以前需要使用NVIC_PriorityGroupConfig( )函数设置中断优先级分组。分组后再在中断初始化函数中使用NVIC_IRQChannelPreemptionPriority设置具体的中断优先级。

下面为串口初始化函数以及中断函数:

Copy
void uart_init (){ //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能 USART1,GPIOA时钟 //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置 // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 USART_InitStructure.USART_BaudRate = 115200;//串口波特率 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(USART1, &USART_InitStructure); //初始化串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART1, ENABLE); //使能串口1 } void USART1_IRQHandler (void) //串口1中断服务程序 { u8 Res; if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ //接收中断(接收到的数据必须是 0x0d 0x0a结尾)。USART_GetITStatus函数如果接收寄存器存在数据就返回SET Res =USART_ReceiveData(USART1); //读取接收到的数据,一次发送一个字节 if ((USART_RX_STA&0x8000)==0){ //接收未完成 if (USART_RX_STA&0x4000){ //接收到了0x0d 0x0D(asc码是13) 指的是“回车” if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x8000; //接收完成了 } else {//还没收到0X0D if (Res==0x0d)USART_RX_STA|=0x4000; else { USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; USART_RX_STA++; if (USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重 新开始接收 } } } } }

这里详细介绍稍难理解一点的语句

Copy
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  • 第一个参数为使用串口1

  • 第二个参数为中断标志,串口有很多种中断,这里是使用USART_IT_RXNE中断

  • 第三个参数为使能

下面为中断处理函数:

Copy
if((USART_RX_STA&0x8000)==0)

USART_RX_STA是状态标记变量,bit0~13接收有效字节数目,bit14接收0x0d,bit15接收完成标志。当接收完成时,bit15置为1。

该变量从0开始,串口中断接收到一个数据(一个字节)就自增1。当数据读取全部OK时候(回车和换行符号来的时候),那么 USART_RX_STA的最高位置1,表示串口数据接收全部完毕了,然后main函数里面可以处理数据了。

当接收到从电脑发过来的数据,把接收到的数据保存在USART_RX_BUF 中,同时在接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(0X0D,0X0A)的第一个字节0X0D 时,计数器将不再增加,等待0X0A 的到来,而如果0X0A 没有来到,则认为这次接收失败,重新开始下一次接收。如果顺利接收到0X0A,则标记USART_RX_STA的第16位,这样完成一次接收,并等待该位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到0X0D,那么在接收数据超过设定值个数后,会丢弃前面的数据,重新接收。

0x4000,即二进制0100 0000 0000 0000,与变量USART_RX_STA,按位与(&),作用是判断USART_RX_STA数值第15位是否为0。

0x8000,即二进制1000 0000 0000 0000,与变量USART_RX_STA,按位与(&),作用是判断USART_RX_STA数值第16位是否为0。

Copy
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;

为了去除最高两位的影响,将最高两位置0。

Copy
if (USART_RX_STA>200) USART_RX_STA=0

200为自己设定的值,如果接收到的函数大于这个值,就清除掉整个字符串重新输入。

posted @   一颗蘋果  阅读(6295)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
CONTENTS