单片机外围模块漫谈之二,如何提高ADC转换精度

在此我们简要总结一下ADC的各种指标如何理解,以及从硬件到软件都有哪些可以采用的手段来提高ADC的转换精度。

1.ADC指标

除了分辨率,速度,输入范围这些基本指标外,衡量一个ADC好坏通常会用到以下这些指标:失调误差,增益误差,微分非线性,积分非线性,信噪比,信纳比,有效位数,总谐波失真。让我们以下图为例来看一下这些指标的意义。

LSB

参数中经常用LSB作为单位,比如说差分非线性为2 LSB。这究竟是多大一个值呢?为了简单起见,我们以一个3bit分辨率,满量程为5V的ADC为例。1个LSB对应的电压大小为5V/7=714mV。如果是8bit分辨率,那么1个LSB对应5/255=19mV。

图中横轴为输入电压Vin增长方向,纵轴为数字输出。理想情况下输入电压每增长1LSB(714mV),那么输出会向上跳变一次,对应虚线L1所在转换曲线。但实际电路往往会引入偏差,转换曲线往往如 L2 所对应曲线。

失调误差(Offset Error)

电压从0开始增大时,引起输出第一次跳变的电压值,与理论上应该引起第一次跳变的电压值(0.5 LSB)的差值。衡量小电压时的转换精度。如图中,理论上应该在0.5 LSB处跳变,实际电压增大到1 LSB时才跳变,所以Offset Error是 1–0.5 = 0.5 LSB。

增益误差(Offset Error)

可以理解为实际转换曲线偏离理想曲线的程度。用最接近满量程时跳变点电压值和理论跳变点电压值的差表示。

差分非线性 DNL(Differential Non-Linearity)

理论上每增加或减少1 LSB 的电压,都会引起输出对应的一次跳变。但实际情况可能如图中a,b处所示,电压的步距大于或小于1个LSB的理论步距。

a 处 DNL = 1.5 – 1 = 0.5 LSB;

b 处 DNL = 0.5 – 1 = -0.5 LSB;

积分非线性 INL(Integral Non Linearity)

差分非线性累积起来造成的对实际转换曲线的最大偏离就是INL。如图中所示,需要注意的是INL不能表征对理想转换曲线的偏离程度。

总不可调整误差 TUE(Total Unadjusted Error)

实际转换曲线与理想转换曲线之间最大的偏离。在最糟糕的一点,我们通过ADC得到的电压,与实际电压的差值。通俗讲就是最不准的一点差多少。

思考一下,如果 DNL 和 INL 都非常好,那么是不是说明 TUE 就非常好?

对,还真不一定。即使线性度非常好,如果增益误差大,还是会导致最终结果大的偏差。

信噪比 SNR(Signal-to-Noise Ratio)

有用信号与噪声的能量比。我们总是期望信噪比越大越好。对于一个 N-Bit 分辨率的ADC来说,如果输入是一个满量程的正弦信号,在只考虑量化噪声的情况下,可以推导出一个有用的公式:

SNR = 6.02N + 1.76dB

推导过程见参考文档 ADI: MT-001

此公式直观的表明了ADC分辨率和信噪比之间的量化关系。

信纳比 SINAD (Signal-to-Noise-and-Distortion Ratio)

实际ADC是无法达到理想状态的,它的输出除了会引入噪声,还会引入输入信号的谐波。SINAD是有用信号能量,与谐波(Distortion)加噪声(Noise)能量的比,它更能体现现实世界中的ADC性能。

SINAD = 20log(S/(N+D))

*而SNR = 20log(S/N)

有效位数 ENOB(Effective Number of Bits)

体现ADC实际性能相当于多少位。可以从SINAD推出:

ENOB = (SINAD–1.76)/6.02

*和理想情况下的位数对应:NOB =(SNR - 1.76)/6.02。

总谐波失真 THD(Total Harmonic Distortion)

有用信号能量与谐波能量的比。

THD = 20log(S/D)

2.如何提高转换精度

模拟电源(VDDA)和电压参考(VREF)

有的单片机ADC模块会引出单独的电源引脚和电压参考引脚,最好用LDO给这些引脚供电,或者用磁珠和滤波电容把这部分电源从数字部分隔离出来。

输入信号的输出阻抗

下图是ADC采样简化等效电路。ADC采样和保持电路的等效输入电阻电容Radc,和Cadc,手册中都会给出。在采样期间,开关SW会接通外部的信号输入电路,给采样电容Cadc充电至和输入信号相等(接近),之后SW断开,ADC对采样电容上的电压进行转换。如果采样时间过短,或者输入信号的输出阻抗过大,将导致采样电压不准。在信号源输出阻抗过高时,可以考虑增加一级运放。

高频串扰

