找回密码
 立即注册
楼主: 杨为民

关于12位ADC 计算公式是除4096还是除4095的问题讨论

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2026-05-01 00:01:26
已绑定手机

0

主题

45

回帖

459

积分

中级会员

积分
459
发表于 2026-4-22 22:03:42 | 显示全部楼层
你说的没错无论用什么公式调试出来结果都一样,关键是硬件只有4095个值啊,不争心不平。就算我明知道要死但是我每天要吃饭争口气是一个道理。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:13
  • 最近打卡:2026-04-24 21:04:12

0

主题

21

回帖

250

积分

中级会员

积分
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的物理工作原理完全一致。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2026-05-01 00:01:26
已绑定手机

0

主题

45

回帖

459

积分

中级会员

积分
459
发表于 2026-4-23 17:30:32 | 显示全部楼层
哦,你这么一说我突然茅塞顿开,我一直勿略了一个问题没把0当数看,
其实是0-4095是4096个LSB,也就是4097个点。
如果比较器在0.5个LSB翻转那么它的精度相对较低,但是读数更稳.
如果比较器在1个LSB翻转那么它的精度相对较高,但是读数没那么稳。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2026-05-01 00:01:26
已绑定手机

0

主题

45

回帖

459

积分

中级会员

积分
459
发表于 2026-4-23 17:37:56 | 显示全部楼层
当REF为5V时读出0的时候其实就是显示0.00122电压值。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2026-05-01 00:01:26
已绑定手机

0

主题

45

回帖

459

积分

中级会员

积分
459
发表于 2026-4-23 17:41:43 | 显示全部楼层
读出4095的时候其实就是显示0.00122X4096电压值
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2026-05-01 00:01:26
已绑定手机

0

主题

45

回帖

459

积分

中级会员

积分
459
发表于 2026-4-23 17:44:19 | 显示全部楼层
好奇妙的感觉,看0不是零
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:107
  • 最近打卡:2026-04-30 14:22:38
已绑定手机

4

主题

272

回帖

6183

积分

论坛元老

积分
6183
发表于 3 天前 | 显示全部楼层
杨*** 发表于 2026-4-22 14:18
我也不知怎么让你得出“耍嘴皮子”的看法,敢不敢赌一把?

简单测试了一下,或许你的说法是对的,ADC脚电压要非常接近VREF才能得到4095的值;
或许我的测试方法有问题,数值不是很稳定。
测试方法:“可编程电阻器”(接VREF,C5处,AI8051U实验箱为3.3V,与VCC相同)与10K电阻(接地,C5处)串联分压,ADC测量这个分压值(C24处)。
    代码是在例程“16-ADC检测16个按键”里改的,用数码管后四位显示ADC结果。
    代码: ai8051u-testadc.zip (115.13 KB, 下载次数: 1)
测试结果:
    当“可编程电阻器”阻值设置为不大于0.2欧时(电压约0.066mV),ADC值有较大概率是4095,
    当“可编程电阻器”阻值设置为1欧时(电压约0.33mV),ADC值有较大概率是4094;
    本来按我的理论,若是电压4096等分,每份电压为3300/4096=约0.8mV,当“可编程电阻器”阻值在不大于2.4欧,ADC值就应是4095,
    实际确差得有点远,莫非ADC引脚内部的模拟开关有压降?
    以为实验箱的PCB引线比较长可能存在干扰,所以买了一块很小的核心板测试,也是差不多的结果。
    另外我也在开天斧三.2(STC8H8K64U)与屠龙刀三.2(STC32G12K128)上用类似方法测试,结果却更差,ADC脚与VREF短接时也很小概率出现4095。
ScreenShot_2026-04-27_231629_112.png
ScreenShot_2026-04-27_231533_177.png


