Arduino乒乓游戏Timer中断不工作 秒数始终显示0问题求助
问题根因排查
1. 中断计数逻辑错误
你当前使用的是Timer1的溢出中断,结合主流Arduino Uno的硬件特性:
- 主控ATmega328P主频为16MHz,你设置了256预分频,Timer1的计数频率为
16000000 / 256 = 62500 Hz - 16位定时器的最大计数值为65535,每计满65536个时钟周期才会触发1次溢出中断,两次溢出中断的间隔约为1.048秒
- 你在ISR中是每触发1次溢出中断才给
counter加1,要等counter累加到62500才会让seconds加1,换算下来需要近18小时才会出现seconds不为0的情况,所以你看到的输出始终是0。
2. 缺少串口初始化
你在loop中直接调用Serial.print(),但setup()里没有添加Serial.begin(波特率)的初始化代码,串口输出本身也会异常,也是输出异常的原因之一。
修复方案
建议改用CTC比较匹配中断实现,计时精度更高,更符合你的60秒计时需求,参考代码如下:
volatile uint16_t seconds = 0; // 计时启停控制变量,游戏回合开始时设为true,结束/超时时设为false volatile bool timer_running = false; // 超时标记,中断里触发超时后可以在主循环判断处理 volatile bool time_out = false; void setup() { Serial.begin(115200); // 初始化串口,波特率要和串口监视器配置一致 noInterrupts(); TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; // 16MHz主频+256预分频下,1秒对应62500个计数,从0开始计数所以要减1 OCR1A = 62499; TCCR1B |= (1 << WGM12); // 开启CTC模式 TCCR1B |= (1 << CS12); // 配置256预分频 TIMSK1 |= (1 << OCIE1A); // 开启比较匹配A中断 interrupts(); } // 比较匹配中断服务函数,每秒触发1次 ISR(TIMER1_COMPA_vect) { if(!timer_running) return; seconds++; if(seconds >= 60) { timer_running = false; time_out = true; } } void loop() { // 读取中断修改的变量时建议关中断,避免8位机读16位变量时被中断打断出现数值错误 noInterrupts(); uint16_t current_sec = seconds; bool current_timeout = time_out; interrupts(); Serial.println(current_sec); if(current_timeout) { // 这里添加60秒超时的处理逻辑 } game = update(); lcd.clear(); render(); }
注意事项
- 游戏单回合开始时,需要关中断后重置
seconds = 0、time_out = false、timer_running = true启动计时 - 游戏单回合提前结束时,需要将
timer_running设为false停止计时,避免影响下一轮计数
内容的提问来源于stack exchange,提问作者Doesnt Matter
相关产品推荐
相关产品推荐

