1 中断分组
嵌套中断的含义: 高优先级中断能打断低优先级中断
翻译:
STM32分组为:组0-4(没组都有16个优先级)
分组配置在寄存器SCB->AIRCR中
使用示例:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
如下图这个图中用了8位:
SCB->AIRCR 寄存器和IP寄存器
首先两者联系,SCB->AIRCR 寄存器的10:8位bit,决定了,IP寄存器4:7bit的高四位的抢占与响应位的分配:
那么SCB->AIRCR 寄存器的10:8位bit怎么决定这个分配呢?
AIRCR 寄存器的10:8位,设置几位抢占,几位响应。举例如下:
AIRCR寄存器8:10与IP寄存器4:7
AIRCR寄存器8:10 IP寄存器4:7
0 111 抢占:0bit,响应:4bit
1 110 抢占:1bit,响应:3bit
2 101 抢占:2bit,响应:2bit
3 100 抢占:3bit,响应:1bit
4 011 抢占:4bit,响应:0bit
怎么理解这个表呢?
AIRCR寄存器8:10是111,表示7,即ip寄存器的第四位到第七位为止是响应级(从0开始),本来就ip寄存器的4:7bit,那4,5,6,7bit,都表示响应
AIRCR寄存器8:10是100,表示4,ip寄存器的第四位到第四位表示响应级。即一位表示响应级
设置响应的例子:
MY_NVIC_Init(3,2,EXTI2_IRQn,2); //抢占3,子优先级2,组2
2 中断编程
中断编程的三步曲:
第一步:使能外设某个中断,具体由对应的中断使能位控制。(例如:我们使用到GPIO之前必须开启GPIO端口的时钟,用到EXTI必须开启AFIO时钟)
第二步:初始化NVIC_InitTypeDef结构体,配置中断优先级分组,设置抢占优先级和响应优先级,使能中断请求
第三步:编写中断服务函数,在stm32f0xx_it.c文件中,都有一个根据中断向量表,实现的一个空的中断服务函数,需要我们自己重新编写
3 中断应用
NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; //中断号
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //次优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
{
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;
tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub);
tmppriority = tmppriority << 0x04;
NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;// IP寄存器设置中断优先级
/* Enable the Selected IRQ Channels --------------------------------------*/
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
else
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
nvic中断寄存器的配置分布:
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
} NVIC_Type;
上一篇:error: #268: declaration may not appear after executable statement in block问题解决方法
下一篇:stm32f4-led
推荐阅读最新更新时间:2024-11-12 10:16
设计资源 培训 开发板 精华推荐
- LTC3731H 的典型应用 - 三相、600kHz、同步降压型开关稳压器控制器
- STC8H开发板
- 使用 Analog Devices 的 LTC2656CIFE-L16#PBF 的参考设计
- LT1765-5,通过最佳电容器连接降低正负 DC/DC 转换器的输出电压纹波
- EEZ Bench Box 3:模块化、开源测试和测量机箱,不止于是可编程直流电源
- 电路在 3.6V 至 16V 的输入范围内产生 350mA 的 2.5V 电压
- 【创意PCB】献给爱丽丝的月下剪影灯
- LT6656BIDC-4.096、4.096V 扩展电源范围电压基准的典型应用
- 用于便携式的 MOSFET 功率驱动器
- 用于基本配置的 ADR365A、5V 低功耗、低噪声电压基准的典型应用