You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:10:55