1. 点亮LED灯
任务说明
本案例使用STM32F103系列单片机(以STM32F103C8T6为例),通过直接操作GPIO寄存器,将PC13引脚配置为推挽输出并输出低电平,从而点亮开发板上连接至PC13的LED灯。核心目标是掌握寄存器地址映射关系、时钟使能配置以及基本的GPIO输出操作,不借助标准外设库或HAL库。
寄存器地址映射
STM32F103的GPIO外设挂载在APB2总线上,其基地址为0x40021000。GPIO端口C的基地址为0x40011000,偏移量计算如下:
- RCC_APB2ENR:地址0x40021018,bit4(IOPCEN)用于使能GPIOC时钟;
- GPIOC_CRH:地址0x40011004,控制PC8~PC15引脚模式(PC13对应bit20~bit23);
- GPIOC_ODR:地址0x4001100C,bit13对应PC13输出数据。
代码实现
// main.c
#include "stm32f10x.h"
// 寄存器地址定义
#define RCC_APB2ENR (*(volatile unsigned long *)0x40021018)
#define GPIOC_CRH (*(volatile unsigned long *)0x40011004)
#define GPIOC_ODR (*(volatile unsigned long *)0x4001100C)
// 位定义
#define RCC_IOPCEN (1 << 4) // GPIOC时钟使能位
#define LED_PIN (1 << 13) // PC13
void LED_Init(void)
{
// 1. 使能GPIOC时钟
RCC_APB2ENR |= RCC_IOPCEN;
// 2. 配置PC13为推挽输出,最大速度2MHz
// CRH寄存器bit20~bit23对应PC13
// MODE13[1:0] = 10 (输出模式,2MHz)
// CNF13[1:0] = 00 (通用推挽输出)
GPIOC_CRH &= ~(0xF << 20); // 先清零
GPIOC_CRH |= (0x2 << 20); // 写入MODE=10, CNF=00
}
void LED_On(void)
{
// 输出低电平点亮LED(共阳极接法)
GPIOC_ODR &= ~LED_PIN;
}
int main(void)
{
LED_Init();
LED_On();
while(1)
{
// 保持点亮状态
}
}
编译与烧录
使用Keil MDK或arm-none-eabi-gcc工具链编译。工程需包含STM32F10x启动文件(startup_stm32f10x_md.s)和系统初始化文件(system_stm32f10x.c)。编译生成HEX文件后,通过ST-Link或串口ISP下载至开发板。
验证方法
将程序烧录至开发板并复位后,观察PC13引脚连接的LED灯状态。若LED正常点亮,说明寄存器配置正确。可通过以下步骤进一步验证:
- 用万用表测量PC13引脚电压,应为低电平(接近0V);
- 修改
LED_On()中操作为GPIOC_ODR |= LED_PIN,重新编译烧录后LED应熄灭,验证输出控制方向正确。
判定标准
LED持续点亮且PC13引脚为低电平,即判定案例通过。若LED不亮,检查RCC_APB2ENR的bit4是否置1、CRH寄存器bit20~bit23是否配置为0x2,以及ODR的bit13是否为0。