如何把单片机/CPLD/FPGA的1个数字IO口变成DAC输出(非PWM方式)
warmonkey2013/04/23电子技术 IP:湖南
前言
此方法可以将1个数字IO口,转化成1路模拟量输出,分辨率>14bit,信噪比>30dB
这样的指标,已经超过了一些古老的8位DAC例如DAC0832,也大大超过了PWM能实现的性能。
而且,这个方法对IO只有两个要求:
1. 至少要有几百k速度,一般单片机都有
2. 几个mA的推挽输出能力(没有则加上缓冲级)
端口数量不限,比如你可以把一个CPLD的几十个脚,统统变成DAC输出

2012-11-03_19-28-23_265.jpg
使用此法通过IO口回放1kHz 8bit 录音,并使用示波器进行频谱分析

dsdemo2.gif
输出波形和频谱

实现方法
构建一个一阶Delta-sigma调制器,伪代码如下,可选汇编或者verilog实现
int acc;
int output;
while(1)
{
acc += output;
GPIO = bit_C;//单片机ALU的溢出位
while(!timeout);
}
不断把输出期望值累加到一个寄存器中,如果加法发生溢出,则设IO为高,否则设为低。
模拟电路部分,需要给输出脚加个RC无源滤波,一阶或二阶都可以
IO---R---C---R---C---OUT
              |______|_____GND

实际代码
Verilog Code for Cypress PSOC3

// Generated on 08/27/2012 at 00:03
// Component: DSDDAC
module dac(clk,nrst,data,dout);