如果与模拟输入引脚靠近的IO上有高频翻转的信号,或者PCB上有与输入信号长距离的平行走线,串扰将干扰输入信号。应避免ADC引脚临近信号高频翻转。在ADC输入布线和临近的走线之间用地线隔离开也可以避免ADC精度下降。

Wait,Stop模式

如果ADC在Wait和Stop模式下还可以工作,在此种模式下可以最大限度的降低MCU电源的波动,提高ADC的转换精度。

过采样(Oversampling)

如果采样频率为fs,那么对于fs/2以内的信号频率既可以获得完整信息。过采样是用远高于所需的采样频率去采样,这样噪声就会均摊在整个采样频带内。我们用数字滤波器可以滤除有用信号频带之外的噪声,从而使频带内的信噪比提高,获得更高的分辨率。对多次转换结果进行平均也可以提高结果的精度。

芯片内部校正

很多单片机内部都有校正机制(Calibration),每次上电后执行一次Calibration,可以以提高ADC的精度。

温度的影响

ADC受温度影响比较大,特别是失调误差和增益误差。如果芯片工作温度范围很宽,可以在不同的温度下预先测量,按温度做出查找表以在实际工作时做校正。

混入白噪声

这种方法对提高直流信号的分辨率很有用。如果输入信号接近直流而且很稳定,那么输出就不会产生跳变,比如输出一直是0x15A,我们无法确认输入电平是更接近0x159,还是更接近0x15B。那么我们可以人为地把白噪声混入信号,使信号产生小的波动从而输出产生跳变,然后再通过数学平均得出一个精度更高的数值。实际操作中可以用GPIO产生一个方波然后通过阻容耦合进输入信号引脚。

参考资料:

ADI: Data Converter Introduction

ADI: MT-001 TUTORIAL  Taking the Mystery out of the Infamous Formula,

"SNR = 6.02N + 1.76dB," and Why You Should Care

ST: AN1636 UNDERSTANDING AND MINIMISING ADC CONVERSION ERRORS

ST: AN2834 Application note How to get the best ADC accuracy in STM32 microcontrollers

NXP: How to Increase the Analog-to-Digital Converter Accuracy in an Application

NXP: Cookbook for SAR ADC Measurements

推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Datawhale-零基础入门NLP-新闻文本分类Task05

