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)

相关推荐

  • Vue3知识地图之Vue生命周期函数与常用模板语法

    技术Vue3知识地图之Vue生命周期函数与常用模板语法本篇内容主要讲解“Vue3知识地图之Vue生命周期函数与常用模板语法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue

    攻略 2021年10月22日
  • css又称什么

    技术css又称什么这篇文章主要介绍“css又称什么”,在日常操作中,相信很多人在css又称什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”css又称什么”的疑惑有所帮助!接下来,请跟着小

    攻略 2021年11月17日
  • 皮鞋上的油污怎么办,皮鞋上有了油点该怎样去除掉

    技术皮鞋上的油污怎么办,皮鞋上有了油点该怎样去除掉皮鞋干裂牛奶擦 喝剩的牛奶或有些放置了几日的牛奶皮鞋上的油污怎么办,不要倒掉,用它擦皮鞋或其它皮革制品岢以防止皮质干裂。要想把皮鞋擦得很亮,可在鞋油里滴上几嘀清水,旧皮鞋

    生活 2021年10月23日
  • 怎么使用scikit-learn工具来进行PCA降维

    技术怎么使用scikit-learn工具来进行PCA降维本篇文章为大家展示了怎么使用scikit-learn工具来进行PCA降维,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1.

    2021年11月2日
  • mysql中char和varchar的区别有哪些

    技术mysql中char和varchar的区别有哪些本篇内容主要讲解“mysql中char和varchar的区别有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql

    攻略 2021年12月3日
  • ADO.NET连接管理器故障怎么排除

    技术ADO.NET连接管理器故障怎么排除这篇文章主要介绍“ADO.NET连接管理器故障怎么排除”,在日常操作中,相信很多人在ADO.NET连接管理器故障怎么排除问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法

    攻略 2021年12月3日