树莓派Pico RP2040寄存器级C编程实现LED闪烁问题求助
问题排查&修复方案
核心问题1:寄存器读写函数实现完全错误
你当前的write32/read32只是修改了局部变量的值,完全没有对指定地址的硬件寄存器做读写操作,要操作内存映射的寄存器,需要把地址转成指针再解引用:
void write32(uint addr, uint val) { *(volatile uint *)addr = val; } uint read32(uint addr) { return *(volatile uint *)addr; }
注意必须加volatile关键字,防止编译器把寄存器操作优化掉
核心问题2:缺少GPIO25的功能选择配置
树莓派Pico的GPIO引脚默认不是SIO输出模式,需要先配置IO_BANK0的GPIO25控制寄存器,把引脚功能切换为SIO,补充对应寄存器定义后在初始化阶段配置即可。
其他问题
- 你代码里的LED熄灭逻辑、延时逻辑全部被注释了,就算前面修复完也只会让LED常亮,不会闪烁
- 延时函数的计数器
i没有在每次循环里重置,就算取消注释也只会第一次延时生效,之后会直接跳过延时 - 直接写GPIO_OUT寄存器会覆盖所有引脚的输出状态,推荐用
GPIO_OUT_SET/GPIO_OUT_CLR寄存器单独操作目标引脚,不会影响其他引脚
修正后的完整myblink.c代码
#include <stdint.h> // 寄存器定义 #define SIO_BASE 0xd0000000 #define GPIO_OUT_SET (SIO_BASE + 0x014) #define GPIO_OUT_CLR (SIO_BASE + 0x018) #define GPIO_OE_SET (SIO_BASE + 0x024) #define IO_BANK0_BASE 0x40014000 #define GPIO25_CTRL (IO_BANK0_BASE + 0x0cc) #define GPIO_FUNC_SIO 5 typedef uint32_t uint; void write32(uint addr, uint val) { *(volatile uint *)addr = val; } uint read32(uint addr) { return *(volatile uint *)addr; } static void delay(uint cycles) { for (uint i = 0; i < cycles; i++) { // 加空操作防止延时被编译器优化 __asm__ volatile ("nop"); } } int main() { // 配置GPIO25为SIO功能 write32(GPIO25_CTRL, GPIO_FUNC_SIO); // 设置GPIO25为输出模式 write32(GPIO_OE_SET, 1 << 25); while (1) { // 点亮LED write32(GPIO_OUT_SET, 1 << 25); delay(0x80000); // 熄灭LED write32(GPIO_OUT_CLR, 1 << 25); delay(0x80000); } }
CMakeLists.txt无需修改,直接重新编译烧录即可正常运行
内容的提问来源于stack exchange,提问作者Matheus Costa
相关产品推荐
相关产品推荐