该任务是用Word2Vec进行预处理,然后用TextCNN和TextRNN进行分类。TextCNN是利用卷积神经网络进行文本文类,TextCNN是用循环神经网络进行文本分类。 1.Word2Vec 文本是一类非结构化数据,文本表示模型有词袋模型(Bag of Words&…

想要学好C++有哪些技巧?

学C能干什么? 往细了说,后端、客户端、游戏引擎开发以及人工智能领域都需要它。往大了说,构成一个工程师核心能力的东西,都在C里。跟面向对象型的语言相比,C是一门非常考验技术想象力的编程语言,因此学习起…

window.open打开新窗口被浏览器拦截的处理方法

一般我们在打开页面的时候&#xff0c; 最常用的就是用<a>标签&#xff0c;如果是新窗口打开就价格target"_blank"属性就可以了&#xff0c; 如果只是刷新当前页面就用window.location.reload()&#xff0c; 在某些特殊情况下也要用到另外一种新窗口打开的方法…

Datawhale-零基础入门NLP-新闻文本分类Task06

之前已经用RNN和CNN进行文本分类&#xff0c;随着NLP的热门&#xff0c;又出现了大热的Attention&#xff0c;Bert&#xff0c;GPT等模型&#xff0c;接下来&#xff0c;就从理论进行相关学习吧。接下来&#xff0c;我们会经常听到“下游任务”等名词&#xff0c;下游任务就是N…

Linux-C编程 / 多线程 / 如何终止某个线程?

示例 demo最简单的 demo&#xff1a;static void* thread1_func(void *arg) {int i 0;// able to be cancelpthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);for(i0; ; i) {printf("thread1 %d\n", i);…

PaddlePaddle入门——基本概念

最近报了百度的深度学习认证&#xff0c;需要使用Paddle进行编程实现&#xff0c;找了一些基础教程&#xff0c;特意记录下来&#xff0c;加深印象。思维导图如下&#xff1a; 一、Paddle的内部执行流程 二、内部详解 1.Variable&#xff08;变量&#xff09; &#xff08;1…

回答一个微信好友的创业问题

ps:很喜欢这种有烟火气息的照片— — 提问&#xff1a;我最近要创业&#xff0c;打算跟一个朋友合伙&#xff0c;但是我朋友不会技术&#xff0c;所以他只投入钱&#xff0c;也不会参与公司的管理。我们启动资金是10万&#xff0c;他打算投入7万&#xff0c;想占股65%。因为没有…

百度深度学习初级认证——已过

开头先放图&#xff0c;百度深度学习初级工程师认证已通过&#xff0c;记录一下备战和考试细节&#xff01;&#xff01;&#xff01; 1.报考 当时是通过百度的AI Studio看到深度学习的认证了&#xff0c;价格是800&#xff0c;然后阴差阳错从百度技术学院的链接看到深度学习…

哦,这是桶排序

漫画&#xff1a;什么是桶排序&#xff1f;要了解桶排序之前&#xff0c;可以先看看上面小灰的那篇文章&#xff0c;我觉得是比较不错的。桶排序也可以理解为分类排序&#xff0c;把不同的数据归类&#xff0c;归类之后再重新排序&#xff0c;每个桶里面的内容就是一类数据&…

如何防御光缆窃听

很多年前&#xff0c;人们就认识到采用铜缆传输信息很容易通过私搭电缆的方式被窃取。对于一个网络和安全管理人员来说&#xff0c;要么对铜缆采用更严格的安全防护措施&#xff0c;要么就使用光缆。因为很多人都认为光纤可以很好地防止***通过窃听手段截获网络数据。但是实际上…

Linux字符设备驱动实例

globalmem看 linux 设备驱动开发详解时&#xff0c;字符设备驱动一章&#xff0c;写的测试代码和应用程序&#xff0c;加上自己的操作&#xff0c;对初学者我觉得非常有帮助。写这篇文章的原因是因为我看了我之前发表的文章&#xff0c;还没有写过字符设备相关的&#xff0c;至…

8-[函数]-嵌套函数,匿名函数,高阶函数

1.嵌套函数 &#xff08;1&#xff09;多层函数套用 name "Alex"def change_name():name "Alex2"def change_name2():name "Alex3"print("第3层打印", name)change_name2() # 调用内层函数print("第2层打印", name)chan…

c语言画谢宾斯基三角形

谢宾斯基三角形是一个有意思的图形&#xff0c;&#xff08;英语&#xff1a;Sierpinski triangle&#xff09;是一种分形&#xff0c;由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集。先画一个三角形&#xff0c;然后呢&#xff0c;取三角形的中点&#xff0c;组…

进程间的通信——无名管道

进程间的通信——无名管道 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、进程间的通信 &#xff08;1&#xff09;同主机进程间数据交互机制&#xff1a;无名管道&#xff08;PIPE&#xff09;&#xff0c;有名管道&#xff08;FIFO&#xff09;…

sklearn官网-多分类问题

sklearn实战-乳腺癌细胞数据挖掘&#xff08;博主亲自录制视频&#xff09; https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare 1.12.6. Multioutput classification Mult…

剖析C语言是如何画出这样的三角形的

哈哈&#xff0c;就是喜欢这些有意思的C语言上篇文章是这样写的c语言画谢宾斯基三角形那篇文章写的有点不直接&#xff0c;然后再查了下资料&#xff0c;看到了下面这些&#xff0c;我觉得解释更加好&#xff0c;这里主要是运用了光栅法&#xff0c;至于光栅法&#xff0c;可以…

NILMTK在Windows下的安装教程

近期&#xff0c;要进行负荷辨识&#xff0c;找到NILMTK安装包&#xff0c;特意将过程记录下来。 &#xff08;1&#xff09;Windows安装 本机已安装了Anaconda&#xff0c;环境是Python3&#xff0c;NILMTK包的项目地址为&#xff1a;https://github.com/nilmtk/nilm_metada…

修改cmdline 把内存改成512MB

#添加cmdline的方式— — 在BoardConfig.mk中修改device/mediateksample/aiv8167sm3_bsp/BoardConfig.mk BOARD_KERNEL_CMDLINE bootopt64S3,32N2,32N2 mem512MB— — 在dts 里面修改kernel-4.4\arch\arm\boot\dts\*.dts / {model "Atmel AT91SAM9M10G45-EK";compa…

NILMTK——经典数据集REDD介绍和使用

配置了NILMTK包的环境之后&#xff0c;想找数据测试一下&#xff0c;在NILMTK官网的API Docs里边发现dataset_converters模块中有内置的数据集处理函数&#xff0c;如图&#xff1a; 将数据转换成HDF文件&#xff0c;这些数据都是比较优秀的&#xff0c;其中&#xff0c;常用的…

上拉电阻的作用

1、介绍使用微控制器&#xff08;MCUs&#xff09; 或任何数字逻辑设备时&#xff0c;上拉电阻器非常常见。本教程将解释何时何地使用上拉电阻器&#xff0c;然后我们将做一个简单的计算&#xff0c;以显示为什么上拉很重要。2、上拉电阻是什么&#xff1f;假设您有一个将一个引…