0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Cortex-M0中断控制和系统控制知识点

安芯教育科技 来源:灵动MM32MCU 2023-03-20 09:28 次阅读

上一篇介绍了Cortex-M0中断控制和系统控制(一),本篇将继续介绍Cortex-M0中断控制知识。

每一个外部中断都有一个对应的优先级寄存器,Cortex-M0中NVIC-IPR共有8个寄存器,而每个寄存器管理4个IRQ中断,所以M0的IRQ中断源最多只支持32个,再加上16个内核中断,也就是说M0最多48个中断源。

a58d7684-c4c8-11ed-bfe3-dac502259ad0.png

a59e6d4a-c4c8-11ed-bfe3-dac502259ad0.png

Cortex-M0采用Armv6-M架构,优先级寄存器配置位有8位,但是有效位只有最高2位,这个地方很多人使用了Cortex-M3后一直也认为Cortex-M0也是最高3或4位有效位,在arm官方资料中有对比两个版本的差别。因此Cortex-M0可编程优先级有4个,加上3个固定的优先级(复位、NMI、HardFault),Cortex-M0总共有7个中断优先级。

a5b3668c-c4c8-11ed-bfe3-dac502259ad0.png

Cortex-M0内核的中断优先级寄存器是以最高位(MSB)对齐的,并且只支持字传输,每次访问都会同时涉及4个中断优先级寄存器。见下图:

a60657e8-c4c8-11ed-bfe3-dac502259ad0.png

因为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系列中断向量表:

