仅代表个人观点有不对的地方欢迎指正。如果不使用外部rtc使用单片机自带的rtc时间上会出现偏移。如何进行修正RTC时钟源相对准确的是外部LEXT32.768KHz的晶振。其主要受到 温度、晶振自身温漂、干扰等影响。为了在现有情况下去调整不再增加板载温度监测直接使用片内温度监测。加快计算抛去浮点数计算。int32_t Get_MCU_Temperature_x100(u16 adc_raw) { int32_t temp_x100; //目标公式目标公式T(Vadc-1270)/4.1325 //为了保留2位小数扩大100倍100*T(100*Vadc-127000)/4.132500 //其中(100*Vadc-127000)/4.13为了消除分母分子分母同乘100 //100*T(10000*Vadc-12700000)/4132500 // Vadc ADC_RAW× 3300 /4096 // 直接带入计算 // 100*T(10000*(ADC_RAW×3300/4096) - 12700000)/413 2500 //计算(10000*(ADC_RAW×3300/4096)/413≈19.507 //计算12700000/413≈30750.6 //最终: 100*T( 19*ADC_RAW - 30750 ) 2500 //vadc_x100 adc_raw*19;//19.507*32≈624//(adc_raw*624)/32//(adc_raw*624)5; temp_x100 (adc_raw*624)5; // 2. 计算 19 * ADC_RAW - 30751 //numerator vadc_x100 - 30751; // 3. 加上 25℃ 基准 (25 * 100 2500) //temp_x100 vadc_x100 - 30751 2500; //temp_x100 temp_x100 - 28251; // 4. 减去 12℃ 补偿单片机运行产热的温差12℃ //temp_x100 temp_x100 - 28251 - 1200; temp_x100 temp_x100 - 29451; return temp_x100; }既然可以对其进行加快/放慢那就设定温度和初始温漂对其进行调整。// 关键配置参数 // 【必须标定】常温(25℃)下的初始频偏。 // 正数表示晶振偏快(需要减慢RTC)负数表示偏慢(需要加快RTC)。 // 放大1000倍。例如常温下测得晶振每天快 2 秒 (约 23ppm)则填 23000。 // 如果没测过先填 0后续根据测试结果微调。 #define RTC_INITIAL_PPM_X1000 (0) void ertc_temperature_calibration(int32_t temp_x100) { // 1. 将放大100倍的温度转换为放大10倍的温度 (保留0.1℃精度) // 加 5 是为了实现四舍五入 int32_t temp_x10 (temp_x100 5) / 10; // 2. 计算与 25℃ 基准的温差 (放大10倍) // 假设温度范围 -40℃~85℃温差范围大约是 -650 到 600 int32_t delta_t_x10 temp_x10 - 250; // 3. 计算温差的平方 (放大100倍) // 最大平方值(-650)^2 422,500。 // 这个值远远小于 int32_t 的最大值(21.4亿)绝对安全 int32_t delta_t_sq_x100 delta_t_x10 * delta_t_x10; // 4. 计算温度引起的“变慢”频偏 (放大1000倍) // 物理公式: Drift_PPM -0.034 * (T - 25)^2 // 因为 delta_t_sq_x100 放大了 100 倍所以公式等价变形为: // drift_ppm_x1000 -34 * delta_t_sq_x100 / 100 // 【关键】这里只有 32位乘法 和 32位除法全部触发 M4 硬件指令 int32_t drift_ppm_x1000 -(34 * delta_t_sq_x100) / 100; // 3. 计算总频偏 初始频偏 温漂频偏 // 正数代表整体偏快负数代表整体偏慢 int32_t total_ppm_x1000 RTC_INITIAL_PPM_X1000 drift_ppm_x1000; // 假设此时 total_ppm_x1000 已经计算出来且我们只关心它的绝对值用于计算脉冲数 N // 注意计算脉冲数 N 时必须使用正数绝对值 int32_t abs_ppm_x1000 (total_ppm_x1000 0) ? total_ppm_x1000 : -total_ppm_x1000; // 【极致优化核心】 // 1. 全部使用 int32_t触发 M4 硬件指令避免 64位软件库调用。 // 2. 使用 ( * 1100 524288) 20 完美替代 (* 1049 500) / 1000。 // 彻底消灭除法指令仅需 1次乘法 1次移位耗时 5 个时钟周期 int32_t N (abs_ppm_x1000 * 1100 524288) 20;// 需要补偿的脉冲数绝对值 uint32_t cal_dec 0; ertc_smooth_cal_clk_add_type cal_add ERTC_SMOOTH_CAL_CLK_ADD_0; // 5. 配置校准参数 (逻辑保持不变) if (total_ppm_x1000 0) { // 晶振整体偏快需要【减慢】 RTC cal_add ERTC_SMOOTH_CAL_CLK_ADD_0; cal_dec (uint32_t)N; if (cal_dec 511) cal_dec 511; } else if (total_ppm_x1000 0) { // 晶振整体偏慢需要【加快】 RTC cal_add ERTC_SMOOTH_CAL_CLK_ADD_512; if (N 512) cal_dec 0; else cal_dec 512 - N; } else { cal_add ERTC_SMOOTH_CAL_CLK_ADD_0; cal_dec 0; } // 5. 硬件配置 crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); pwc_battery_powered_domain_access(TRUE); ertc_smooth_calibration_config(ERTC_SMOOTH_CAL_PERIOD_8, cal_add, cal_dec); }将RTC_INITIAL_PPM_X1000作为外部调整参数即可对rtc进行平滑加快或减慢。