另一个测试结果,想看一下10位ADC的表现如何,单片机是STC15W408AS,VCC约5V:
   代码: stc15-testadc.zip (25.9 KB, 下载次数: 1)
   “可编程电阻器”接VCC,与10K电阻(接地)串联分压;
   当“可编程电阻器”电压不大20.0mV时,ADC值为1023;
   当“可编程电阻器”电压不大24.2mV时,ADC值为1022;
   按我的理论,若是电压1024等分,每份电压为5000/1024=约4.9mV,当“可编程电阻器”电压大于4.9mV时,ADC值就应是1022才对,
   实际却需要更大的电压降才行,莫非是VREF在内部低于了VCC?
ScreenShot_2026-04-27_231653_256.png
ScreenShot_2026-04-27_231717_333.png ScreenShot_2026-04-27_231729_054.png
ScreenShot_2026-04-27_231742_794.png ScreenShot_2026-04-27_231755_048.png

点评

送999不成功 送512成功,但不让送了 你回个贴,下次我送256试试?  详情 回复 发表于 3 天前
(1)作为程序员,比在写程序的时候只能写一行程序,程序中必须选择做个唯一的选择:是4096或者是4095。所以我写了另一篇文章供你参考。 在12位ADC 计算公式是除4096还是除4095是选择题而不是对错题 https://www.s  详情 回复 发表于 3 天前
1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:76
  • 最近打卡:2026-04-30 21:57:39

151

主题

1324

回帖

4902

积分

荣誉版主

积分
4902
发表于 3 天前 | 显示全部楼层
lcws*** 发表于 2026-4-28 00:01
简单测试了一下,或许你的说法是对的,ADC脚电压要非常接近VREF才能得到4095的值;
或许我的测试方法有问 ...

(1)作为程序员,比在写程序的时候只能写一行程序,程序中必须选择做个唯一的选择:是4096或者是4095。所以我写了另一篇文章供你参考。

在12位ADC 计算公式是除4096还是除4095是选择题而不是对错题
https://www.stcaimcu.com/thread-23569-1-1.html
(出处: 国芯人工智能技术交流网站)

我在上面文章中列举的观点是不同身份的人有不同的选择,程序员听老板的选择。
(2)看到你的实验照片,我回想起30多年前为云南烟叶收购做的电子秤,当时使用的单片机是Intel8096,片上没有ADC(8097才有10位),购买到的ADC芯片ADC0809只有8位,而要求是300公斤量程正负10克。
因此只能利用8096的16位计数器自己设计电路制作了15位的双积分ADC。按用户要求数码管显示到XXX.ZZZ公斤,小数点后三位。
然后到质检局审批合格证,人家就是放10公斤、1公斤的 砝码,要求小数后显示的是".000",不会听你解释什么LSB的。
(3)很高兴你提供了另一种选择:工程师应该做实验来选择。也很高兴看到你的结果:
简单测试了一下,或许你的说法是对的,ADC脚电压要非常接近VREF才能得到4095的值;或许我的测试方法有问题,数值不是很稳定。
看你使用了标准电阻板,我认为你的测试方法是正确的。
(4)感谢你愿意动手来验证ADC公式的正确性,送999朵小红花


(5)不好意思,我的星愿不足
星愿.jpg

我不知道我有多少星愿,我都送给你吧


回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:76
  • 最近打卡:2026-04-30 21:57:39

151

主题

1324

回帖

4902

积分

荣誉版主

积分
4902
发表于 3 天前 | 显示全部楼层
(1)我不知道我有多少星愿,我想知道,把它全部送出,怎么办?每次10个10个地送?

(2)菩萨把着方向盘,让我为大家展示一次ADC变换的原理:用对半法
(3)大家可以在楼上看我的演示过程

回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:76
  • 最近打卡:2026-04-30 21:57:39

151

主题

1324

回帖

4902

积分

荣誉版主

积分
4902
发表于 3 天前 | 显示全部楼层
lcws*** 发表于 2026-4-28 00:01
简单测试了一下,或许你的说法是对的,ADC脚电压要非常接近VREF才能得到4095的值;
或许我的测试方法有问 ...

送999不成功
送512成功,但不让送了
你回个贴,下次我送256试试?
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-5-1 10:30 , Processed in 0.129001 second(s), 108 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表