RP2040通过寄存器配置GPIO2电平变化中断的问题求助
纯寄存器配置RP2040 GPIO2电平变化中断
直接给你不依赖Pico SDK的纯寄存器操作步骤,从GPIO初始化到中断回调设置全流程:
1. 初始化GPIO2为输入
先把GPIO2配置成通用输入模式,可选启用内部上拉:
- 设置GPIO功能为SIO(通用IO):
*(volatile uint32_t*)0x40014008 = 5; // IO_BANK0_GPIO2_CTRL,功能5对应SIO - 配置为输入方向:
*(volatile uint32_t*)0xD0000000 &= ~(1 << 2); // SIO_GPIO_OE_CLR,清除第2位,设为输入 - (可选)启用内部上拉电阻:
*(volatile uint32_t*)0x40014004 |= (1 << 4); // IO_BANK0_GPIO2_PAD,PUE位置1
2. 配置电平变化触发条件
电平变化中断需要同时开启上升沿和下降沿触发:
- 启用GPIO2上升沿中断:
*(volatile uint32_t*)0xD0000010 |= (1 << 2); // SIO_GPIO_INTE_RISE,第2位置1 - 启用GPIO2下降沿中断:
*(volatile uint32_t*)0xD0000014 |= (1 << 2); // SIO_GPIO_INTE_FALL,第2位置1
3. 路由中断到PROC0
你提到的IO_BANK0_PROC0_INTE0寄存器,需要打开GPIO2对应的中断允许位,让中断信号能传到核心0:
*(volatile uint32_t*)0x40014070 |= (1 << 2); // IO_BANK0_PROC0_INTE0,允许GPIO2中断发往PROC0
4. 设置中断回调与向量表
RP2040的IO_BANK0中断在NVIC中的编号是21,对应向量表的索引是16(系统异常数)+21=37。
编写中断回调函数
注意必须在回调里清除中断标志,否则会反复触发:
void gpio2_interrupt_handler(void) { // 先清除GPIO2的中断标志 *(volatile uint32_t*)0xD0000020 |= (1 << 2); // SIO_GPIO_INTF_CLR,写1清除标志 // 这里写你的中断处理逻辑,比如翻转LED、记录状态等 }
挂载回调到中断向量表
如果是裸机环境,直接修改向量表对应位置:
// 把回调函数地址写入向量表的对应索引位置 *(volatile uint32_t*)(0x00000000 + 37*4) = (uint32_t)gpio2_interrupt_handler;
如果你的工程已经重定位了向量表到RAM,就修改对应RAM地址的位置。
5. 启用中断
最后要打开NVIC中的IO_BANK0中断,以及全局中断:
- 启用NVIC中的IO_BANK0中断:
*(volatile uint32_t*)0xE000E100 |= (1 << 21); // NVIC_ISER0,第21位置1 - 开启ARM核心的全局中断:
__asm__ volatile ("cpsie i"); // Cortex-M0+启用全局中断指令
关键提醒
- 所有寄存器地址都来自RP2040官方数据手册,确保地址正确。
- 中断回调里必须清除
SIO_GPIO_INTF_CLR对应位,否则中断会持续触发。 - 如果是用汇编写裸机,要注意回调函数的栈帧处理,C语言的话编译器会自动处理。
内容的提问来源于stack exchange,提问作者eLeCtrOssSnake
相关产品推荐
相关产品推荐

