STM32 NUCLEO-L432KC:仅用GPIO实现LED调光及按键控制技术问询
STM32 NUCLEO-L432KC 纯GPIO实现LED调光与按键控制
核心实现思路
由于你仅使用GPIO和基础C指令,只能通过**软件PWM(脉冲宽度调制)**实现调光:利用人眼视觉暂留特性,在固定周期内控制LED亮、暗的时间比例(占空比),不同占空比对应不同亮度:
- 100%亮度:LED持续点亮
- 50%亮度:每个周期内亮暗时间各占一半
- 10%亮度:每个周期内亮10%时间、暗90%时间
按键逻辑需区分两种操作:
- 短按:逐级切换亮度(上电默认100%,依次降低为50%→10%→100%循环)
- 长按3秒:触发LED全局开关(直接切换开/关状态,优先级高于亮度调节)
完整代码实现
/* USER CODE BEGIN PV */ // 亮度等级枚举定义 typedef enum { BRIGHTNESS_100 = 0, BRIGHTNESS_50, BRIGHTNESS_10, BRIGHTNESS_MAX } BrightnessLevel; // 全局变量 uint8_t button_state = 0; // 按键当前状态(低电平有效) uint32_t press_start_time = 0; // 按键按下起始时间戳 uint8_t led_global_on = 1; // LED全局开关:1=开启 0=关闭 BrightnessLevel current_level = BRIGHTNESS_100; // 默认100%亮度 const uint16_t pwm_cycle = 10; // PWM周期(单位:ms),10ms可避免视觉闪烁 /* USER CODE END PV */ while(1) { // 读取按键引脚状态 button_state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3); if(!button_state) { // 检测到按键按下 press_start_time = HAL_GetTick(); // 记录按下时间 // 等待按键释放或长按超时 while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3)) { if(HAL_GetTick() - press_start_time >= 3000) { // 长按满3秒 led_global_on = !led_global_on; // 切换全局开关 // 等待按键释放,防止重复触发 while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3)); break; } } // 判断为短按(按下时长<3秒)且LED处于开启状态 if(HAL_GetTick() - press_start_time < 3000 && led_global_on) { // 亮度逐级降低,循环切换 current_level = (current_level + 1) % BRIGHTNESS_MAX; HAL_Delay(200); // 短按消抖延迟 } } // LED亮度输出逻辑 if(led_global_on) { switch(current_level) { case BRIGHTNESS_100: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); break; case BRIGHTNESS_50: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); HAL_Delay(pwm_cycle / 2); // 亮5ms HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); HAL_Delay(pwm_cycle / 2); // 暗5ms break; case BRIGHTNESS_10: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); HAL_Delay(pwm_cycle * 0.1); // 亮1ms HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); HAL_Delay(pwm_cycle * 0.9); // 暗9ms break; default: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); break; } } else { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); // 全局关闭时LED熄灭 } }
代码说明
- 亮度控制:通过
pwm_cycle定义周期,不同亮度等级对应不同的亮暗时间比例,10ms周期可保证视觉无闪烁 - 按键处理:用
HAL_GetTick()获取系统时间戳,精准区分短按/长按,加入消抖延迟避免机械按键误触发 - 全局开关:长按3秒后切换
led_global_on状态,优先级高于亮度调节,关闭时直接熄灭LED
内容的提问来源于stack exchange,提问作者Yuta Watanabe
相关产品推荐
相关产品推荐

