2026年7月20日 流水灯及按键控制 📅 发布时间:2026/8/24 14:06:55 👁 浏览次数: 2026年7月20日 流水灯及按键控制文章目录2026年7月20日 流水灯及按键控制LED模块#includeled.huint8_tucLed[4]{0,0,0,0};// LED 状态数组 (4个LED)uint8_tled_mode0;//0-流水灯 1-闪烁uint8_tflow_index0;//0 1 2 3uint32_tflow_tick0;#defineFLOW_TIMER100uint32_tstar_tick0;#defineSTAR_TIMER2000staticint8_tflow_dir1;// 1向右, -1向左uint8_tneed_init0;/** * brief 根据ucLed数组状态更新6个LED的显示 * param ucLed Led数据储存数组 (大小为6) */voidled_disp(uint8_t*ucLed){uint8_ttemp0x00;// 用于记录当前 LED 状态的临时变量staticuint8_ttemp_old0xff;// 记录之前 LED 状态的变量, 用于判断是否需要更新显示for(inti0;i4;i)// 遍历4个LED的状态{// 将LED状态整合到temp变量中方便后续比较if(ucLed[i])temp|(1i);// 如果ucLed[i]为1, 则将temp的第i位置1}// 仅当当前状态与之前状态不同的时候才更新显示if(temp!temp_old){// 使用HAL库函数根据temp的值设置对应引脚状态 (假设高电平点亮)HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,(temp0x01)?GPIO_PIN_RESET:GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,(temp0x02)?GPIO_PIN_RESET:GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,(temp0x04)?GPIO_PIN_RESET:GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,(temp0x08)?GPIO_PIN_RESET:GPIO_PIN_SET);temp_oldtemp;// 更新记录的旧状态}}/** * brief LED 显示处理函数 (主循环调用) */voidled_task(void){uint32_tnowHAL_GetTick();if(led_mode0)//流水灯{if(now-flow_tickFLOW_TIMER){flow_ticknow;for(uint8_ti0;i4;i)// 全部熄灭ucLed[i]0;ucLed[flow_index]1;if(flow_index3)flow_dir-1;// 到最右改为向左if(flow_index0)flow_dir1;// 到最左改为向右flow_indexflow_dir;// 按方向移动}}else//闪烁{if(need_init){for(uint8_ti0;i4;i)ucLed[i]1;// 统一star_ticknow;// 重置计时need_init0;// 标记已经初始化过了}if(now-star_tickSTAR_TIMER){star_ticknow;for(uint8_ti0;i4;i)ucLed[i]^1;// 全亮 ?全灭}}led_disp(ucLed);// 调用led_disp函数更新LED状态}LED实现先顺时针再逆时针组合流水效果之后再循环通过是否到达时间间隔非阻塞式判断确定下一个灯应该被点亮if(now - flow_tick FLOW_TIMER)时间判断到了之后再更新flow_tick通过方向变量以及下标判断流水的方向if(flow_index 3) flow_dir -1; // 到最右改为向左if(flow_index 0) flow_dir 1; // 到最左改为向右按键按下之后模式翻转定义进入闪烁模式的标志位need_init确保一进入闪烁模式之后所有灯的状态一致再同步进行闪烁。if(need_init){for(uint8_ti0;i4;i)ucLed[i]1;// 统一star_ticknow;// 重置计时need_init0;// 标记已经初始化过了}按键模块#includekey.huint8_tkey_val,key_down,key_up,key_old;uint8_tkey_read(){uint8_ttemp0;// 初始化返回值为0 (无按键)if(HAL_GPIO_ReadPin(GPIOA,KEY0_Pin)GPIO_PIN_RESET)temp1;returntemp;// 返回检测到的按键值或0无按键/串口忙。}voidkey_task(void){key_valkey_read();key_downkey_val(key_val^key_old);key_up~key_val(key_val^key_old);key_oldkey_val;if(key_down1){need_init1;led_mode^1;}}按键按下确认进入闪烁模式的标志位need_init置1灯状态统一后置0恢复原状态确认已被使用模式翻转进入闪烁模式。