1. GPIO输出控制LED闪烁

GPIO输出控制LED闪烁 学习卡片

任务说明

本案例要求在ARM嵌入式开发板上,通过配置GPIO输出寄存器,控制板载LED以1Hz频率闪烁(即每500ms翻转一次电平)。你需要完成从寄存器配置到延时控制的完整代码编写,并能在开发板上观察到LED的亮灭变化。

硬件连接与寄存器映射

以STM32F407开发板为例,板载LED通常连接在GPIOF的Pin9(或根据实际板卡调整)。本案例使用GPIOF端口,输出引脚为Pin9,低电平点亮LED。系统时钟配置为168MHz,APB2外设时钟为84MHz。

时钟配置 HSE 8MHz PLL ×21 → 168MHz AHB → 168MHz APB2 → 84MHz GPIOF 端口配置 RCC->AHB1ENR Bit5 = 1 (使能GPIOF时钟) GPIOF->MODER Bits[19:18] = 01 (PF9输出) GPIOF->ODR Bit9 = 0 → LED亮 Bit9 = 1 → LED灭 GPIOF->BSRR PF9 → LED阳极 LED阴极 → 串联电阻 → GND 低电平点亮 1Hz = 500ms亮 + 500ms灭

代码实现

以下代码直接操作寄存器完成GPIO配置与LED闪烁控制,不依赖HAL库。延时函数使用简单的循环计数实现,系统时钟168MHz下,内层循环约耗时1μs。

// main.c
#include "stm32f4xx.h"

// 简单延时函数:约延时 ms 毫秒(168MHz主频)
void delay_ms(uint32_t ms) {
    uint32_t i, j;
    for (i = 0; i < ms; i++) {
        // 约168次循环 ≈ 1μs,168000次 ≈ 1ms
        for (j = 0; j < 168000; j++) {
            __NOP();
        }
    }
}

void GPIO_Init(void) {
    // 1. 使能GPIOF时钟(AHB1总线)
    RCC->AHB1ENR |= (1U << 5);   // Bit5: GPIOFEN

    // 2. 配置PF9为输出模式
    GPIOF->MODER &= ~(3U << 18); // 先清零Bits[19:18]
    GPIOF->MODER |= (1U << 18);  // 设置为01:通用输出模式

    // 3. 设置输出类型为推挽(默认即可,此处显式配置)
    GPIOF->OTYPER &= ~(1U << 9); // Bit9=0:推挽输出

    // 4. 设置输出速度(可选,默认即可)
    GPIOF->OSPEEDR &= ~(3U << 18);
    GPIOF->OSPEEDR |= (2U << 18); // 50MHz速度

    // 5. 无上下拉
    GPIOF->PUPDR &= ~(3U << 18);
}

int main(void) {
    GPIO_Init();

    while (1) {
        // 点亮LED:PF9输出低电平
        GPIOF->BSRR = (1U << (9 + 16)); // BR9=1,复位Pin9
        delay_ms(500);

        // 熄灭LED:PF9输出高电平
        GPIOF->BSRR = (1U << 9);        // BS9=1,置位Pin9
        delay_ms(500);
    }
}

代码说明

代码首先通过RCC->AHB1ENR的Bit5使能GPIOF端口时钟。然后配置GPIOF->MODER寄存器,将Pin9对应的模式位(Bits[19:18])设置为01,即通用输出模式。在main函数的循环中,通过GPIOF->BSRR寄存器操作Pin9:向BR9写入1使引脚输出低电平(LED点亮),向BS9写入1使引脚输出高电平(LED熄灭)。每次状态切换后调用delay_ms(500)延时500ms,从而实现1Hz的闪烁频率。

编译与烧录

使用ARM Compiler或GCC工具链编译,生成HEX文件后通过ST-Link烧录到开发板。以Keil MDK为例:

// 工程配置要点
1. Device: STM32F407VG
2. 在Options for Target → C/C++ → Define 中添加 USE_STDPERIPH_DRIVER
3. 选择 "Use MicroLIB" 以减小代码体积
4. 编译后点击 LOAD 烧录程序

验证方法

烧录程序后,观察开发板上的LED(PF9连接)是否以1Hz频率闪烁。使用秒表计时10秒,LED应完成约10次完整亮灭循环(允许±1次误差)。若LED常亮或常灭,检查GPIOF时钟使能位是否正确、MODER寄存器配置是否冲突,以及BSRR操作位是否对应Pin9。

判定标准:LED以稳定周期闪烁,亮灭时间各约500ms,且通过示波器测量PF9引脚波形时,高电平持续约500ms,低电平持续约500ms,频率约为1Hz。