1.1优先级分组 首先,我们先通过标识来解释手册里NVIC向量表的含义:
Core-M4内核最多支持256级的可编程优先级。用8位来表示优先级级别,,优先级级别分为8组,分别是组0~组7,如表1.0所示 (8位范围:0~255) 表1.1 中断分组讲解 组号 | 抢占优先级 | 响应优先级 | 0 | 用高七位表示抢占优先级 0~127 如果CPU的中断分组选择为“组 0”,则 抢占优先级可以设置为0~127,注意:数字越小,级别越高。 | 最低表示响应优先级 0~1 响应优先级可以设置为0或者1,注意:数字越小级别越高。 | 1 | 用高六位表示抢占优先级 如果CPU的中断分组选择为“组 1”, 抢占优先级可以设置为0~63 | 低两位表示响应优先级 响应优先级可以设置为0~3 | 2 | 用高5位表示抢占优先级 如果CPU的中断分组选择为“组 2”, 抢占优先级可以设置为0~31 | 低三位表示响应优先级 响应优先级可以设置为0~7 | 3 | 用高4位表示抢占优先级 如果CPU的中断分组选择为“组 2”, 抢占优先级可以设置为0~15 | 低四位表示响应优先级 响应优先级可以设置为0~15 | 4 | 用高3位表示抢占优先级 如果CPU的中断分组选择为“组 2”, 抢占优先级可以设置为0~7 | 低五位表示响应优先级 响应优先级可以设置为0~31 | 5 | 用高2位表示抢占优先级 如果CPU的中断分组选择为“组 2”, 抢占优先级可以设置为0~3 | 低6位表示响应优先级 响应优先级可以设置为0~63 | 6 | 最高位表示抢占优先级 如果CPU的中断分组选择为“组 2”, 抢占优先级可以设置为0~1 | 低7位表示响应优先级 响应优先级可以设置为0~127 | 7 | | 8位表示响应优先级 响应优先级可以设置为0~255 |
如果用图来形象表示,则看图1.1-8位中断分组 :
1.1 8位中断分组 stm32为了节省材料成本,并没有完全使用这8位,它忽略低4位。如下图1-2
1.2 高位分组
表1.2 裁剪分组讲解 组号 | 中断优先级分组说明 | 抢占优先级等级范围 | 响应优先级等级范围 | 3 | 所有4位用于指定抢占优先级 | 0~15 | 不可设置 | 4 | 最高3位用于指定抢占优先级,最低1位用于指定响应优先级 | 0~7 | 0~1 | 5 | 最高2位用于指定抢占优先级,最低2位用于指定响应优先级 | 0~3 | 0~3 | 6 | 最高1位用于指定抢占优先级,低3位用于指定响应优先级 | 0~1 | 0~7 | 7 | 所有4位用于指定响应优先级 | 不可设置 | 0~15 |
1.2 NVIC中断中断控制器相关函数NVIC分组设置void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) 位置:core_cm4.h的1453行 作用:设置优先级分组。 参数:PriorityGroup优先级分组组号 举例:STM32的优先级分组设置为组5,则对应的代码如下:NVIC_SetPriorityGrouping(5); NVIC具体中断优先级编码uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) 作用:设置抢占优先级和响应优先级的级别 位置:core_cm4.h的1610行 参数:PriorityGroup优先级分组组号;PreemptPriority:抢占优先级;SubPriority:响应优先级 返回值:32位的编码值,编码值用于中断优先级设置 举例:优先级分组选择为组5,抢占优先级为2,响应优先级为2,代码如下: u32 prio; prio = NVIC_EncodePriority(5,2,2); NVIC中断优先级设置void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) 作用:将优先级分组情况以及抢占优先级和响应优先级设置到响应的中断。 参数: IRQn :中断通道编号。 priority:是NVIC_EncodePriority函数的返回值 举例:设置串口1全局中断的优先级分组选择为组5,抢占优先级为2,响应优先级为3 对应的代码: u32 prio; prio = NVIC_EncodePriority(5,2,3); NVIC_SetPriority(37,prio); 也可以写成NVIC_SetPriority(USART1_IRQn,prio); NVIC中断使能void NVIC_EnableIRQ(IRQn_Type IRQn) 作用:使能中断通道 参数:IRQn :中断通道编号。 举例:使能串口1全局中断,NVIC_EnableIRQ(37); 可以写成NVIC_EnableIRQ(USART1_IRQn); NVIC中断禁能void NVIC_DisableIRQ(IRQn_Type IRQn) 作用:禁止中断通道。 参数:IRQn :中断通道编号。 举例:禁止串口1全局中断,NVIC_DisableIRQ(37); 1.3 实例代码之串口中断: - #include "stm32f4xx.h"
- //PA9 ----TXD--发送数据 (站在芯片角度)
- //PA10 --- RXD--接收收据 (站在芯片角度)
- void Usart1_Init(u32 baudRate)
- {
- u32 prio;
- float USARTDIV;
- u16 Mantissa; //整数
- u8 Fraction; //小数
- /****使能GPIOA的时钟***/
- RCC->AHB1ENR |= 1<<0;
- /****配置PA10为复用功能+上拉***/
- GPIOA->MODER |= 2<<20;//复用功能
- GPIOA->PUPDR |= 1<<20;//上拉
- /****配置PA9位复用功能+推挽***/
- GPIOA->MODER |= 2<<18;//复用功能
- GPIOA->OTYPER &=~(1<<9);//推挽
- /****PA9选择复用功能7,TXD***/
- GPIOA->AFR[1] |= 7<<4 ;
- /****PA10选择复用功能7,RXD***/
- GPIOA->AFR[1] |= 7<<8 ;
-
- /****使能串口1的时钟***/
- RCC->APB2ENR |= 1<<4;
- /****设置数据帧格式***/
- USART1->CR1 |= 1<<15;//OVER8设置为1
- USART1->CR1 &=~(1<<12);//将串口1的数据帧设置为“1 起始位, 8 数据位, n 停止位 ”
- USART1->CR2 &=~(3<<12);//1位停止位
- USART1->CR1 &=~(1<<10);//禁止奇偶校验
-
- /****设置波特率***/
- //USARTDIV = fCK/8*(2- OVER8 )/TxRx 波特率
- USARTDIV = (float)84000000/8/baudRate;
- Mantissa = (int)USARTDIV;
- Fraction = (u8)((USARTDIV-Mantissa)*16);
- USART1->BRR = Mantissa<<4 | Fraction;
-
-
- USART1->CR1 |= 1<<5; //使能串口接收中断
- NVIC_SetPriorityGrouping(5); //设置优先级分组设置为组5,注意:一个工程只能有一个分组
- prio = NVIC_EncodePriority(5,2,2); //组5,抢占优先级为2,响应优先级为2
- NVIC_SetPriority(USART1_IRQn,prio);
- NVIC_EnableIRQ(USART1_IRQn); //使能串口1中断通道USART1_IRQn==37 也可以用37表示串口1的通道编号
-
- USART1->CR1 |= 1<<3;//使能发送器
- USART1->CR1 |= 1<<2;//使能接收器
- USART1->CR1 |= 1<<13;//使能串口1
- }
- //中断服务程序代码,在接收到一个字节是会进入串口中断服务函数
- void USART1_IRQHandler(void)
- {
- u8 data;
- if(USART1->SR&(1<<5))
- {
- data = USART1->DR;
- /*******接收到一个字节原样回发*******/
- USART1->DR = data;
- while(!(USART1->SR&(1<<6)));
- USART1->SR &=~(1<<6); //清零
- }
- }
复制代码
|