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

AVR交通灯系统中断按键与LED工作异常 运行时4颗LED全亮

问题排查与修复方案

核心错误点

  • 全局状态变量state未显式初始化,默认值为枚举第一个值EW,无法进入启动初始化逻辑
  • 主循环无计时等待逻辑,会无限高速执行端口切换,LED高频闪烁人眼识别为常亮
  • 定时器中断逻辑不满足计时需求,没有区分正常模式和行人模式的不同计时阈值
  • 行人模式触发逻辑不符合需求,没有等待当前通行阶段走完再切换
  • 未引入<stdbool.h>头文件,boolean类型编译会报错

修复后完整代码

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>

volatile uint8_t second = 0;
volatile bool buttonPressed = false;

enum light_state {EW, SN, PES_FIRST, PES_SECOND, START_UP};
enum light_state state = START_UP;

int main(void) {
  DDRB = 0xFF; // 所有PB引脚设为输出
  PORTB = 0x00; // 初始所有LED熄灭

  DDRD &= ~(1 << 2); // PD2设为输入
  PORTD |= (1 << PORTD2); // 启用上拉电阻

  // 外部中断0配置,下降沿触发
  EIMSK |= (1 << INT0);
  EICRA |= (1 << ISC01);
  EIFR |= (1 << INTF0);

  // 定时器1配置,CTC模式,1024预分频,1秒触发一次中断
  TCCR1B |= (1 << WGM12) | (1 << CS12) | (1 << CS10);
  OCR1A = 15624; // 16MHz/1024 -1 = 15624,对应1秒
  TIMSK1 |= (1 << OCIE1A);

  sei();
  while (1) {
    switch(state) {
      case START_UP:
        PORTB = 0x00;
        second = 0;
        state = SN; // 初始进入SN阶段:LED1+LED4亮
        break;
      
      case SN: // SN阶段:LED1(PB1)、LED4(PB4)亮4秒
        PORTB = (1 << PB1) | (1 << PB4);
        if(second >=4) {
          second = 0;
          if(buttonPressed) {
            state = PES_FIRST; // 有按键,进入行人模式第一阶段
            buttonPressed = false;
          } else {
            state = EW; // 无按键,进入EW阶段
          }
        }
        break;
      
      case EW: // EW阶段:LED2(PB2)、LED3(PB3)亮4秒
        PORTB = (1 << PB2) | (1 << PB3);
        if(second >=4) {
          second = 0;
          state = SN;
        }
        break;
      
      case PES_FIRST: // 行人模式第一阶段:LED2+LED5亮2秒
        PORTB = (1 << PB2) | (1 << PB5);
        if(second >=2) {
          second = 0;
          state = PES_SECOND;
        }
        break;
      
      case PES_SECOND: // 行人模式第二阶段:LED2+LED3亮2秒
        PORTB = (1 << PB2) | (1 << PB3);
        if(second >=2) {
          second = 0;
          state = SN;
        }
        break;
      
      default:
        state = START_UP;
        break;
    }
  }
}

// 按键中断
ISR(INT0_vect) {
  buttonPressed = true;
}

// 定时器中断,1秒触发一次
ISR(TIMER1_COMPA_vect) {
  second++;
}

修复说明

  1. 新增了行人模式的两个状态PES_FIRST和PES_SECOND,分别对应LED5亮2秒、LED3亮2秒的阶段,LED2全程保持点亮
  2. 主循环增加计时判断,只有计时到对应阈值才切换状态,避免端口高速翻转
  3. 状态初始化显式指定为START_UP,启动时所有LED熄灭
  4. 增加<stdbool.h>头文件引入,解决bool类型编译问题
  5. 行人模式触发逻辑只有在SN阶段结束后才会进入,符合“等待LED1、LED4熄灭后再工作”的需求

内容的提问来源于stack exchange,提问作者Trần Thiên

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:36:00