nRF52832 中断相关

本文介绍了nRF52832芯片的中断系统,包括中断号的分布、中断等级、中断优先级设置以及相关操作函数。重点提到了中断表的位置(VTOR)、中断抢占优先级和亚优先级,并提供了开启、关闭、挂起和清除中断的方法。此外,还讨论了系统时钟中断的配置和系统复位功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中断号见《nrf52.h》 66行至117行,负数为cortex-M4内核中断(内部中断),0与正数为厂商自定义中断(外部中断)。
函数名见《iar_startup_nrf52.s》 78行至134行。

中断等级0~7,有点少吧。
注意:SCB->VTOR定义中断表位置(Vector Table Offset Register)。
默认抢占中断等级3位,0~7全是抢占中断。

中断抢占优先级和亚优先级,具体定义见宋岩译《Cortex-M3 权威指南》,110页,不做引用(M3与M4变化不大)。
__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void);

设置中断优先级,外部内部中断都可用(自动分辨正负号)。
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority);
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn);

开挂中断,注意以下只支持外部中断。
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn);
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn);
是否挂起
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);
软件挂起
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);
清除挂起
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn);
是否激活
__STATIC_INLINE u

### 实现 nRF52832 上的中断捕获 在 nRF52832 微控制器中,通过配置外设并编写相应的中断服务程序 (ISR),可以实现对外部事件或内部定时器事件的响应。对于 GPIO 和定时器产生的中断,具体操作如下: #### 配置 GPIO 中断 为了使能某个特定引脚上的边沿触发中断,在初始化阶段需设置该引脚的方向为输入,并指定其工作模式(上升沿/下降沿)。之后调用 `NRF_GPIO->INTENSET` 来开启对应的中断请求。 ```c void setup_gpio_interrupt(uint32_t pin_number, uint32_t config){ NRF_GPIO->PIN_CNF[pin_number] = config; // 设置引脚配置 NVIC_SetPriority(GPIOTE_IRQn, 1); // 设定优先级 NVIC_EnableIRQ(GPIOTE_IRQn); // 启动 GPIOTE 中断向量 } ``` 当检测到设定条件满足时会自动跳转至预先定义好的 ISR 函数内执行相应逻辑[^1]。 #### 定义和注册中断服务例程 针对不同的硬件模块有不同的 IRQ Handler 名称约定;这里以通用可编程 I/O 外设为例说明如何创建一个简单的回调机制来处理按键按下事件: ```c // 在 main.c 文件顶部声明外部函数原型 extern void GPIOTE_IRQHandler(void); // 编写具体的中断处理器代码 void GPIOTE_IRQHandler(void){ if(NRF_GPIOTE->EVENTS_IN[0]){ /* 清除事件 */ NRF_GPIOTE->EVENTS_IN[0] = 0; // 插入用户自定义动作... toggle_led(); // 切换 LED 状态作为示范 /* 如果有更多任务要在此处完成,请继续添加 */ } } ``` 上述例子展示了基本框架,实际开发过程中可能还需要考虑其他因素如多路复用、去抖动等细节问题[^2]。 #### 使用定时器捕捉周期性时间间隔 除了直接由物理信号引起的瞬态变化之外,有时也需要依靠软件计数的方式获取固定频率的时间戳。此时可以选择利用芯片内置的定时器资源配合 PWM 功能生成脉冲序列供后续分析计算之用。 ```c void timer_init(){ // 初始化 TIMER0 并启动它 NRF_TIMER0->TASKS_CLEAR = 1; // 配置比较寄存器 CC[0], 当计数值等于此值时产生匹配事件 NRF_TIMER0->CC[0] = COMPARE_VALUE; // 允许 Compare[0] 的中断 NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk; // 注册定时器中断处理函数 NVIC_SetPriority(TIMER0_IRQn, 1); NVIC_EnableIRQ(TIMER0_IRQn); } void TIMER0_IRQHandler() { if ((NRF_TIMER0->EVENTS_COMPARE[0]) != 0) { // 执行需要定期重复的任务 do_periodic_task(); // 清除中断标志位 NRF_TIMER0->EVENTS_COMPARE[0] = 0; } } ``` 这段代码片段实现了每经过一定毫秒后就触发一次中断的功能,可以在 `do_periodic_task()` 方法体内放置任何希望按规律循环运行的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值