typedefenumIRQn{

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()
{
unsignedlongtemp;//定义一个临时变量
temp=*(volatileunsignedlong)(0xE000E400);//读取IRP0值
temp&=(0xFF00FFFF|(0xC0<< 16));            //修改中断#2优先级为0xC0
    *(volatile unsigned long)(0xE000E400) = temp; //设置IPR0
}

1.2. 汇编代码

在程序中可以一次设置多个中断优先级。

void__NVIC_SetPriority()
{
LDRR0,=0xE000E100;//设置使能中断寄存器地址
MOVSR1,#0x4;//中断#2
STRR1,[R0];//使能#2中断
LDRR0,=0xE000E200;//设置挂起中断寄存器地址
MOVSR1,#0x4;//中断#2
STRR1,[R0];//挂起#2中断
LDRR0,=0xE000E280;//设置清除中断挂起寄存器地址
MOVSR1,#0x4;//中断#2
STRR1,[R0];//清除#2的挂起状态
}

1.3. CMSIS标准设备驱动函数

//设置中断优先级
__STATIC_INLINEvoid__NVIC_SetPriority(IRQn_TypeIRQn,uint32_tpriority)
{
if((int32_t)(IRQn)>=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) << _BIT_SHIFT(IRQn)));
    }
    else {
        SCB->SHP[_SHP_IDX(IRQn)]=((uint32_t)(SCB->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位。

方法一:
voidNVIC_SetPriority(TIM1_CC_IRQn,3);//设置#14中断的优先级为0xC0
方法二:
voidNVIC_Config(void)
{NVIC_InitTypeDefNVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel=TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

设置好中断优先级后,用户还可以读取当前已经设置的中断优先级。

审核编辑:汤梓红

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

    关注

    68

    文章

    18288

    浏览量

    222193
  • 寄存器
    +关注

    关注

    30

    文章

    5032

    浏览量

    117746
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39850
  • 中断
    +关注

    关注

    5

    文章

    884

    浏览量

    41028
  • Cortex-M0
    +关注

    关注

    4

    文章

    122

    浏览量

    38356

原文标题:Cortex-M0中断控制和系统控制(二)

文章出处:【微信号:Ithingedu,微信公众号:安芯教育科技】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    ARM Cortex-M0权威指南(英文版)

    嵌入式系统课程(ARM Cortex-M0)的高年级本科生及研究生等。Joseph Yiu是英国ARM公司微控制系统级设计专家,是ARM Cort
    发表于 10-08 16:46

    基于Cortex-M0的Nano100系列微控制器评估板

    Nu-LB-Nano130,基于Cortex-M0的Nano100系列微控制器评估板,为Nano130微控制器提供完整的开发环境,具有8 / 16K字节内部SRAM和32/64/128K字节嵌入式
    发表于 03-27 08:18

    灵动微课堂 (第175讲) | Cortex-M0中断控制系统控制(一)

    Controller)集成在Cortex-M0处理器里,它与处理器内核紧密相连,并且提供了中断控制功能以及对系统异常的支持。处理器的NV
    发表于 07-29 17:14

    灵动微课堂 (第176讲) | Cortex-M0中断控制系统控制(二)

    每一个外部中断都有一个对应的优先级寄存器,Cortex-M0NVIC-IPR共有8个寄存器,而每个寄存器管理4个IRQ中断,所以M0的IR
    发表于 07-29 18:49

    灵动微课堂 (第177讲) | Cortex-M0中断控制系统控制(三)

    Cortex-M0处理器允许两种形式的中断请求:电平触发和脉冲输入。电平触发是外设的中断请求有持续的电平信号,若电平信号在处理器从ISR返回之前没有被取消,则中断返回后将再次触发已经服
    发表于 07-29 18:51

    灵动微课堂 (第178讲) | Cortex-M0中断控制系统控制(四)

    Cortex-M0系统控制块(SCB)是内核外设的主要模块之一,提供系统控制以及系统执行信息,包括配置,控制,上报
    发表于 08-06 14:49

    STM32外部中断知识点概述

    STM32外部中断概述知识点(1)知识点(2)知识点(3)中断服务函数外部中断常用库函数外部
    发表于 08-16 07:43

    灵动微课堂 (第180讲) | Cortex-M0中断控制系统控制(六)

    MRS, MSR, 1.2存储器访问确保访问的内存地址是对齐的,这一很重要。在ARMv6-M架构(包括Cortex-M0Cortex-M0处理器)上不支持非对齐传输。任何未对齐内存
    发表于 08-23 11:02

    Cortex-A7中断系统知识点汇总,看完你就懂了

    Cortex-A7中断系统知识点汇总,看完你就懂了
    发表于 11-29 08:00

    基于Cortex-M0中断系统的IP集成与中断服务函数设计

    为极术线上技术分享干货汇总(含PPT下载及视频回放及线下活动资料下载,持续更新,欢迎收藏~整理:极术社区集创赛Arm杯彭吉安-(集创赛)基于Cortex-M0中断系统的IP集成与中断
    发表于 12-14 07:15

    ATmega16系列a04_INT0及INT1中断知识点汇总,绝对实用

    ATmega16系列a04_INT0及INT1中断知识点汇总,绝对实用
    发表于 01-24 07:39

    系统控制中断

    系统控制中断
    发表于 04-29 17:57 124次下载

    Cortex-M0中断控制系统控制(二)

    每一个外部中断都有一个对应的优先级寄存器,Cortex-M0中NVIC-IPR共有8个寄存器,而每个寄存器管理4个IRQ中断,所以M0的IRQ中断源最多只支持32个,再加上16个内核
    发表于 02-08 15:48 2次下载
    <b class='flag-5'>Cortex-M0</b><b class='flag-5'>中断</b><b class='flag-5'>控制</b>和<b class='flag-5'>系统控制</b>(二)

    Cortex-M0中断控制系统控制

    Cortex-M0采用Armv6-M架构,优先级寄存器配置位有8位,但是有效位只有最高2位,这个地方很多人使用了Cortex-M3后一直也认为Cortex-M0也是最高3或4位有效位
    的头像 发表于 04-24 11:20 2640次阅读

    Cortex-M0系统控制块(SCB)介绍

    Cortex-M0系统控制块(SCB)是内核外设的主要模块之一,提供系统控制以及系统执行信息,包括配置,控制,上报
    的头像 发表于 03-25 15:14 3487次阅读