CW32L083系列MCU中断系统介绍

描述

本文针对CW32L083系列MCU,同系列产品亦可参考。

 

ARM® Cortex®-M0+ 内核的嵌套向量中断控制器 (NVIC),用于管理中断和异常。NVIC和处理器内核紧密相连,可以实现低延迟的异常和中断处理。处理器支持最多32个中断请求 (IRQ)输入,支持多个内部异常。

 

主要特性 

• 16个内部异常 

• 32个可屏蔽外部中断 

• 4个可编程的优先级 

• 低延时的异常和中断处理

• 支持中断嵌套 

• 中断向量表重映射

 

本文介绍了处理器的 32 个外部中断请求(IRQ0 ~ IRQ31),处理器内部异常的具体情况请参考“ARM® Cortex®-M0+Technical Reference Manual”与“ARM® v6-M Architecture Reference Manual”。

 

中断优先级 

外部中断可设置 4 级优先级,最高优先级为“0”,最低优先级为“3”,默认值为“0”。当处理器正在执行一个中断处理程序时,如果出现一个更高优先级的中断,那么这个中断就被抢占。如果出现的中断的优先级和正在处理的中断的优先级相同或更低,这个中断就不会被抢占,但是新中断的状态就变为挂起。如果多个挂起的中断具有相同的优先级,中断编号越小的挂起中断优先处理。例如,如果IRQ[0]和IRQ[1]均挂起时,并且两者的优先级相同,那么先处理 IRQ[0]。

 

中断向量表

ARM® Cortex®-M0+ 响应中断时,处理器自动从存储器的中断向量表中取出中断服务程序 ( ISR )的起始地址。中断向量表包括主栈指针(MSP)的初始值,内部异常和外部中断的服务程序入口地址。每个中断向量占用1个字(4 字节),中断向量的存储地址为向量编号乘以4,下面的是CW32L083的中断向量表。

 

mcu

 

mcu

CW32L083由于部分外设的中断复用一个IRQ中断源,在中断服务程序中应先检查中断标志位,以确定产生中断的外设。NMI在CW32L083中未使用。HSE 、LSE 时钟信号起振失败和 LSI、LSE、HSIOSC、HSE、PLL 时钟信号稳定对应 RCC 全局中断。HSE 或 LSE 时钟信号在运行中失效对应 FAULT 中断。

 

中断寄存器的相关配置

1.中断的使能、挂起、清除挂起

ARM® Cortex-M0+处理器支持最多32个外部中断源,分别对应中断使能设置寄存器NIVC_ISER的32个使能位,和中断使能清除寄存器NVIC_ICER的32个禁止位。将使能位置1,允许中断;将禁止位置1,禁止中断。上文中NVIC中断使能仅针对处理器 NVIC而言,外设的中断是否使能,还受相应外设的中断控制寄存器控制。

而在中断发生的时候,如果系统正在处理相同优先级的或者更高优先级的中断,系统将不会立马的处理这个中断,而是将这个中断的状态设置为挂起,保存在中断挂起状态寄存器中,在处理器未进去此中断处理之前,如果没有手动清除挂起状态,这个状态会一直有效,等处理器进入中断处理的时候,硬件会自动清除相应的中断挂起状态。也可以通过设置中断挂起设置寄存器NVIC_ISPR的对应位,将此中断的状态设置为挂起状态,如果系统没有正在处理与之相同优先级或更高优先级的中断,此中断将被立即响应并处理。可以通过设置中断挂起清除寄存器NVIC_ICPR的对应位,将此中断的状态设置为挂起清除状态。

 

2.中断的优先级、中断屏蔽

中断优先级控制寄存器NVIC_IPR0 ~ NVIC_IPR7,用于设置IRQ0~IRQ31 的中断优先级,每个中断源使用8位,在CW32L083中仅使用了高两位,最多可设置4个中断优先级。

在某些特殊场合,需要禁止所有中断,可以使用中断屏蔽寄存器PRIMASK实现。PRIMASK只有最低1位有效,将此位置1,除了NMI和硬件错误异常之外的所有外部中断和异常都被禁止;清0后,允许响应中断和异常。该位复位后默认为0。

 

按键中断检测实验分析

以CW32L083评估板为例,按键连接至CW32L083的PA4、PA5端口,LED连接至PC2、PC3接口。按键按下将产生中断,在中断服务程序中进行LED翻转。

int32_t main(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __RCC_GPIOA_CLK_ENABLE();  // 使能GPIOA的配置时钟 __RCC_GPIOC_CLK_ENABLE();  // 使能GPIOC的配置时钟 //按键GPIO初始化 GPIO_InitStruct.IT = GPIO_IT_RISING | GPIO_IT_FALLING; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pins =GPIO_PIN_4 | GPIO_PIN_5; GPIO_Init(CW_GPIOA, &GPIO_InitStruct); //LED的GPIO初始化 GPIO_InitStruct.IT = GPIO_IT_NONE; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pins =GPIO_PIN_2 | GPIO_PIN_3; GPIO_Init(CW_GPIOC, &GPIO_InitStruct); //配置中断滤波 GPIO_ConfigFilter(CW_GPIOA, bv4, GPIO_FLTCLK_RC150K); //清除PA4、PA5中断标志并使能NVIC GPIOA_INTFLAG_CLR(bv4| bv5); NVIC_EnableIRQ(GPIOA_IRQn); __enable_irq(); //---------------------------------------------------------------------- //相关程序在中断服务GPIOA_IRQHandler中进行处理 while (1) { } } //GPIOA的中断服务函数 void GPIOA_IRQHandlerCallback(void) { if (CW_GPIOA->ISR_f.PIN4) { GPIOA_INTFLAG_CLR(bv4);清除PA04的中断标志位 PC03_TOG(); } if (CW_GPIOA->ISR_f.PIN5) { GPIOA_INTFLAG_CLR(bv5);//清除PA05的中断标志位 PC02_TOG(); } }

由上面代码可以看到,如果按下KEY1(PA04),LED1(PC03)的状态会翻转,如果松开按键,LED1又会翻转一次。在每次执行中断函数的时候,需要清除中断标志位即GPIOA_INTFLAG_CLR(bv4)。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分