1.1優先度のグループ化
まずは、識別することにより、スケールに手動NVICの意味を説明しましょう:
コア-M4コアは256プログラマブル優先順位をサポートします。(255 0〜8の範囲)優先度の優先度レベルを表すために8ビット,, 8つのグループは、表1.0に示すように、グループ7に、すなわち、グループ0、に分けると
説明するために表1.1割り込みパケット
グループ番号 | プリエンプションの優先順位 | 優先順位の応答 |
0 | エクスプレス先取り優先順位の高い7 0〜127 場合は、CPUの割り込みパケットの選択は、「グループである0 」、 先取り優先順位は次のように設定してもよい127 0 注:レベルが高いほど、数より小さい。 |
レスポンスは最も低い優先度を表し、 0〜1 レスポンス優先順位はに設定されてもよい0 または1 注:小さい数より高いレベル。 |
1 | エクスプレス先取り優先順位の高い6 場合は、CPUの割り込みパケットは、「グループとして選択される1」、 先取り優先順位は次のように設定されてもよい0~63 |
二つは、低優先度の応答を表します レスポンス優先順位は次のように設定することができ、0〜3 |
2 | 高い5 先取り優先順位を表すビット もしCPU 「グループとして選択グループ化割り込み2」、 先取り優先順位は次のように設定されてもよい0~31 |
低応答は、3つの優先を示し、 レスポンス優先順位は次のように設定することができます0〜7 |
3 | 高4 先取り優先順位を表すビット もしCPU 「グループとして選択グループ化割り込み2」、 先取り優先順位は次のように設定されてもよい0~15 |
下位4ビットは、応答の優先度を表します レスポンス優先順位は次のように設定することができます0〜15 |
4 | 高い3 先取り優先順位ビットを表します もしCPU 「グループとして選択グループ化割り込み2」、 先取り優先順位は次のように設定することができる0〜7 |
5桁の応答は低い優先順位を示し レスポンス優先順位は次のように設定することができます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); //清零 } }