`define wl 17
input clk,nrst;
input [`wl-2:0]data;
output dout;
reg [`wl-1:0]acc;
always @ (posedge clk or negedge nrst)
begin
if(!nrst)
begin
acc <= 0;
end
else
begin
acc <= acc[`wl-2:0] + data;
end
end
assign dout = acc[`wl-1];
endmodule

实物测试
无线音频传输装置,平台PSOC3,虚拟DAC时钟4M,SFDR > 30dB
attachment icon DSDDAC.7z 10.43KB 7Z 71次下载
Screenshot from 2013-04-23 02:10:40.png
电路原理图,DSD_DAC为一个GPIO口,没有模拟功能
2012-11-03_19-28-23_265.jpg
30dB是保守估计, 因为这里在1kHz附近的噪声,是录音音源和无线干扰引入的。
换成直接回放录音,SFDR可以轻松超过50dB。
此设计年代久远,未能留下最佳状态的数据,可惜了。
主观感觉,接耳机的时候,这东西音质类似AM收音机听本地强台的效果。底噪有点大,但是声音的还原还算不错

这个最主要优势是成本低,也没有PWM的基频泄漏,同时精度很高。
在这里输出级噪声和带宽的关系是“软”的,可以用更大噪声换取更大带宽。而PWM带宽受基波频率限制,提高基频频率之后,精度会严重降低。

原理
这个算法是如何工作的呢?为什么它在有高带宽的同时,又有高精度?
其实,我们将上面的计算程序,变换一下形式,就很明白了
float diff = 0, output = 0.3;//output = -1.0~1.0 //0-1扩展到-1~+1
while(1) {
//diff+=output;
if(acc < 0.0)  //diff = -acc
{   io =  1.0;  }
else
{   io = -1.0;  }
diff += io - output;
wait();
}
6860566889445.gif
diff是输出的误差,输出会不断的在+1和-1之间摆动,努力使得误差为0;
这就相当于,diff是一个积分器,它对输出和期望的偏差量io-output积分。
而if语句则相当于比较器,如果积分器输出为正,说明输出太高,需要输出-1,反之需要输出+1
这样就会在引脚上产生一个方波,它的频率和脉宽不断变化,但是方波电压的平均值,正好等于output输出波形见文章开头那幅图

进阶
如果采用更复杂的结构,例如使用4M的计数频率,3阶调制器,输出级采用对称恒流源结构(让IO口灌电流和拉电流的能力完全相同),理论上可以在4kHz内,达到80dB的信噪比。


从另外一个视角看上面的环路图:
量化噪声是在积分器之后,比较器(量化器)产生,输出端反馈回到积分器之前。
量化噪声通过负反馈环路,来到积分器之前。负反馈环路会抑制这个噪声。
积分器的存在,使得负反馈作用在低频段比较强,高频段比较弱(积分等效低通,引入一个极点,也就是20db/oct的滚降)
320px-DeltaSigmaNoise.svg.png
结果就是,在最后输出的信号频谱中,噪声主要集中在高频部分
如果改变环路的传递函数,就可以获得不同的噪声成形特性,比如说带通特性
这个过程叫做噪声成形 Noise shaping(上图),噪声传递函数很重要。。。


提高内部调制器阶数,改用更先进的环路,在同样的调制频率下,性能可以成倍提高,但是计算分析也更复杂。
好在有现成的matlab工具箱可以完成调制器的设计:
XXXXXXXXXXXXXXXXX/matlabcentral/fileexchange/19-delta-sigma-toolbox

反过来用
那就是Sigma-Delta ADC~~~~高精度必然是它了~~~~
上面的工具箱可以用于分析ADC

胡思乱想
如果把计数频率设计到1G、2G,甚至是10G、20G(很多FPGA的LVDS口已经有这个能力了),岂不是可以直接产生射频信号?

Screenshot from 2013-04-25 09:19:53.png
 
attachment icon REALIZATION OF A SIGMA-DELTA MODULATOR IN FPGA.pdf 561.43KB PDF 207次下载 预览

ADC做到这个频率,又会怎么样呢。。。

吐槽
digikey上面有不少24bit 96k音频DAC,信噪比超过100dB,还只要几块钱一个,它们就是这种原理做出来的。
相比之下传统的电阻阵列DAC,内部很复杂,成本很高,还只有极少数能做到16bit INL 1LSB误差,信噪比/谐波失真更是悲剧。
TI的器件页面上,16bit以上的DAC,全是D-S方式的。

废话
D-S调制理论被认为是近几十年来模拟电路理论的最大进步,它模糊了数字和模拟的界限。
有时候,更简单的实现,反而带来更好的效果。。。。


Ref
XXXXXXXXXXXXXXXXXXXXXXX/wiki/%CE%94%CE%A3%E8%AA%BF%E8%AE%8A

本坛大神Mitchell作品
XXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXml

闲来无事,搭了个简单的电路来验证Delta-Sigma DAC的性能。
滤波网络使用的最简单的无源2阶低通RC滤波器,DAC使用的100MHz时钟,Sigma累加器使用12bit分辨率:
37_6688_7b313298bf96f6f.jpg   

既然要来奇怪的波形,就来点更更更奇怪的波形吧,你看我Delta-Sigma DAC是怎么做得出来的,嘿嘿~
(1)奇怪阶梯。这相似度有没有99%?
37_6688_bba48252492f415.png

(2)既然要YY,那就YY得更彻底一点。这细节够丰富吧?
37_6688_51031f0cb407786.png

(3)挑战一下极限,XY显示。测试一下Delta-Sigma DAC的速度。
37_6688_a1968980fcbccd3.png

再来点别的:
(1)100KHz正弦信号输出
37_6688_1a406eea5f96c43.jpg

(2)Delta-Sigma信号波形。看仔细了,不是PWM。
  37_6688_c4246483902503d.png

(3)100KHz信号示波器截图。可以于LZ位的180Hz的正弦波做个对比。
   37_6688_0f069cc427e2d73.png

(4)最后是100KHz信号FFT,hanning窗。这信噪比没有60dB也至少有50dB了吧?单单这一项指标,就可以把加权电阻方案甩得不见踪影。
37_6688_d146db4766a9168.png

[修改于 7年4个月前 - 2017/01/17 23:52:03]

+200  科创币    拔刀斋    2013/04/23 把delta-sigma解释的非常清楚
+30  科创币    yanli12321    2013/04/23
+16  科创币    神之觉醒    2013/08/10 得好好研究下~~~
+1  科创币    张静茹    2014/06/13 终于能大概看懂点哪个代码了
+1  学术分    虎哥    2013/04/23 高质量发帖
来自:电子信息 / 电子技术
27
 
4
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
warmonkey 作者
11年1个月前 IP:未同步
519066
本质上是一样的 伪代码那段 是单电平的调制
当输出误差acc累计到32768的时候 将acc设置成32768-65536=-32768
并设置输出为1,否则输出为0
也就是把output=-32768~32767映射到了0-1.0
这个程序 工作起来是完全正常的 输出频谱也符合D-S的特征
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
warmonkey作者
10年7个月前 IP:未同步
652174
yanli12321 发表于 2013-8-12 11:54
突然想到.........如果用D-S调制方式控制正弦逆变器后级那可是极好的啊!


那就是T类功放,频率和占空比一起变
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
warmonkey
学者 机友
文章
357
回复
7653
学术分
14
2008/10/11注册,1天13时前活动

Cubesat

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}