1. 点亮LED灯

点亮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正常点亮,说明寄存器配置正确。可通过以下步骤进一步验证:

  1. 用万用表测量PC13引脚电压,应为低电平(接近0V);
  2. 修改LED_On()中操作为GPIOC_ODR |= LED_PIN,重新编译烧录后LED应熄灭,验证输出控制方向正确。

判定标准

LED持续点亮且PC13引脚为低电平,即判定案例通过。若LED不亮,检查RCC_APB2ENR的bit4是否置1、CRH寄存器bit20~bit23是否配置为0x2,以及ODR的bit13是否为0。

寄存器操作点亮LED — 地址映射与配置流程 RCC_APB2ENR 0x40021018 | bit4=1 GPIOC_CRH 0x40011004 | bit23:20=0x2 GPIOC_ODR 0x4001100C | bit13=0 ① 使能GPIOC时钟 RCC_APB2ENR |= (1<<4) ② 配置PC13推挽输出 CRH bit23:20 = 0x2 ③ 输出低电平点亮LED ODR bit13 = 0 PC13引脚 → LED → VCC(共阳极)