理解ADC:为什么量化噪声也会产生谐波?附带介绍 Dither(抖动)

前言

今天继续从经典的 ADI 《MT-001》说起,通常情况下量化噪声是白噪声,但如果量化噪声与输入信号之间存在相关性,就不能被当做白噪声对待。

文中举了一个有意思的例子:理想 ADC 的采样频率为 80 MSPS ,一种情况输入信号频率为 2MHz,采样频率与其相除正好是 40 倍;另一种情况输入信号频率稍微偏一点,为 2.111MHz,采样频率不能与其整除。那么两种情况的量化噪声分别什么样?

图1 量化噪声 FFT 频谱图:(A) 输入信号为 2MHz; (B) 输入信号为 2.111MHz;[1]

可以看到,图 (A) 中量化噪声中有明显的谐波,且 FFT 底噪较低;图 (B) 中没有明显的谐波,且 FFT 底噪较高。

文中告诉我们,两种情况下理想 ADC 的 SNR 都是 74 dBc(噪声总能量一样),但图 (A) 中 SFDR 是 77dBc(谐波较大),图 (B) 中 SFDR 是 92dBc(谐波较小)。

解释原因,文中强调了“相关性”,摘录如下:

Under certain conditions where the sampling clock and the signal are harmonically related, the quantization noise becomes correlated, and the energy is concentrated in the harmonics of the signal—however, the RMS value remains approximately q/√12.
Quite often, the assumption is made that the theoretical quantization noise appears as white noise, spread uniformly over the Nyquist bandwidth DC to Fs/2. Unfortunately, this is not true in all cases. In the case of strong correlation, the quantization noise appears concentrated at the various harmonics of the input signal, just where you don't want them.

你理解了吗?下文是我的理解。


为什么量化噪声会产生谐波?

我们可以把 ADC 看成是一种非线性设备,输入一个连续的信号,输出一个离散的(有台阶)的量化信号,比如:

图2 ADC 量化信号与量化噪声[2]

量化信号与输入信号之间的差距,就是量化噪声。

如果采样时钟频率是输入信号的整数倍(比如以 80MHz 采样 2MHz 的正弦波),在每个周期内,采集到的样本数量是一样的,并且这些“样本值”也是固定的。对于不同周期的采样,只是在一遍一遍的重复这些样本值。

然后,将量化信号与输入信号相减,得到的量化噪声也是一些固定的样本值,重复出现的样本值具有周期性,这种周期性与输入信号相关。图2 就是这样一个例子。

如果采样时钟频率不是输入信号的整数倍(比如以 80MHz 时钟采样 2.111 MHz 的正弦波),只要采样的样本数量够多,几乎能覆盖正弦波所有可能的值(因为每个周期内采样的位置不同),样本值的合集非常丰富。将两者相减,得到的量化噪声是相对随机的,这使得量化噪声与输入信号不相关。

总之,如果量化噪声在周期上与输入信号具有相关性,会出现谐波,使得 SFDR 不佳。但就 SNR 来说,因为只影响噪声能量密度的分布,总能量没有变化,所以 SNR 一样(理想 SNR 只由 bit 位数决定,详情请见上一篇)。


为什么只有奇数谐波?

另外一个问题,在图1 (A) 中,为何量化噪声的频谱只有输入信号的奇数谐波?如 3rd(6MHz)、 5th(10MHz)、 7th(14MHz)……

对于这个问题,回顾一下傅里叶变换的基本图示,比如下面这种可以帮助理解:

图3 FFT奇数谐波对应的信号[3]

图4 FFT偶数谐波对应的信号[3]

也就是,如果信号在正半周期与负半周期是对称的,频谱上只有奇数谐波;如果正半周期与负半周期不对称,则有偶数谐波。图1 (A) 的量化噪声属于前者的情况。


如何模拟量化噪声?

我看了几篇用 Python 模拟量化噪声的案例,类似步骤如下,完整代码见[4]:

signal = np.sin(2*np.pi*f0*t) #原始输入信号
quantized = quantize(signal, threshold) #量化信号
qnoise = quantized - signal #量化噪声

做出时域图和频谱图的示例分别如下:

图5 Python模拟的量化噪声[4]

图中,蓝色是原始输入信号,红色是量化后信号(2 bit 量化),绿色是量化噪声。

