stm32F103利用定时器实现流水灯
时间: 2025-01-02 15:19:20 浏览: 15
### STM32F103 使用定时器实现流水灯效果
#### 利用定时器和状态机编程方法实现流水灯
为了在STM32F103微控制器上利用定时器实现流水灯效果,可以采用状态机的方式进行编程。这种方式不仅能够清晰地定义不同状态下LED的行为模式,还能有效管理各个状态之间的转换逻辑。
当设备首次通电时,进入初始状态,在此期间仅有一个特定的LED被激活并按照设定的时间间隔快速闪烁三次作为启动提示信号[^2]。之后系统会自动切换到下一个阶段即顺序点亮四个不同的LED形成流动光效;紧接着再进入到反向操作流程——逐个关闭之前亮起过的那些发光二极管来展示另一种形式的动态变化。上述过程循环往复执行下去直到电源切断为止。
下面给出一段基于SysTick定时器的状态机代码示例用于说明如何具体实施这一方案:
```c
#include "stm32f1xx_hal.h"
// 定义 LED 端口及引脚编号
#define LED_PORT GPIOA
#define LED_PIN_1 GPIO_PIN_5
#define LED_PIN_2 GPIO_PIN_6
#define LED_PIN_3 GPIO_PIN_7
#define LED_PIN_4 GPIO_PIN_8
volatile uint8_t state = 0;
volatile uint8_t count;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1){
switch(state){
case 0:// 上电初始化状态
if(count < 6){ // 计数六次完成一次完整的开闭动作
if((count % 2) == 0){
HAL_GPIO_WritePin(LED_PORT, LED_PIN_1, GPIO_PIN_SET);
}else{
HAL_GPIO_WritePin(LED_PORT, LED_PIN_1, GPIO_PIN_RESET);
}
count++;
break;
}else{// 当计数值达到上限后重置计数并向下一状态转移
count = 0;
state = 1;
break;
}
case 1:// 正序点亮所有LED
if(count < 4){
HAL_GPIO_WritePin(LED_PORT, ((uint16_t)(1 << (count + 5))), GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(LED_PORT, ((uint16_t)(1 << (count + 5))), GPIO_PIN_RESET);
count++;
break;
}else{
count = 0;
state = 2;
break;
}
case 2:// 反序熄灭所有LED
if(count < 4){
HAL_GPIO_WritePin(LED_PORT, ((uint16_t)(1 << (8 - count))), GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(LED_PORT, ((uint16_t)(1 << (8 - count))), GPIO_PIN_RESET);
count++;
break;
}else{
count = 0;
state = 1;
break;
}
default:
break;
}
HAL_Delay(1000); // 延迟一秒等待下一轮处理
}
}
void SysTick_Handler(void){
__HAL_SYSTICK_CLEARFLAG(); // 清除标志位防止误触发中断服务函数
}
```
这段代码展示了怎样设置GPIO端口以及编写主循环内的条件判断语句以响应当前所处的不同工作状况。此外还包含了必要的延时调用来模拟实际硬件环境下的时间流逝情况。值得注意的是这里并没有直接使用硬编码的方式来指定具体的I/O资源而是借助宏定义的形式使得整个程序更加灵活易于维护调整。
阅读全文