Cortex-M0中断控制和系统控制

每一个外部中断都有一个对应的优先级寄存器,cortex-m0中nvic-ipr共有8个寄存器,而每个寄存器管理4个irq中断,所以m0的irq中断源最多只支持32个,再加上16个内核中断,也就是说m0最多48个中断源。
cortex-m0采用armv6-m架构,优先级寄存器配置位有8位,但是有效位只有最高2位,这个地方很多人使用了cortex-m3后一直也认为cortex-m0也是最高3或4位有效位,在arm官方资料中有对比两个版本的差别。因此cortex-m0可编程优先级有4个,加上3个固定的优先级(复位、nmi、hardfault),cortex-m0总共有7个中断优先级。
cortex-m0内核的中断优先级寄存器是以最高位(msb)对齐的,并且只支持字传输,每次访问都会同时涉及4个中断优先级寄存器。见下图:
因为bit0 - bit5没有使用,所以如果没有进行写操作读出都为0。
由于不同的 cortex-m 系列,其中断优先级是不一样的,所以在 cmsis 库中的头文件中可以查看优先级的数量 \_\_nvic\_prio\_bits。
中断优先级寄存器的编程应该在中断使能之前,其通常是在程序开始时完成的。arm官方资料提示应该避免在中断使能之后改变中断优先级,因为这种情况的结果在armv6-m系统结构是不可预知的,并且不被cortex-m0处理器支持。cortex-m3/m4处理器的情况又有所不同,他们都支持中断优先级的动态切换。cortex-m3处理器和cortex-m0处理器的另外一个区别是,cortex-m3访问中断优先级寄存器时支持字节或半字传输,因此可以每次只设置一个寄存器。如果需要改变优先级,程序中需要关闭中断后再重新设置中断优先级寄存器。
在 cortex-m内核中,一个中断的优先级数值越低,逻辑优先级却越高。比如,中断优先级为2的中断可以抢占中断优先级为3的中断,但反过来就不行。换句话说,中断优先级2比中断优先级3的优先级更高。
cortex-m0处理器对中断嵌套的支持无需任何软件干预,如果mcu已经在运行一个中断,而有了新的更高优先级的中断请求,正在运行的中断将会被暂停,转而执行更高优先级的中断,高优先级中断执行完成后又回到原来的低优先级中断。如果出现两个同一优先级的中断,则是判断谁开始发起中断请求,mcu会先执行同一优先级中首先发起请求的中断。
mm32f0130系列中断向量表:
typedef enum irqn {     nonmaskableint_irqn             = -14,                                  ///< 2 non maskable interrupt     hardfault_irqn                  = -13,                                  ///< 3 cortex-m0 hard fault interrupt     memorymanagement_irqn           = -12,                                  ///< 4 cortex-m0 memory management interrupt     busfault_irqn                   = -11,                                  ///< 5 cortex-m0 bus fault interrupt     usagefault_irqn                 = -10,                                  ///< 6 cortex-m0 usage fault interrupt     svc_irqn                        = -5,                                   ///< 11 cortex-m0 sv call interrupt     debugmonitor_irqn               = -4,                                   ///< 12 cortex-m0 debug monitor interrupt     pendsv_irqn                     = -2,                                   ///< 14 cortex-m0 pend sv interrupt     systick_irqn                    = -1,                                   ///< 15 cortex-m0 system tick interrupt     wwdg_iwdg_irqn                  = 0,                                    ///< watchdog interrupt     wwdg_irqn                       = 0,                                    ///< window watchdog interrupt     pvd_irqn                        = 1,                                    ///< pvd through exti line detect interrupt     bkp_irqn                        = 2,                                    ///< bkp through exti line interrupt     rtc_irqn                        = 2,                                    ///< rtc through exti line interrupt     flash_irqn                      = 3,                                    ///< flash interrupt     rcc_crs_irqn                    = 4,                                    ///< rcc & crs interrupt     rcc_irqn                        = 4,                                    ///< rcc interrupt     exti0_1_irqn                    = 5,                                    ///< exti line 0 and 1 interrupts     exti2_3_irqn                    = 6,                                    ///< exti line 2 and 3 interrupts     exti4_15_irqn                   = 7,                                    ///< exti line 4 to 15 interrupts     hwdiv_irqn                      = 8,                                    ///< hwdiv global interrupt     dma1_channel1_irqn              = 9,                                    ///< dma1 channel 1 interrupt     dma1_channel2_3_irqn            = 10,                                   ///< dma1 channel 2 and channel 3 interrupts     dma1_channel4_5_irqn            = 11,                                   ///< dma1 channel 4 and channel 5 interrupts     adc_comp_irqn                   = 12,                                   ///< adc & comp interrupts     comp_irqn                       = 12,                                   ///< comp interrupts     adc_irqn                        = 12,                                   ///< adc interrupts     adc1_irqn                       = 12,                                   ///< adc interrupts     tim1_brk_up_trg_com_irqn        = 13,                                   ///< tim1 break, update, trigger and commutation interrupts     tim1_cc_irqn                    = 14,                                   ///< tim1 capture compare interrupt     tim2_irqn                       = 15,                                   ///< tim2 interrupt     tim3_irqn                       = 16,                                   ///< tim3 interrupt     tim14_irqn                      = 19,                                   ///< tim14 interrupt     tim16_irqn                      = 21,                                   ///< tim16 interrupt     tim17_irqn                      = 22,                                   ///< tim17 interrupt     i2c1_irqn                       = 23,                                   ///< i2c1 interrupt     spi1_irqn                       = 25,                                   ///< spi1 interrupt     spi2_irqn                       = 26,                                   ///< spi1 interrupt     uart1_irqn                      = 27,                                   ///< uart1 interrupt     uart2_irqn                      = 28,                                   ///< uart2 interrupt     can_irqn                        = 30,                                   ///< can interrupt     usb_irqn                        = 31,                                   ///< usb interrupt } irqn_type;
设置中断优先级的流程:先读一个字,再修改对应字节,最后整个字写回。
1.1 c代码 void__nvic_setpriority() {     unsigned long temp;                              //定义一个临时变量     temp = *(volatile unsigned long)(0xe000e400); //读取irp0值     temp &= (0xff00ffff |(0xc0 <= 0) {         nvic->ip[_ip_idx(irqn)]  = ((uint32_t)(nvic->ip[_ip_idx(irqn)]  & ~(0xfful << _bit_shift(irqn))) |                                     (((priority << (8u - __nvic_prio_bits)) & (uint32_t)0xfful) shp[_shp_idx(irqn)] & ~(0xfful << _bit_shift(irqn))) |                                     (((priority << (8u - __nvic_prio_bits)) & (uint32_t)0xfful) << _bit_shift(irqn)));     } }
这里的参数irqn为中断id号,可以为负,也可以为正。当irqn为负时,设置系统异常的优先级,当irqn大于等于0时,设置外设中断优先级,芯片厂商会提供中断向量表irqn\_type,应用层只需要调用即可;priority是0、1、2、3,函数内部会自动移位到对应的优先级最高2位。
方法一: void nvic_setpriority(tim1_cc_irqn, 3) ; //设置#14中断的优先级为0xc0 方法二: void nvic_config(void) {    nvic_inittypedef nvic_initstructure;     nvic_initstructure.nvic_irqchannel = tim1_cc_irqn;     nvic_initstructure.nvic_irqchannelpriority = 3;     nvic_initstructure.nvic_irqchannelcmd = enable;     nvic_init(&nvic_initstructure); }
设置好中断优先级后,用户还可以读取当前已经设置的中断优先级。


功率放大器在超声激励甲烷氨燃烧火焰排放特性研究中的应用
业内专家谈5G热点问题,引入广电对市场格局影响较小
字节跳动今年已经为AI购买了超10亿美元的GPU
iPhone8什么时候上市?iPhone8最新消息:iPhone8机模曝光,屏幕内嵌指纹识别
回顾吴甘沙对中国无人驾驶的协同创新之路的分析和理解
Cortex-M0中断控制和系统控制
千寻位置助力华人运通自动驾驶应用加速落地
继高通之后微软又遭调查 棱镜门余波发酵?
数字化办公?选云桌面就对了!
W117/W217/W317恒流源电路图
经典与创新融合 黑莓旗舰KEY2正式发布
如何选择旁路电容
荣耀和华为是“父子”还是“兄弟”?
AMD发布五款RX600系列新显卡 主要用于笔记本
混合现实满足策展人对实物与数字之间无缝融合诉求
pic单片机多路ad切换程序与循环程序设计
5G+人工智能如何为用户提供更好的产品体验?
如何选择分压、限流电路?分压限流电路总结
紧抓可穿戴机遇 罗姆诠释如何从“小”做起
多种液体自动混合PLC控制