ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基于STM32L4的NVIC中断系统

2021-09-15 13:33:29  阅读:307  来源: 互联网

标签:__ 优先级 中断 STM32L4 NVIC IRQn uint32


STM32L4中断系统

         STM32L4基于Cortex-M4架构,内部有一个嵌套中断向量控制器(NVIC)来管理异常,并将优先级最高的异常提交给CPU处理。异常的编号范围是1~255,其中编号1~15被归为系统异常(如NMI、SYSTICK等),编号16~255被归为外部异常(也称外部中断,如UART、EXTI等),各个异常源与NVIC和Core的关系如下图,

        对于STM32L4系列MCU,除了16个系统异常外,还支持82个中断源,这些中断源的优先级支持16级。

         NVIC对异常的管理通过一系列的寄存器进行,如外部中断控制的NVIC寄存器、系统异常控制的SCB寄存器、全局控制的特殊功能寄存器。

1.1、外部中断控制的NVIC寄存器

         NVIC寄存器用于控制外部中断IRQ的行为,如中断设置使能、中断清除使能、中断设置挂起、中断清除挂起、中断优先级设置、软件触发中断等。

  1. 中断使能配置寄存器的操作函数:

void __NVIC_EnableIRQ(IRQn_Type IRQn)  //使能中断,IRQn为中断编号,如USART3_IRQN;

void __NVIC_DisableIRQ(IRQn_Type IRQn) //禁止中断,IRQn为中断编号

uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)//获取中断使能状态,返回1:使能,0:禁止

  1. 中断挂起寄存器的操作函数:

void __NVIC_SetPendingIRQ(IRQn_Type IRQn) //设置挂起位,IRQn为中断编号

void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)//清除挂起位,IRQn为中断编号

uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) //获取挂起位状态,返回1:挂起,0:未挂起

  1. 活跃状态寄存器的操作函数:

uint32_t __NVIC_GetActive(IRQn_Type IRQn) //获取活跃位状态,返回1:活跃,0:未活跃

当某个活跃位置1时,表示MCU当前正在处理该中断的服务程序,执行完成后,该活跃位自动被清零;

当低优先级的中断服务程序正在执行时,高优先级中断挂起,则MCU打断低优先级中断,执行高优先级的中断服务程序,此时,低优先级与高优先级的活跃位均置1。

  1. 优先级配置寄存器

void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

//设置中断优先级,IRQn为中断编号,priority为优先级,STM32L4支持16级,即priority取值为0~15;

uint32_t __NVIC_GetPriority(IRQn_Type IRQn) //获取中断优先级,IRQn为中断编号

  1. 软件中断设置寄存器

NVIC->STIR = IRQn // IRQn为中断编号

软件中断设置与中断挂起设置寄存器使用的效果一致,都能触发一次软件中断。

1.2、系统异常控制的SCB寄存器

         SCB寄存器用于配置系统异常,包含系统异常使能、异常挂起设置与清除、优先级、活跃状态查询等;同时还有错误源状态与系统调试相关的寄存器。

         在SCB模块中,与系统异常设置有关的主要是SCB->ICSR、SCB->AIRCR、SCB->SHP[X]、SCB->SHCSR寄存器,相关的异常有NMI、FAULT、SVC、PendSV、SysTick等,对应的使能与挂起位配置如下表所示:

  1. NMI挂起位设置

SCB->ICSR |= (1 << 31); 或 (*((volatile uint32_t *)0xe000ed04)) |= (1 << 31);

  1. Memmanage错误

//使能Memmanage异常中断,默认关闭

SCB->SHCSR |= 1 << 16;或(*((volatile uint32_t *)0xe000ed24)) |= (1 << 16);

 //设置优先级,IRQn = -12;

__NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

或(*((volatile uint32_t *)0xe000ed18)) = priority;

  1. 总线错误

//使能总线异常中断,默认关闭

SCB->SHCSR |= 1 << 17; 或(*((volatile uint32_t *)0xe000ed24)) |= (1 << 17);