但在实际开发中,我们是对 ADC 之后的量化信号做 FFT,也就是对上图的红色信号直接做 FFT,那么想象一下其频谱图会是什么样?


如何破除相关性 —— Dither(抖动)

为了避免图1 (A) 中的情况,现代化 ADC 内部具有 Dither,这是一种对信号施加抖动的技术,可以破除量化噪声相关性,虽然会略微增加底噪,但可以改善 SFDR 。

一般 SPEC 上也会标注 Dither 开启后的 SFDR 差异,举例如下:

图6 ADC ltc2208 内部 Dither 对 SFDR 的提升[5]


小结

今天我们从 ADI 《MT-001》的例子出发,解释了当量化噪声与输入信号具有周期相关性时会产生谐波,通过 Dither 可以破除相关性,提升 SFDR。

顺便说一下 ADI MT 系列非常经典,值得细品,作者 Walt Kester 介绍如下,在 ADI 工作了 47 年:

图7 Walt Kester的介绍

有网友整理了他的著作全集,有兴趣查阅的话详见[6]。


参考资料

主要来自以下内容,都可以通过搜索关键词获取:

1. ADI MT-001 by Walt Kester: Taking the Mystery out of the Infamous Formula, "SNR = 6.02N + 1.76dB" and Why You Should Care
2. https://www.researchgate.net/publication/228855699_Improved_residual_analysis_in_ADC_testing
3. https://www.quora.com/What-are-even-and-odd-harmonics-in-audio-signals-Why-are-they-important
4. https://dsp.stackexchange.com/questions/36629/coherent-sampling-and-the-distribution-of-quantization-noise
5. ADI Linear ltc2208 datasheet
6. https://tomverbeure.github.io/2021/02/15/Analog-Devices-Tutorials.html


欢迎关注我的微信公众号“疯狂的运放”,及时收到最新的推文。

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

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

相关文章

从0到1构建 UniApp + Vue3 + TypeScript 移动端跨平台开源脚手架

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template 🌺 仓库主页: GitCode💫 Gitee &#x1f…

Docker部署教程:打造流畅的斗地主网页小游戏

Docker部署教程:打造流畅的斗地主网页小游戏 一、项目介绍项目简介项目预览二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署斗地主网页小游戏下载镜像创建容器检查容器状态查看容器日志安全设置四、访问斗地主网页小游戏五、总结一、项目介绍 项目简介 …

计算机视觉常用数据集Cityscapes的介绍、下载、转为YOLO格式进行训练

我在寻找Cityscapes数据集的时候花了一番功夫,因为官网下载需要用公司或学校邮箱邮箱注册账号,等待审核通过后才能进行下载数据集。并且一开始我也并不了解Cityscapes的格式和内容是什么样的,现在我弄明白后写下这篇文章,用于记录…

【机器学习】Lesson3 - 逻辑回归(LR)二分类

目录 背景 一、适用数据集 1. 数据集选择 1.1 领域 1.2 数据集维度 1.3 记录行(样本数量) 2. 本文数据集介绍 3. 数据集下载 注意 二、逻辑回归的基本原理 1. 目的 2. Sigmoid 函数 3. 类别划分 4. 召回率 三、代码 1. 导入所需包&数…

kubernetes——part2-3 使用RKE构建企业生产级Kubernetes集群

使用RKE构建企业生产级Kubernetes集群 一、RKE工具介绍 RKE是一款经过CNCF认证的开源Kubernetes发行版,可以在Docker容器内运行。 它通过删除大部分主机依赖项,并为部署、升级和回滚提供一个稳定的路径,从而解决了Kubernetes最常见的安装复杂…

重学SpringBoot3-Spring WebFlux之HttpHandler和HttpServer

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-Spring WebFlux之HttpHandler和HttpServer 1. 什么是响应式编程?2. Project Reactor 概述3. HttpHandler概述3.1 HttpHandler是什么3.2 Http…

3D Gaussian Splatting代码详解(三):模型构建,实现3D 高斯椭球体的克隆和分裂

