# STM32F10x PA0~PA7八路流水灯程序说明文档 ## 一、文档概述 本文档针对基于寄存器开发的STM32F10系列8路流水灯工程进行完整说明硬件使用PA0~PA7共8个GPIO引脚驱动LED程序采用标准库底层寄存器直接操作搭配SysTick精准延时实现单灯依次循环流水效果。 ## 二、硬件资源说明 1. **主控芯片**STM32F10x如F103C8T6 2. **外设引脚**GPIOA端口 PA0、PA1、PA2、PA3、PA4、PA5、PA6、PA7 3. **LED驱动逻辑**共阳极接法 - LED正极接3.3V电源负极串联限流电阻后接STM32 PA引脚 - 引脚输出**低电平** → LED点亮引脚输出**高电平** → LED熄灭 4. **系统时钟**内核主频72MHzSysTick定时器基于系统时钟做us/ms/s多级延时 ## 三、程序整体功能 上电初始化完成后8颗LED按照 PA0→PA1→PA2→PA3→PA4→PA5→PA6→PA7 顺序依次点亮每颗灯保持500ms后熄灭全部走完一轮后无限循环流水。 ## 四、代码模块分块解析 ### 1. 头文件与函数声明 c #include stm32f10x.h void Delay_us(uint16_t us); void Delay_ms(uint16_t ms); void Delay_s(uint16_t s); - stm32f10x.h芯片底层寄存器、位掩码宏定义头文件提供RCC、GPIO、SysTick寄存器地址与位定义 - 三个延时函数声明分别支持微秒、毫秒、秒级延时供主逻辑调用 ### 2. main主函数程序入口 #### 1GPIOA时钟使能 c RCC-APB2ENR | RCC_APB2ENR_IOPAEN; RCC为复位时钟控制外设APB2总线挂载GPIOA/GPIOB/GPIOC等端口该语句打开GPIOA外设时钟不开启时钟则GPIO无输出功能。 #### 2PA0~PA7模式配置CRL寄存器 c GPIOA-CRL 0x33333333; - GPIOA-CRL端口配置低寄存器每4位控制1个引脚PA0~PA7 - 4位配置格式CNF[1:0] MODE[1:0] - 数值0x3 00 11CNF00通用推挽输出MODE11最大速度50MHz - 一次性将PA0~PA7全部配置为50MHz推挽输出模式 #### 3初始电平配置全部LED熄灭 c GPIOA-ODR | (GPIO_ODR_ODR0 | GPIO_ODR_ODR1 ... | (1 7)); ODR为端口输出数据寄存器置1对应引脚输出高电平上电默认全部引脚拉高所有LED初始关闭。 #### 4主循环流水逻辑 c while(1) { // 单灯操作模板 GPIOA-ODR ~(1 n); // 对应引脚置0点亮LED Delay_ms(500); // 保持500ms GPIOA-ODR | (1 n); // 对应引脚置1熄灭LED } 依次遍历PA0~PA7逐个点亮延时、熄灭一轮结束自动重复循环。 ### 3. SysTick精准延时函数 #### 1微秒延时 Delay_us c void Delay_us(uint16_t us) { SysTick-LOAD 72 * us; SysTick-CTRL | 0x05; while ((SysTick-CTRL SysTick_CTRL_COUNTFLAG) 0); SysTick-CTRL ~SysTick_CTRL_ENABLE; } - 72MHz主频SysTick每1个时钟周期 1/72 μs装载值72*us实现对应微秒计数 - CTRL0x05使用内核时钟、关闭中断、开启定时器 - 循环等待COUNTFLAG计数完成标志位计时结束关闭定时器 #### 2毫秒延时 Delay_ms c void Delay_ms(uint16_t ms) { while (ms--) { Delay_us(1000); } } 循环调用1000次微秒延时1000μs 1ms实现毫秒级延时。 #### 3秒级延时 Delay_s c void Delay_s(uint16_t s) { while (s--) { Delay_ms(1000); } } 循环调用1000次毫秒延时1000ms 1s备用扩展延时函数。 ## 五、寄存器操作关键点说明 1. **CRL与CRH区分** PA0~PA7由CRL控制PA8~PA15由CRH控制本程序仅使用PA0~PA7仅操作CRL。 2. **ODR寄存器位操作** - GPIOA-ODR ~(1 n)清除第n位引脚输出低电平 - GPIOA-ODR | (1 n)置位第n位引脚输出高电平 3. **位掩码宏与移位写法** 低引脚PA0~PA6使用标准库宏GPIO_ODR_ODRxPA7采用移位1 7两种写法功能完全等价。 ## 六、运行效果描述 1. 上电瞬间8颗LED全部熄灭 2. 流水顺序LED0(PA0)亮500ms → 熄灭 → LED1(PA1)亮500ms → 熄灭 …… 直至LED7(PA7) 3. LED7熄灭后立刻重新从LED0开始无限循环往复 4. 单灯点亮间隔固定500ms延时精度由SysTick硬件定时器保证无软件空循环误差 ## 七、注意事项与故障排查 ### 1. 硬件问题 - LED不亮检查限流电阻、正负极是否接反、PA引脚接线是否松动 - 全部常亮引脚初始化未拉高或硬件接成共阴极 ### 2. 软件问题 - 流水无延时/速度过快系统时钟未配置为72MHzSysTick装载值不匹配 - 单个LED无反应确认引脚编号、CRL寄存器配置是否正确 - 程序无输出忘记开启RCC_APB2ENR_IOPAEN时钟使能 ## 八、扩展修改建议 1. 调整流水速度修改Delay_ms(500)内数值数值越大流水越慢 2. 增加PA8扩展至9路LED新增CRH寄存器配置循环增加i8逻辑 3. 简化流水代码使用for循环替代重复点灯代码精简main函数 c uint8_t i; for(i0;i8;i) { GPIOA-ODR ~(1i); Delay_ms(500); GPIOA-ODR | (1i); } 4. 双向流水一轮正向走完后增加反向PA7~PA0流水逻辑#include stm32f10x.h void Delay_us(uint16_t us); void Delay_ms(uint16_t ms); void Delay_s(uint16_t s); int main(void) { // 1. 开启GPIOA外设时钟 RCC-APB2ENR | RCC_APB2ENR_IOPAEN; // 2. 配置 PA0~PA7 全部为通用推挽输出 50MHzCRL寄存器 GPIOA-CRL 0x33333333; // 4. 所有引脚默认输出高电平全部关灯 GPIOA-ODR | (GPIO_ODR_ODR0 | GPIO_ODR_ODR1 | GPIO_ODR_ODR2 | GPIO_ODR_ODR3 | GPIO_ODR_ODR4 | GPIO_ODR_ODR5 | GPIO_ODR_ODR6 | GPIO_ODR_ODR7 | (1 7)); // 5. 无限循环流水灯 while(1) { // PA0 GPIOA-ODR ~(1 0); Delay_ms(500); GPIOA-ODR | (1 0); // PA1 GPIOA-ODR ~(1 1); Delay_ms(500); GPIOA-ODR | (1 1); // PA2 GPIOA-ODR ~(1 2); Delay_ms(500); GPIOA-ODR | (1 2); // PA3 GPIOA-ODR ~(1 3); Delay_ms(500); GPIOA-ODR | (1 3); // PA4 GPIOA-ODR ~(1 4); Delay_ms(500); GPIOA-ODR | (1 4); // PA5 GPIOA-ODR ~(1 5); Delay_ms(500); GPIOA-ODR | (1 5); // PA6 GPIOA-ODR ~(1 6); Delay_ms(500); GPIOA-ODR | (1 6); // PA7 GPIOA-ODR ~(1 7); Delay_ms(500); GPIOA-ODR | (1 7); } } // 72MHz系统时钟 微秒级延时 void Delay_us(uint16_t us) { SysTick-LOAD 72 * us; SysTick-CTRL | 0x05; while ((SysTick-CTRL SysTick_CTRL_COUNTFLAG) 0); SysTick-CTRL ~SysTick_CTRL_ENABLE; } void Delay_ms(uint16_t ms) { while (ms--) { Delay_us(1000); } } void Delay_s(uint16_t s) { while (s--) { Delay_ms(1000); } }