AVR32DD20处理器内部温度读取结果偏差,求错误排查建议
问题分析与解决方案
你的核心错误出在温度校准公式的理解与实现上,结合AVR32DD系列的温度传感器校准规则,具体问题和修正方案如下:
1. 错误根源
(1)未考虑校准斜率的单位缩放
AVR32DD的SIGROW.TEMPSENSE0(斜率值)单位是0.0625℃/ADC步,而非直接的温度/ADC步。你的计算中未对该系数做处理,导致结果被放大了16倍(0.0625 = 1/16)。
(2)温度单位混淆
你直接将计算结果当作开尔文温度,但根据校准公式,计算出的原始值是摄氏温度,需要加上273才能转换为开尔文。
(3)不必要的偏移/斜率转换逻辑
你尝试将校准值转换为3.3V下的等效值,不如直接将ADC原始读数转换为2.048V参考下的等效值更直观,也更容易避免计算错误。
2. 修正后的代码实现
// 确保ADC参考电压设置为VDD(3.3V),这一步很关键! ADC0.CTRLC |= ADC_VREFSEL_VDD_gc; uint16_t sigrow_offset = SIGROW.TEMPSENSE1; // 3249 uint16_t sigrow_slope = SIGROW.TEMPSENSE0; // 1192 // ADC初始化(保留你的原有设置) ADC0.MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; ADC0.CTRLD = (ADC0.CTRLD & ~ADC_INITDLY_gm) | ADC_INITDLY_DLY256_gc; ADC0.SAMPCTRL = 255; _delay_ms(10); // 替换为稳定的毫秒延迟(如果你的_delay_mu是微秒,10us也足够) ADC0_ConversionStart(); while (!(ADC0.INTFLAGS & ADC_RESRDY_bm)); uint16_t adc_val = ADC0_ConversionResultGet(); ADC0.INTFLAGS = ADC_RESRDY_bm; // 将3.3V下的ADC值转换为2.048V参考下的等效值 uint32_t adc_eq = (uint32_t)adc_val * 3300 / 2048; // 计算摄氏温度:考虑0.0625的斜率系数,除以2^16(65536) int32_t temp_c = ((int32_t)sigrow_offset - (int32_t)adc_eq) * (int32_t)sigrow_slope; temp_c >>= 16; // 等价于除以65536 // 转换为开尔文温度 int32_t temp_k = temp_c + 273;
3. 额外验证点
- 确认ADC参考电压设置:如果未设置
ADC_VREFSEL_VDD_gc,ADC默认使用内部2.048V参考,会导致所有转换值错误。 - 采样与延迟:你的采样时间(
SAMPCTRL=255)和初始化延迟设置已经足够,无需调整。
按上述代码计算,室温下的temp_k应该会接近296K(23℃),且温度变化时数值会线性响应。
内容的提问来源于stack exchange,提问作者Vladimir Gomon
相关产品推荐
相关产品推荐