3 模型构建 3.4 根据梯度对3D gaussian 进行增加或删减 (1) 对3D高斯分布进行密集化和修剪的操作 def densify_and_prune(self, max_grad, min_opacity, extent, max_screen_size):"""对3D高斯分布进行密集化和修剪的操作:param max_g…

无人机协同控制技术详解!

一、算法概述 无人机协同控制技术算法是指通过综合运用通信、控制、优化等多学科知识,实现对多个无人机的协同控制和任务规划。这些算法通常基于各种数学模型和控制理论,如线性代数、微分方程、最优控制等,旨在确保无人机能够相互协作&#…

【热门主题】000013 C++游戏开发全攻略

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【热…

QT中的item views与Item widgets控件的用法总结

0、前言 在一般进行数据表格展示的时候,大多时候要用到表格、列表或者树形结构。 Qt中常见的控件显示有两大类: Item View (list View、Tree View、Table View、Column View和Undo View)Item widget(List Widget、Tree Widget和…

ssm+vue645基于web的电影购票系统设计与实现

博主介绍:专注于Java(springboot ssm 等开发框架) vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不…

Spark RDD

概念 RDD是一种抽象,是Spark对于分布式数据集的抽象,它用于囊括所有内存中和磁盘中的分布式数据实体 RDD 与 数组对比 对比项数组RDD概念类型数据结构实体数据模型抽象数据跨度单机进程内跨进程、跨计算节点数据构成数组元素数据分片(Partitions)数据…

java-数据结构

一.链表 单向链表 /单向链表 public class SinglyLinkedList implements Iterable<Integer> {//头节点private Node head null;//头指针//节点类private static class Node{int value;//值Node next;//下一个节点的指针public Node(int value, Node next) {this.val…

pycharm与anaconda下的pyside6的安装记录

一、打开anaconda虚拟环境的命令行窗口&#xff0c;pip install&#xff0c;加入清华源&#xff1a; pip install PySide6 -i https://pypi.tuna.tsinghua.edu.cn/simple 二、打开pycharm&#xff0c;在文件--设置--工具--外部工具中配置一下三项&#xff1a; 1、 QtDesigner…

成本累计曲线:项目预算的秘密武器

在项目管理的过程中&#xff0c;成本控制是影响项目成败的关键因素之一&#xff0c;而其中“成本累计曲线”就像是一位财务导航员&#xff0c;为项目的成本控制和进度监控提供了极大的帮助。那么&#xff0c;什么是成本累计曲线&#xff1f;它包含哪些步骤&#xff1f;如何应用…

[0152].第3节:IDEA中工程与模块

我的后端学习大纲 IDEA大纲 1、Project和Module的概念&#xff1a; 2、Module操作&#xff1a; 2.1.创建Module: 2.2.删除Module&#xff1a; 2.3.导入Module&#xff1a; 1.导入外来模块的代码&#xff1a; 查看Project Structure&#xff0c;选择import module&#xff1a…

【Linux网络】UdpSocket

目录 套接字 socket编程 源IP地址和目的IP地址 端口号 网络字节序 socket常用API socket结构 UDP UDP协议&#xff08;用户数据报协议&#xff09; 创建套接字 绑定 通信 udp_echo_server:简单的回显服务器和客户端代码 dict_server:简单的英译汉的网络字典 chat_…

双11猫咪好物盛典开启,线上抢购不停 购物清单新鲜出炉

双十一购物狂欢节终于到了&#xff01;铲屎官们想好要给猫咪添置什么好东西了吗&#xff1f;还不知道怎么选的看过来啦~这里整理了一份双十一购物清单&#xff0c;快看看有没有你需要的吧&#xff01; 双十一养猫必购1&#xff1a;CEWEY自动猫砂盆 CEWEY自动猫砂盆真的是我最爱…

magic-api简单使用二:自定义返回结果

背景 在上一章 中我们学习了搭建项目和导入文件&#xff0c; 这二天稍微有点时间&#xff0c;研究下这个magic-api的写法。 后续如果需要维护或者更改&#xff0c;也能在项目中尽快上手。 今天我们主要学习自定义返回结果&#xff0c;当然也可以使用官方的。不需要任何更改。…

二百七十、Kettle——ClickHouse中增量导入清洗数据错误表

一、目的 比如原始数据100条&#xff0c;清洗后&#xff0c;90条正确数据在DWD层清洗表&#xff0c;10条错误数据在DWD层清洗数据错误表&#xff0c;所以清洗数据错误表任务一定要放在清洗表任务之后。 更关键的是&#xff0c;Hive中原本的SQL语句&#xff0c;放在ClickHouse…