基于STM32的交通灯系统故障求助:黄灯全亮且无法控制
STM32交通灯控制系统故障排查与修复
问题分析
你遇到的4个黄灯全亮且无法切换的问题,根源在于以下代码逻辑错误:
- 按键状态未实时更新:
direct和rst的GPIO读取放在while循环外部,程序启动后仅读取一次按键状态,后续操作无法被检测 - 状态机逻辑混乱:在状态分支中直接修改
pre_state,破坏了状态流转规则,导致异常跳转 - 无延时控制:倒计时变量在高速循环中瞬间递减至0,完全达不到3秒延时需求
- 默认分支误触发:未预期状态会进入默认分支,同时点亮两个黄灯
修正后的代码
// 定义状态枚举,增强代码可读性 typedef enum { STATE_GR, // 南北绿、东西红 STATE_YR, // 南北黄、东西红 STATE_RR1, // 南北红、东西红(等待东西绿灯) STATE_RG, // 南北红、东西绿 STATE_RY, // 南北红、东西黄 STATE_RR2 // 南北红、东西红(等待南北绿灯) } TrafficLightState; uint8_t i, j; TrafficLightState current_state = STATE_GR; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1){ // 实时读取按键状态 uint8_t direct = HAL_GPIO_ReadPin(direct_GPIO_Port, direct_Pin); uint8_t rst = HAL_GPIO_ReadPin(rst_GPIO_Port, rst_Pin); // 复位处理 if (rst == 1) { current_state = STATE_GR; i = 0; j = 0; } else { // 状态机流转逻辑 switch (current_state) { case STATE_GR: if (direct == 1) { // switch1闭合,切换到南北黄灯 current_state = STATE_YR; i = 3; } break; case STATE_YR: if (i > 0) { HAL_Delay(1000); // 1秒延时 i--; } else { current_state = STATE_RR1; j = 3; } break; case STATE_RR1: if (j > 0) { HAL_Delay(1000); j--; } else { current_state = STATE_RG; } break; case STATE_RG: if (direct == 0) { // switch1断开,切换到东西黄灯 current_state = STATE_RY; j = 3; } break; case STATE_RY: if (j > 0) { HAL_Delay(1000); j--; } else { current_state = STATE_RR2; i = 3; } break; case STATE_RR2: if (i > 0) { HAL_Delay(1000); i--; } else { current_state = STATE_GR; } break; default: current_state = STATE_GR; break; } } // 灯光输出逻辑 switch (current_state) { case STATE_GR: HAL_GPIO_WritePin(R1_GPIO_Port, R1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(G1_GPIO_Port, G1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(Y1_GPIO_Port, Y1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(R2_GPIO_Port, R2_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(G2_GPIO_Port, G2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y2_GPIO_Port, Y2_Pin, GPIO_PIN_RESET); break; case STATE_YR: HAL_GPIO_WritePin(R1_GPIO_Port, R1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(G1_GPIO_Port, G1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y1_GPIO_Port, Y1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(R2_GPIO_Port, R2_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(G2_GPIO_Port, G2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y2_GPIO_Port, Y2_Pin, GPIO_PIN_RESET); break; case STATE_RR1: case STATE_RR2: HAL_GPIO_WritePin(R1_GPIO_Port, R1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(G1_GPIO_Port, G1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y1_GPIO_Port, Y1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(R2_GPIO_Port, R2_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(G2_GPIO_Port, G2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y2_GPIO_Port, Y2_Pin, GPIO_PIN_RESET); break; case STATE_RG: HAL_GPIO_WritePin(R1_GPIO_Port, R1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(G1_GPIO_Port, G1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y1_GPIO_Port, Y1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(R2_GPIO_Port, R2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(G2_GPIO_Port, G2_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(Y2_GPIO_Port, Y2_Pin, GPIO_PIN_RESET); break; case STATE_RY: HAL_GPIO_WritePin(R1_GPIO_Port, R1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(G1_GPIO_Port, G1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y1_GPIO_Port, Y1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(R2_GPIO_Port, R2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(G2_GPIO_Port, G2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y2_GPIO_Port, Y2_Pin, GPIO_PIN_SET); break; default: // 异常状态关闭所有灯 HAL_GPIO_WritePin(R1_GPIO_Port, R1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(G1_GPIO_Port, G1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y1_GPIO_Port, Y1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(R2_GPIO_Port, R2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(G2_GPIO_Port, G2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Y2_GPIO_Port, Y2_Pin, GPIO_PIN_RESET); break; } } /* USER CODE END 3 */ }
关键修改说明
- 实时按键读取:将GPIO读取移至循环内部,确保每次循环获取最新按键状态
- 状态机优化:用枚举定义状态,移除分支中对状态变量的直接修改,仅通过赋值控制流转
- 添加延时:使用
HAL_Delay(1000)实现1秒延时,满足3秒倒计时需求 - 合并冗余逻辑:合并双红状态的灯光输出,减少重复代码
- 异常处理:默认分支添加异常状态复位,避免误触发双黄灯
内容的提问来源于stack exchange,提问作者Huy Nguyễn Đĩnh
相关产品推荐
相关产品推荐

