STM32F103(标准库)LED 流水灯
STM32F103(标准库)LED 流水灯实验
在前一篇文章中,我们实现了 STM32F103 点亮一个 LED 并闪烁。本篇我们继续进阶,利用 GPIOA 的多个引脚,实现 LED 流水灯效果。
一、实验目标
- 使用 STM32F103 标准外设库,配置 GPIOA 所有引脚为输出模式
- 通过软件延时控制多个 LED 依次点亮,实现流水灯效果
- 熟悉
GPIO_Write()函数的用法,掌握端口整体输出的方式
二、硬件准备
- STM32F103 最小系统板
- 8 个 LED(或开发板自带 LED 扩展模块)
- 下载器(ST-LINK/J-Link)
接线方式:
- PA0 ~ PA7 → 8 个 LED → 电阻 → GND
⚠️ 注意:这里使用 GPIO_Write() 输出时,需要一次性操作整个端口,因此 PA0~PA7 对应的 LED 必须正确接线,否则流水效果可能不完整。

三、软件设计
1. 主函数代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
// 1. 开启 GPIOA 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 2. 配置 GPIOA 所有引脚为推挽输出
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; // 全部引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化 GPIOA
// 3. 循环控制流水灯
while (1)
{
// 1号灯亮(PA0)
GPIO_Write(GPIOA, ~0x0001); // 0000 0000 0000 0001
Delay_ms(100);
// 2号灯亮(PA1)
GPIO_Write(GPIOA, ~0x0002); // 0000 0000 0000 0010
Delay_ms(100);
// 3号灯亮(PA2)
GPIO_Write(GPIOA, ~0x0004); // 0000 0000 0000 0100
Delay_ms(100);
// 4号灯亮(PA3)
GPIO_Write(GPIOA, ~0x0008); // 0000 0000 0000 1000
Delay_ms(100);
// 5号灯亮(PA4)
GPIO_Write(GPIOA, ~0x0010); // 0000 0000 0001 0000
Delay_ms(100);
// 6号灯亮(PA5)
GPIO_Write(GPIOA, ~0x0020); // 0000 0000 0010 0000
Delay_ms(100);
// 7号灯亮(PA6)
GPIO_Write(GPIOA, ~0x0040); // 0000 0000 0100 0000
Delay_ms(100);
// 8号灯亮(PA7)
GPIO_Write(GPIOA, ~0x0080); // 0000 0000 1000 0000
Delay_ms(100);
}
}
关键点解析:
- 使用
GPIO_Write(GPIOA, value)可以一次性设置整个端口的输出值。 - 因为 LED 通常采用 低电平点亮(即 PAx = 0 → LED 亮),所以代码中取了反
~0x0001。 0x0001表示 PA0 置低,其他位高;同理0x0002表示 PA1 置低。
2. 延时函数
Delay.h
#ifndef __DELAY_H
#define __DELAY_H
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);
#endif
Delay.c
#include "stm32f10x.h"
/**
* @brief 微秒级延时
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; // 设置重装值
SysTick->VAL = 0x00; // 清空计数器
SysTick->CTRL = 0x00000005; // 选择时钟源,启动定时器
while(!(SysTick->CTRL & 0x00010000)); // 等待计数到 0
SysTick->CTRL = 0x00000004; // 关闭定时器
}
/**
* @brief 毫秒级延时
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief 秒级延时
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
这里延时函数与上篇文章一致,利用 SysTick 实现微秒/毫秒/秒级延时。
四、运行效果
下载程序后,PA0~PA7 依次输出低电平,每个 LED 依次点亮,形成 流水灯效果。
如果你把延时改长一些(比如 500ms),流水灯会变得更清晰。
五、总结
本实验主要内容:
- 学习了 GPIOA 端口整体输出 的方法
- 掌握了
GPIO_Write()与逐个引脚操作的区别 - 实现了 LED 流水灯 的效果,为后续扩展(如跑马灯、动态显示)打下基础

浙公网安备 33010602011771号