2. LED闪烁

任务说明

本案例基于寄存器直接操作方式,使用延时函数控制LED交替亮灭,实现LED闪烁效果。核心目标是掌握循环结构在延时控制中的应用,以及通过寄存器地址操作GPIO输出电平的方法。案例以STM32F103系列单片机为硬件平台,LED接在PC13引脚(板上LED),低电平点亮。

硬件连接

STM32F103 Cortex-M3 PC13 GPIO Port C 330Ω GND 限流电阻 LED (阳极) 阴极→GND PC13输出低电平 → LED点亮

PC13通过330Ω限流电阻连接LED阳极,LED阴极接地。当PC13输出低电平时LED点亮,输出高电平时LED熄灭。

寄存器配置

操作PC13需要配置两个寄存器:GPIOC_CRH(端口配置高寄存器,控制PC8~PC15)和GPIOC_ODR(端口输出数据寄存器)。PC13对应CRH的bit20~23,将其设置为通用推挽输出(CNF=00,MODE=01,即0x1),输出模式为2MHz。ODR寄存器的bit13控制PC13输出电平。

代码实现

以下代码通过寄存器地址直接操作,实现LED以约1秒周期闪烁(亮500ms,灭500ms)。延时函数使用简单的循环递减实现,便于理解循环在延时控制中的作用。


#include "stm32f10x.h"

// 寄存器地址定义
#define GPIOC_CRH    (*(volatile unsigned long *)0x40011004)
#define GPIOC_ODR    (*(volatile unsigned long *)0x4001100C)
#define RCC_APB2ENR  (*(volatile unsigned long *)0x40021018)

// 简单延时函数:循环递减
void delay(unsigned int count)
{
    while(count--)
    {
        // 空循环体,仅消耗CPU周期
    }
}

int main(void)
{
    // 1. 使能GPIOC时钟(APB2总线)
    RCC_APB2ENR |= (1 << 4);   // IOPCEN位置1
    
    // 2. 配置PC13为推挽输出,2MHz
    GPIOC_CRH &= ~(0xF << 20); // 先清除CNF13和MODE13位
    GPIOC_CRH |= (0x1 << 20);  // MODE13=01(输出2MHz),CNF13=00(推挽)
    
    // 3. 主循环:LED交替亮灭
    while(1)
    {
        GPIOC_ODR &= ~(1 << 13);  // PC13输出低电平 → LED点亮
        delay(500000);            // 延时约500ms
        
        GPIOC_ODR |= (1 << 13);   // PC13输出高电平 → LED熄灭
        delay(500000);            // 延时约500ms
    }
}

代码说明

代码首先通过RCC_APB2ENR寄存器使能GPIOC端口时钟,这是使用GPIO前必须完成的步骤。然后配置GPIOC_CRH寄存器,将PC13设置为推挽输出模式。主循环中通过操作GPIOC_ODR寄存器的bit13来控制LED状态:清零该位输出低电平点亮LED,置位该位输出高电平熄灭LED。每次切换后调用delay函数延时,形成闪烁效果。

编译与烧录

使用Keil MDK或arm-none-eabi-gcc工具链编译。若使用arm-none-eabi-gcc,编译命令如下:


arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb led_blink.c -o led_blink.o
arm-none-eabi-ld -T stm32f103.ld led_blink.o -o led_blink.elf
arm-none-eabi-objcopy -O binary led_blink.elf led_blink.bin

其中stm32f103.ld为链接脚本,需根据具体开发板配置Flash和RAM起始地址。烧录时使用ST-Link或J-Link工具将生成的bin文件写入单片机Flash。

验证方法

将程序烧录至开发板后,观察板上LED(PC13)是否以约1秒周期闪烁。若LED正常闪烁,说明寄存器配置和延时函数工作正常。可通过修改delay函数的参数值来改变闪烁频率,例如将参数改为1000000,闪烁周期应变为约2秒,以此验证延时函数对闪烁速度的控制作用。

判定标准

满足以下条件即判定案例通过:

  • LED以稳定周期交替亮灭,周期约1秒(允许因主频差异有±30%偏差);
  • 修改delay参数后闪烁频率随之变化;
  • 代码中所有寄存器地址与STM32F103数据手册一致,无编译错误。