STM32F103C8蓝板GPIO驱动配置问题:内置LED控制失效
STM32F1 内置LED自定义驱动故障排查与修复
问题描述
在STM32F1开发板上编写自定义驱动控制内置LED,尝试将PortC引脚13配置为推挽输出并置位,但代码无法正常运行。
原代码
#include<stdint.h> #define RCC_BASE_ADDR 0x40021000UL //RCC BASE ADDRESS #define RCC_APB2_ENR_OFFSET 0x18UL #define RCC_APB2_ENR_ADDR (RCC_BASE_ADDR + RCC_APB2_ENR_OFFSET) //##################################### #define GPIOC_BASE_ADDR 0x40011000UL #define GPIO_CTR_OFFSET 0x00UL //GPIO controll register #define GPIO_CTR_ADDR (GPIOC_BASE_ADDR + GPIO_CTR_OFFSET) #define GPIO_MODE_OUT_OFFSET 0x0CUL //GPIO OUTPUT MODE #define GPIO_MODE_OUT_ADDR (GPIOC_BASE_ADDR + GPIO_MODE_OUT_OFFSET) #define GPIO_BSRR_OFFSET 0x10UL //GPIO BIT SET RESET REGISTER #define GPIO_BSRR_ADDR (GPIOC_BASE_ADDR + GPIO_BSRR_OFFSET) int main() { uint32_t *pRCCAPB2EnReg = (uint32_t *)RCC_APB2_ENR_ADDR; uint32_t *pGPIOCtr = (uint32_t *)GPIO_CTR_ADDR; uint32_t *pGPIOModeOut = (uint32_t *)GPIO_MODE_OUT_ADDR; uint32_t *pGPIOBSRR = (uint32_t *)GPIO_BSRR_ADDR; *pRCCAPB2EnReg |= (1<<4); *pGPIOCtr |= (0<<3); *pGPIOCtr |= (0<<2); *pGPIOCtr |= (0<<1); *pGPIOCtr |= (1<<0); *pGPIOModeOut |= (1<<13); *pGPIOBSRR |= (1<<13); return 0; }
问题分析与修复步骤
- 寄存器定义错误:STM32F1的GPIO端口配置寄存器分为
GPIO_CRL(偏移0x00,控制引脚0-7)和GPIO_CRH(偏移0x04,控制引脚8-15),PC13属于引脚8-15范围,必须操作GPIO_CRH而非自定义的GPIO_CTR。另外STM32F1不存在GPIO_MODE_OUT寄存器,输出模式和速度均在CRL/CRH中配置。 - 引脚配置位错误:PC13对应的配置位是
GPIO_CRH的位20-23(每个引脚占4位,计算方式:4*(13-8)=20)。推挽输出需将这4位设置为0011:CNF[1:0]设为00(通用推挽输出),MODE[1:0]设为11(50MHz输出速度)。 - 主函数缺少死循环:嵌入式程序执行完
main的return后会进入不可控状态,必须添加while(1)让程序持续运行,确保配置生效。
修正后的代码
#include<stdint.h> #define RCC_BASE_ADDR 0x40021000UL #define RCC_APB2_ENR_OFFSET 0x18UL #define RCC_APB2_ENR_ADDR (RCC_BASE_ADDR + RCC_APB2_ENR_OFFSET) #define GPIOC_BASE_ADDR 0x40011000UL #define GPIOC_CRH_OFFSET 0x04UL // 控制引脚8-15的配置寄存器 #define GPIOC_CRH_ADDR (GPIOC_BASE_ADDR + GPIOC_CRH_OFFSET) #define GPIO_BSRR_OFFSET 0x10UL #define GPIO_BSRR_ADDR (GPIOC_BASE_ADDR + GPIO_BSRR_OFFSET) int main() { uint32_t *pRCCAPB2EnReg = (uint32_t *)RCC_APB2_ENR_ADDR; uint32_t *pGPIOC_CRH = (uint32_t *)GPIOC_CRH_ADDR; uint32_t *pGPIOBSRR = (uint32_t *)GPIO_BSRR_ADDR; // 使能GPIOC时钟 *pRCCAPB2EnReg |= (1 << 4); // 配置PC13为推挽输出,50MHz速度 // 先清除PC13对应的4位,再设置为0011 *pGPIOC_CRH &= ~(0xF << 20); *pGPIOC_CRH |= (0x3 << 20); // 置位PC13(部分开发板LED为低电平点亮,若不亮可改为*(pGPIOBSRR) = (1 << (13+16))) *pGPIOBSRR = (1 << 13); // 死循环保持程序运行 while(1); return 0; }
额外说明
部分STM32F1开发板的内置LED是低电平触发(PC13拉低时点亮),如果修正后LED仍不亮,将置位代码改为:
*pGPIOBSRR = (1 << (13 + 16)); // BSRR的高16位是复位位,拉低PC13
内容的提问来源于stack exchange,提问作者GiGeNCo
相关产品推荐
相关产品推荐

