Cortex-M0中断控制和系统控制,二)

技术Cortex-M0中断控制和系统控制,二) Cortex-M0中断控制和系统控制(二)转载:https://aijishu.com/a/1060000000237975
每一个外部中断都有一个对应的

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

转载:https://aijishu.com/a/1060000000237975

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

Cortex-M0采用Armv6-M架构,优先级寄存器的配置位为8位,但最高有效位仅为2位。这个地方很多人一直认为Cortex-M0也是使用Cortex-M3后的3、4位最高有效位,arm官方信息中两个版本是有区别的。因此,Cortex-M0有四个可编程优先级,而Cortex-M0有三个固定优先级(复位、NMI和HardFault),总共有七个中断优先级。

Cortex-M0内核的中断优先级寄存器与最高有效位(MSB)对齐,仅支持字传输。每次访问同时涉及四个中断优先级寄存器。见下图:

因为不使用位0-位5,所以如果没有写操作,读出全部为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将首先执行与发起请求优先级相同的中断。

MM32F0130系列中断向量表:

typedefensumirqn {

NonMaskableInt_IRQn=-14,///2NonMaskableInterrupt

HardFault_IRQn=-13,///3 cortex-m0 hard fault interrupt

MemoryManagement_IRQn=-12,///4 cortex-m0 memorymanagementinterrupt

BusFault_IRQn=-11,///5Cortex-M0BusFaultInterrupt

UsageFault_IRQn=-10,///6 cortex-m0usagefaulttinterrupt

SVC_IRQn=-5,///11Cortex-M0SVCallInterrupt

DebugMonitor_IRQn=-4,///12 cortex-m0 debugmonitorinterrupt

PendSV_IRQn=-2,///14 ortex-m0 PendSV interrupt

SysTick_IRQn=-1,///15 cortex-m0systemtick interrupt

WWDG_IWDG_IRQn=0,///watchdointerrupt

WWDG_IRQn=0,///窗口监视中断

PVD_IRQn=1,///pvdthroothxtilinedprotectinterrupt

BKP_IRQn=2,///bkpthroughextiliineinterrupt

RTC_IRQn=2,///rtcthrughextilineinterrupt

FLASH_IRQn=3,///FLASHInterrupt

RCC_CRS_IRQn=4,///RCCCRSInterrupt

RCC_IRQn=4,///RCCInterrupt

EXTI0_1_IRQn=5,EXTI0和1Interrupts

EXTI2_3_IRQn=6,EXTI2和3中断

EXTI4_15_IRQn=7,///exti line4 to 15中断

HWDIV_IRQn=8,///HWDIVGlobalInterrupt

DMA1_Channel1_IRQn=9,///DMA1Channel1Interrupt

DMA1_Channel2_3_IRQn=10,///DMA1 channel 2和channel 3中断

DMA1_C

hannel4_5_IRQn=11,///DMA1Channel4andChannel5Interrupts
ADC_COMP_IRQn=12,///ADCCOMPInterrupts
COMP_IRQn=12,///COMPInterrupts
ADC_IRQn=12,///ADCInterrupts
ADC1_IRQn=12,///ADCInterrupts
TIM1_BRK_UP_TRG_COM_IRQn=13,///TIM1Break,Update,TriggerandCommutationInterrupts
TIM1_CC_IRQn=14,///TIM1CaptureCompareInterrupt
TIM2_IRQn=15,///TIM2Interrupt
TIM3_IRQn=16,///TIM3Interrupt
TIM14_IRQn=19,///TIM14Interrupt
TIM16_IRQn=21,///TIM16Interrupt
TIM17_IRQn=22,///TIM17Interrupt
I2C1_IRQn=23,///I2C1Interrupt
SPI1_IRQn=25,///SPI1Interrupt
SPI2_IRQn=26,///SPI1Interrupt
UART1_IRQn=27,///UART1Interrupt
UART2_IRQn=28,///UART2Interrupt
CAN_IRQn=30,///CANInterrupt
USB_IRQn=31,///USBInterrupt
}IRQn_Type;

设置中断优先级的流程:先读一个字,再修改对应字节,最后整个字写回。

1.1 C代码
void__NVIC_SetPriority()
{
unsignedlongtemp;//定义一个临时变量
temp=*(volatileunsignedlong)(0xE000E400);//读取IRP0值
temp=(0xFF00FFFF|(0xC016));//修改中断#2优先级为0xC0
*(volatileunsignedlong)(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);
}

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

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/126073.html

(0)

相关推荐

  • 对象与类

    技术对象与类 对象与类类:构造对象的模板或蓝图,类构造对象的过程称为创建类的实例
    封装(数据隐藏):将数据和行为组合在一个包里,并对对象使用者隐藏具体实现方式
    对象中的数据称为实例字段,操作数据的过程称

    礼包 2021年10月28日
  • Synchronized升级过程是怎样的

    技术Synchronized升级过程是怎样的Synchronized升级过程是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。要理解Synchron

    攻略 2021年10月20日
  • 一个火一个亘,左面一个火右面一个亘,念什么

    技术一个火一个亘,左面一个火右面一个亘,念什么烜xuǎn烜的中文解释以下结果由汉典提供词典解释部首笔画 部首:火部外笔画:6总笔画:10 五笔86:OGJG五笔98:OGJG仓颉:FMAM 笔顺编号:4334125111

    生活 2021年10月23日
  • 2019-2020 ICPC Asia Hong Kong Regional Contest

    技术2019-2020 ICPC Asia Hong Kong Regional Contest 2019-2020 ICPC Asia Hong Kong Regional ContestB - Bi

    礼包 2021年10月28日
  • 如何利用okhttp框架实现包含验证码的用户登录并保持session操作

    技术如何利用okhttp框架实现包含验证码的用户登录并保持session操作小编给大家分享一下如何利用okhttp框架实现包含验证码的用户登录并保持session操作,相信大部分人都还不怎么了解,因此分享这篇文章给大家参

    攻略 2021年11月18日
  • 关于mysql的相关操作是怎样的

    技术关于mysql的相关操作是怎样的这篇文章将为大家详细讲解有关关于mysql的相关操作是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、Mysql用户密码修改m

    攻略 2021年10月25日