STM32G431利用定时器完成LED流水灯,按键实现正反流水灯的切换的代码
时间: 2025-02-14 20:20:35 浏览: 106
STM32G431微控制器通常使用定时器配合GPIO控制LED实现流水灯效果,并通过按键触发正反向切换。下面是一个简化版的代码示例,假设我们使用了TIM2定时器和PA0~PA7引脚连接LED,以及PB0按键:
```c
#include "stm32g4xx.h"
// 定义定时器结构体实例和配置
TIM_HandleTypeDef htim2;
TIM_MasterConfigTypeDef sMasterConfig;
// LED GPIO初始化
GPIO_InitTypeDef GPIO_InitStruct;
#define LED_GPIO_PORT GPIOA
#define LED_PIN(i) GPIO_Pin_##i
// 按键GPIO初始化
#define KEY_PIN GPIO_Pin_0
#define KEY_GPIO_PORT GPIOB
void led_init(void) {
GPIO_InitStruct.Pin = LED_GPIO_PORT | LED_PIN(0) | LED_PIN(1) | ... | LED_PIN(7);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
// 初始状态设置为低电平关闭LED
for (uint8_t i = 0; i < 8; i++) {
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN(i), GPIO_PIN_RESET);
}
}
void timer_config(void) {
htim2.Instance = TIM2;
htim2.Init.Prescaler = 8399; // 根据系统频率调整预分频值
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 500; // 设置周期为500us
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim2);
// 配置TIM2为主时钟
sMasterConfig.MasterOutputTrigger = TIM_TRGO.edge;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
}
void led_blink(uint8_t direction) {
static uint8_t led_index = 0;
if (direction == 0) { // 正向
led_index++;
if (led_index >= 8) {
led_index = 0;
}
} else { // 反向
led_index--;
if (led_index < 0) {
led_index = 7;
}
}
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN(led_index), GPIO_PIN_SET); // 开启LED
HAL_Delay(500); // 等待一段时间
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN(led_index), GPIO_PIN_RESET); // 关闭LED
}
void button_callback(uint16_t pin) {
if (pin == KEY_PIN && HAL_GPIO_ReadPin(KEY_GPIO_PORT) == GPIO_PIN_SET) {
static uint8_t direction = 0; // 初始化方向为正向
direction ^= 1; // 切换开关方向
led_blink(direction); // 调用函数改变LED流动方向
}
}
int main(void) {
led_init();
timer_config();
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); // 设置定时器中断优先级
HAL_NVIC_EnableIRQ(TIM2_IRQn);
HAL_GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);
EXTI_InitTypeDef extiConfig;
extiConfig.EXTI_Line = KEY_LINE; // 替换为你按键对应的EXTI线
extiConfig.EXTI_Mode = EXTI_MODE_IT_FALLING;
extiConfig.EXTI_Trigger = EXTI_TRIGGER_RISING;
extiConfig.EXTI_LineCmd = ENABLE;
HAL_EXTI_Init(&extiConfig);
while (1) {
HAL_GPIO_TogglePin(KEY_GPIO_PORT, KEY_PIN); // 模拟按键按下
HAL_GPIO_EXTI_IRQHandler(extiConfig.EXTI_Line); // 处理按键中断
}
}
// 相关问题--
1. 如果想要更改LED流水灯的速度,如何修改定时器配置?
2. 如何处理按键抖动问题以确保正确的按钮操作?
3. 这段代码是否适用于所有STM32G431型号?如果不是,需要哪些额外步骤或配置更改?
```
阅读全文
相关推荐
















