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

ADC0读取结果右移2位的作用及必要性咨询

关于ADC读取时右移2位的疑问

我已经解决了部分问题,但还有疑问需要澄清:使用以下ADC初始化与读取代码时,未添加(ADC0.RES >> 2)时得到十进制值4092,添加2位右移后得到1024。我不清楚其中原理,想了解该右移操作是否必要,以及为何仅在右移2位后得到该结果,请予以解释。

uint16_t adc_value=0;
void ADC0_init(void)
{
    /* Disable digital input buffer */
    PORTA.PIN6CTRL &= ~PORT_ISC_gm;
    PORTA.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
    
    /* Disable pull-up resistor */
    PORTA.PIN6CTRL &= ~PORT_PULLUPEN_bm;
    
    
    ADC0.CTRLB = VREF_ADC0REFEN_bm ;
    VREF.CTRLA = VREF_ADC0REFSEL_4V34_gc;  
    
    
    ADC0.CTRLC |= ADC_PRESC_DIV4_gc      /* CLK_PER divided by 4 */
               | ADC_REFSEL_INTREF_gc;  /* Internal reference */
    
    
    ADC0.CTRLA |= ADC_ENABLE_bm          /* ADC Enable: enabled */
               | ADC_RESSEL_10BIT_gc;   /* 10-bit mode */
    
    /* Select ADC channel */
    ADC0.MUXPOS  = ADC_MUXPOS_AIN6_gc;
}

uint16_t ADC0_read(void)
{
    /* Start ADC conversion */
    ADC0.COMMAND = ADC_STCONV_bm;
    
    /* Wait until ADC conversion done */
    while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
    {
        ;
    }
    /* Clear the interrupt flag by writing 1: */
    ADC0.INTFLAGS = ADC_RESRDY_bm;
    return (ADC0.RES >> 2);
}
解答

1. 右移操作的本质:ADC结果的对齐规则

你在初始化时配置了10位ADC分辨率(ADC_RESSEL_10BIT_gc),但这款MCU的ADC0.RES是16位寄存器。为了统一不同分辨率的存储格式,ADC会把10位的转换结果左对齐存储在寄存器的高位区域——具体到你的情况,10位有效数据被放在了ADC0.RES的bits 11~2位置,低2位补0。

比如你读到的4092,二进制是111111111100,其实就是10位满量程值(1023)左移2位后的结果(1023 × 4 = 4092)。

2. 右移2位的作用:还原真实的10位数值

右移2位操作ADC0.RES >> 2,就是把左对齐的有效数据移回寄存器的低10位,消除高位填充的偏移,得到符合10位分辨率范围的真实值(0~1023)。你得到的1024应该是近似值(实际满量程是1023,可能是测量误差或输入接近参考电压导致的微小偏差)。

3. 右移操作是否必要

这取决于你的使用场景:

  • 如果你需要计算绝对电压值(比如根据参考电压换算输入电压),必须添加右移,否则数值会被放大4倍,导致计算结果完全错误。
  • 如果你只需要比较ADC结果的相对大小(比如判断输入是否超过阈值),可以不用右移,但这不符合常规开发习惯,且会降低数值范围的可读性。

简言之,右移是为了将ADC的左对齐结果转换为开发者习惯的右对齐格式,确保数值对应真实的分辨率范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:25:30