芯片:STM32F103C8T6
功能:GPIOA、GPIOB、GPIOC 三端口,4 个 LED(3 个外接 LED+PC13 板载 LED)轮流流水,间隔 1s,寄存器直接编程
一、实验目的
熟悉 STM32 GPIO 寄存器工作原理,掌握寄存器配置 GPIO 推挽输出。
学会搭建 LED 外围电路,实现多 LED 流水点亮。
掌握 RCC 外设时钟使能方法,将板载 PC13 LED 加入流水序列。
二、实验器材
STM32F103C8T6 最小系统、ST-LINK 下载器、面包板、LED×3、220Ω 电阻 ×3、杜邦线、Keil MDK、PC
三、实验原理
引脚分配
表格
引脚 端口 说明
PA0 GPIOA 外接 LED1
PB0 GPIOB 外接 LED2
PB1 GPIOB 外接 LED3
PC13 GPIOC 板载 LED,无需接线
逻辑:引脚低电平点亮 LED,高电平熄灭。
核心寄存器
表格
寄存器 地址 功能
RCC_APB2ENR 0x40021018 开启 GPIOA/GPIOB/GPIOC 时钟
GPIOA_CRL 0x40010800 配置 PA0
GPIOB_CRL 0x40010C00 配置 PB0、PB1
GPIOC_CRH 0x40011004 配置 PC13
GPIOA_ODR 0x4001080C A 口输出电平控制
GPIOB_ODR 0x40010C0C B 口输出电平控制
GPIOC_ODR 0x4001100C C 口输出电平控制
推挽输出参数0x3:50MHz 推挽输出。软件两层 for 循环实现粗略毫秒延时。
四、硬件接线
PA0 → LED 正极 →220Ω 电阻 →GND
PB0 → LED 正极 →220Ω 电阻 →GND
PB1 → LED 正极 →220Ω 电阻 →GND
PC13 板载 LED 无需接线
ST-LINK 连接 SWDIO、SWCLK、3.3V、GND 用于烧录
五、程序设计思路
开启 GPIOA、GPIOB、GPIOC 外设时钟。
配置 PA0、PB0、PB1、PC13 为推挽输出。
初始化全部 LED 熄灭。
循环依次单独点亮一个 LED,其余熄灭,每次延时 1s,循环流水。
六、源代码
c
//寄存器地址宏定义
#define RCC_APB2ENR (*(volatile unsigned int)0x40021018)
#define GPIOA_CRL ((volatile unsigned int)0x40010800)
#define GPIOB_CRL ((volatile unsigned int)0x40010C00)
#define GPIOC_CRH ((volatile unsigned int *)0x40011004)
#define GPIOA_ODR (*(volatile unsigned int)0x4001080C)
#define GPIOB_ODR ((volatile unsigned int)0x40010C0C)
#define GPIOC_ODR ((volatile unsigned int *)0x4001100C)
/**
- @brief 软件毫秒延时
*/
void Delay_ms(unsigned int t)
{
unsigned int i,j;
for(i = t; i > 0; i–)
for(j = 7200; j > 0; j–);
}
int main(void)
{
//开启GPIOA、GPIOB、GPIOC时钟
RCC_APB2ENR |= (1<<2) | (1<<3) | (1<<4);
//PA0推挽输出 GPIOA_CRL &= ~(0xF << 0); GPIOA_CRL |= (0x3 << 0); //PB0推挽输出 GPIOB_CRL &= ~(0xF << 0); GPIOB_CRL |= (0x3 << 0); //PB1推挽输出 GPIOB_CRL &= ~(0xF << 4); GPIOB_CRL |= (0x3 << 4); //PC13推挽输出 GPIOC_CRH &= ~(0xF << 20); GPIOC_CRH |= (0x3 << 20); //全部LED熄灭 GPIOA_ODR |= (1 << 0); GPIOB_ODR |= (1 << 0) | (1 << 1); GPIOC_ODR |= (1 << 13); while(1) { //PA0亮1s GPIOA_ODR &= ~(1 << 0); GPIOB_ODR |= (1 << 0) | (1 << 1); GPIOC_ODR |= (1 << 13); Delay_ms(1000); //PB0亮1s GPIOA_ODR |= (1 << 0); GPIOB_ODR &= ~(1 << 0); GPIOB_ODR |= (1 << 1); GPIOC_ODR |= (1 << 13); Delay_ms(1000); //PB1亮1s GPIOA_ODR |= (1 << 0); GPIOB_ODR |= (1 << 0); GPIOB_ODR &= ~(1 << 1); GPIOC_ODR |= (1 << 13); Delay_ms(1000); //PC13亮1s GPIOA_ODR |= (1 << 0); GPIOB_ODR |= (1 << 0) | (1 << 1); GPIOC_ODR &= ~(1 << 13); Delay_ms(1000); }}
七、实验步骤
在面包板搭建 LED 电路,接好 PA0、PB0、PB1 三路 LED。
ST-LINK 连接开发板与电脑。
Keil 新建工程,芯片选择 STM32F103C8T6,粘贴代码并编译。
配置 ST-LINK 下载器,烧录程序。
上电,观察 LED 流水效果。
八、实验现象
上电后,LED 按 PA0 → PB0 → PB1 → PC13 顺序依次单独点亮,其余熄灭,每个灯点亮 1 秒,循环流水。
九、问题分析
软件延时精度有限,受编译器和系统时钟影响,初始闪烁过快,修改内层循环计数至 7200 后延时接近 1s。
GPIO 必须开启对应 RCC 时钟,否则引脚无法输出电平。
220Ω 限流电阻保护 LED,防止过流烧毁。
十、实验总结
本次实验直接操作寄存器配置 GPIO,成功使用 GPIOA/GPIOB/GPIOC 三个端口实现 4 个 LED 流水灯,切换间隔 1s。掌握了底层寄存器配置、时钟使能,理解 GPIO 推挽输出原理,完成实验任务。