- 打卡等级:偶尔看看I
- 打卡总天数:13
- 最近打卡:2026-04-24 21:04:12
中级会员
- 积分
- 250
|
发表于 2026-4-23 09:03:50
|
显示全部楼层
不如问下AI:
在将12位ADC的采样值转换为电压时,正确的做法是除以4096。
这是一个在嵌入式开发中非常经典的问题,很多开发者都会有此疑问。下面为你详细解释为什么是4096,而不是4095。
🤔 为什么是 4096?
要理解这个问题,关键在于区分两个概念:“量化区间的总数”和“数字输出的最大值”。
量化区间总数是 4096
一个12位的ADC,其分辨率是12位,意味着它可以将参考电压(Vref)范围(例如0V到3.3V)等分为 2^12 个离散的区间。
2^12 = 4096
所以,整个电压范围被切成了 4096个 小台阶,每个台阶的宽度被称为 1个LSB (Least Significant Bit,最低有效位)。
1 LSB = Vref / 4096
数字输出的最大值是 4095
ADC转换后输出的是一个数字码。由于数字系统从0开始计数,这4096个区间对应的数字码范围是 0 到 2^12 - 1。
2^12 - 1 = 4095
因此,ADC能输出的最大数字值是 4095。
⚙️ 转换公式的推导
ADC的转换过程,本质上是将输入的模拟电压(Vin)映射到它所属的那个量化区间,并输出该区间的编号(即数字码)。
数字码 (ADC_value) = 0 代表输入电压在第一个区间 [0, 1 LSB) 内。
数字码 (ADC_value) = 1 代表输入电压在第二个区间 [1 LSB, 2 LSB) 内。
...
数字码 (ADC_value) = 4095 代表输入电压在最后一个区间 [4095 LSB, 4096 LSB) 内。
所以,一个数字码 N 代表的电压值,就是 N 个LSB的宽度。由此可以推导出计算输入电压的公式:
Vin = ADC_value × 1 LSB = ADC_value × (Vref / 4096)
整理后就是我们最终使用的公式:
Vin = (ADC_value × Vref) / 4096
⚠️ 为什么除以 4095 是错的?
如果使用 Vin = (ADC_value × Vref) / 4095 这个公式,会带来一个系统性的增益误差。
当ADC采样值达到最大值4095时,我们期望它代表接近参考电压Vref的值。但用错误的公式计算:
Vin = (4095 × Vref) / 4095 = Vref
这看起来似乎是对的,但它错误地假设了数字码4095就精确地等于Vref。实际上,数字码4095代表的是一个电压范围,其中心点或理想值是 4095.5 * (Vref / 4096),而整个ADC的量程上限(即4096个区间的终点)才是Vref。
使用除以4096的正确公式,当ADC值为4095时:
Vin = (4095 × Vref) / 4096 ≈ 0.99976 × Vref
这个结果准确地反映了4095这个数字码所代表的电压是“略低于参考电压Vref”的,这与ADC的物理工作原理完全一致。 |
|