Arduino的void loop能否独立运行?LCD秒计数器延迟更新问题求解
问题根源
你的代码里用的delay()是阻塞式函数,执行到delay()时程序会完全暂停等待时间结束,期间不会执行任何其他代码。所以counter()函数只能等text()里总时长16秒的三个delay全部执行完才会运行一次,自然只能16秒更新一次计数。
解决方案
改用非阻塞的时间判断逻辑,基于millis()函数记录时间差,分别控制文本切换和计数器更新,两个逻辑互不阻塞。
修改后完整代码
#include <LiquidCrystal.h> const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // 文本切换相关变量 unsigned long textLastMs = 0; const long textInterval1 = 8000; // Text1显示时长 const long textInterval2 = 4000; // Text2显示时长 const long textInterval3 = 4000; // Text3显示时长 int textStage = 0; // 当前文本展示阶段 0:Text1 1:Text2 2:Text3 // 计数器相关变量 unsigned long counterLastMs = 0; const long counterInterval = 1000; // 计数器更新间隔1秒 int secondCount = 0; void setup() { lcd.begin(16, 2); // 初始化显示第一个文本 lcd.setCursor(6, 0); lcd.print("Text1"); } void loop() { unsigned long currentMs = millis(); updateText(currentMs); updateCounter(currentMs); } void updateText(unsigned long currentMs) { switch(textStage) { case 0: // 显示Text1阶段 if(currentMs - textLastMs >= textInterval1) { // 到时间切换到下一阶段 lcd.setCursor(6, 0); lcd.print(" "); textStage = 1; textLastMs = currentMs; lcd.setCursor(6, 0); lcd.print("Text2"); } break; case 1: // 显示Text2阶段 if(currentMs - textLastMs >= textInterval2) { lcd.setCursor(6, 0); lcd.print(" "); textStage = 2; textLastMs = currentMs; lcd.setCursor(6, 0); lcd.print("Text3"); } break; case 2: // 显示Text3阶段 if(currentMs - textLastMs >= textInterval3) { lcd.setCursor(6, 0); lcd.print(" "); textStage = 0; textLastMs = currentMs; lcd.setCursor(6, 0); lcd.print("Text1"); } break; } } void updateCounter(unsigned long currentMs) { if(currentMs - counterLastMs >= counterInterval) { counterLastMs = currentMs; secondCount++; // 先清除上一次的数字,避免位数变化时残留旧字符 lcd.setCursor(7, 1); lcd.print(" "); lcd.setCursor(7, 1); lcd.print(secondCount); } }
实现说明
- 所有延时逻辑都通过
millis()计算当前时间和上次执行时间的差值来判断是否到执行时机,全程没有阻塞,两个功能可以并行运行 - 文本切换按阶段控制,保持你原来的8秒、4秒、4秒的16秒循环周期不变
- 计数器每秒单独更新,同时加了清除旧数字的逻辑,避免计数到两位数后出现字符残留问题
内容的提问来源于stack exchange,提问作者agester
相关产品推荐
相关产品推荐