//设置优先级,IRQn = -11;

__NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

或(*((volatile uint32_t *)0xe000ed19)) = priority;

  1. 使用错误

//使能使用异常中断,默认关闭

SCB->SHCSR |= 1 << 18; 或(*((volatile uint32_t *)0xe000ed24)) |= (1 << 18);

//设置优先级,IRQn = -10;

__NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

或(*((volatile uint32_t *)0xe000ed1A)) = priority;

  1. SVC系统调用

//系统调用指令,执行SVC_HANDLER()处理函数;

svc 0

//设置优先级,IRQn = -5;

__NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

或(*((volatile uint32_t *)0xe000ed1F)) = priority;

  1. PendSV可挂起的系统调用

//设置pendsv挂起位

SCB->ICSR |= (1 << 28); 或 (*((volatile uint32_t *)0xe000ed04)) |= (1 << 28);

//清除pendsv挂起位

SCB->ICSR |= (1 << 27); 或 (*((volatile uint32_t *)0xe000ed04)) |= (1 << 27);

//设置优先级,IRQn = -2;

__NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

或(*((volatile uint32_t *)0xe000ed22)) = priority;

  1. SysTick定时器

//异常使能

SysTick->CTRL |= (1 << 2); 或 (*((volatile uint32_t *)0xe000e010)) |= (1 << 2);

//设置SYSTICK挂起位

SCB->ICSR |= (1 << 26); 或 (*((volatile uint32_t *)0xe000ed04)) |= (1 << 26);

//清除SYSTICK挂起位

SCB->ICSR |= (1 << 25); 或 (*((volatile uint32_t *)0xe000ed04)) |= (1 << 25);

//设置优先级,IRQn = -1;

__NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

或(*((volatile uint32_t *)0xe000ed23)) = priority;

1.3、全局控制的特殊寄存器

         全局中断使能与禁止主要是操作内核CPSR寄存器的I位与F位的置1与清0状态。

A、PRIMASK

         用于禁止除了NMI和HardFault外的所有异常和中断,内核提供的操作函数为:

         void __set_PRIMASK(uint32_t priMask);

         uint32_t __get_PRIMASK(void);

         举例:

         /* Disable interrupts*/

         uint32_t  primask_bit = __get_PRIMASK();

       __disable_irq();

         //…不可中断代码

         /* Re-enable the interrupts */

    __set_PRIMASK(primask_bit);

B、FAULTMASK

         用于禁止除了NUM外的所有异常和中断,包含HardFault也被屏蔽,内核提供的操作函数为:

         uint32_t __get_FAULTMASK(void);

         void __set_FAULTMASK(uint32_t faultMask);

         举例:

         /* Disable interrupts*/

         uint32_t  faultmask_bit = __get_ FAULTMASK ();

       __disable_fault_irq ();

         //…不可中断代码

         /* Re-enable the interrupts */

__set_ FAULTMASK (faultmask_bit);

C、BASEPRI

         该寄存器用于禁止优先级低于某特定等级的中断,在内核提供的操作函数如下:

         uint32_t  __get_BASEPRI(void);//获取当前被屏蔽等级阈值

         void __set_BASEPRI(uint32_t basePri);//设置当前被屏蔽的等级阈值

         举例:

         __set_BASEPRI(0x60); //禁止优先级在0x60~0xFF间的中断。

1.4、Core控制模块的地址空间

         ARM Cortex m4地址总线位宽32bit,支持4G的存储器容量,但实际在MCU中最多支持几个M的Flash容量,因此其它的地址位置用于各种外设的访问。

         4G的地址空间被分为8个块,每个块512M,代码区域为首块(0x00000000~0x1FFFFFFF),内部SRAM区域为第二块(0x20000000~0x3FFFFFFF),而内核控制模块则位于第8块,如下图所示:

标签:__,优先级,中断,STM32L4,NVIC,IRQn,uint32
来源: https://blog.csdn.net/goodshanzi/article/details/119683535

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有