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 必须正确接线,否则流水效果可能不完整。

img


三、软件设计

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);
	}
}

关键点解析

  1. 使用 GPIO_Write(GPIOA, value) 可以一次性设置整个端口的输出值。
  2. 因为 LED 通常采用 低电平点亮(即 PAx = 0 → LED 亮),所以代码中取了反 ~0x0001
  3. 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),流水灯会变得更清晰。


五、总结

本实验主要内容:

  1. 学习了 GPIOA 端口整体输出 的方法
  2. 掌握了 GPIO_Write() 与逐个引脚操作的区别
  3. 实现了 LED 流水灯 的效果,为后续扩展(如跑马灯、动态显示)打下基础
posted @ 2025-08-30 11:40  jeikerxiao  阅读(177)  评论(0)    收藏  举报