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

ESP32读取RTC毫秒值出现跳变问题的解决方案咨询

问题原因及解决方案

核心问题

  1. 数值计算错误:你用rtc.getMicros()/100得到的是10微秒单位的数值,不是毫秒,导致输出的“毫秒”实际是10μs的倍数,呈现跳变效果。
  2. RTC计时与硬件定时器不同步:ESP32Time的getMicros()依赖系统软件计时,和硬件定时器的1ms中断触发时机存在偏差,无法保证每次中断时刚好递增1ms。
  3. 冗余计数:你已经在中断里维护了millisCounter,这是硬件定时器驱动的精准1ms计数器,完全可以替代RTC读取的毫秒值。

修正后的代码

#include <Arduino.h>
#include <esp32-hal-timer.h>
#include <sys/time.h>
#include <ESP32Time.h>

ESP32Time rtc(0);

volatile bool timer_flag = false;
hw_timer_t *My_timer = NULL; // 创建硬件定时器
volatile unsigned long millisCounter = 0; // 毫秒计数器

void IRAM_ATTR onTimer() // 定时器中断函数
{
  timer_flag = true;
  millisCounter++; // 每毫秒递增计数器
}

void setup() 
{
  Serial.begin(115200);
  // 初始化硬件定时器:定时器1,预分频80(时钟80MHz/80=1MHz),向上计数
  My_timer = timerBegin(1, 80, true);
  timerAttachInterrupt(My_timer, &onTimer, true);
  // 设置中断触发周期:1000个时钟周期(1MHz时钟下,1000周期=1ms),自动重载
  timerAlarmWrite(My_timer, 1000, true);
  timerAlarmEnable(My_timer); // 启用定时器中断
}

void loop() 
{
  if (timer_flag) 
  {
    timer_flag = false;

    // 获取RTC秒数,结合硬件计数器的毫秒值
    int currentSecond = rtc.getSecond(); // 获取秒数
    unsigned long currentMillis = millisCounter % 1000; // 取计数器低三位,得到0-999的毫秒值

    // 输出时间信息
    Serial.print("秒: ");
    Serial.print(currentSecond);
    Serial.print(", 毫秒: ");
    Serial.println(currentMillis);
  }
}

额外说明

  • 如果需要完整的运行时间戳,直接使用millisCounter即可,它从0开始每毫秒递增,代表系统运行的总毫秒数。
  • 若必须使用RTC的毫秒值,需修正计算为rtc.getMicros()/1000,但仍可能存在同步偏差,精度不如硬件计数器。

内容的提问来源于stack exchange,提问作者sema

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:55:04