PWM实现DAC尝试
不久前在数电中自学了DA与AD的内容, 书中介绍的主要是基于ADC, DAC芯片实现的数模之间的转换. 而实现DA还可以通过单片机输出PWM的方法.
网上找了相关资料, 一些作者的文章写得很不错, 让我这个“门外汉”也能简单了解PWM技术. 虽然不高深, 但这个过程中, 有数电, 模电和数学的综合运用, 这让我有点兴趣, 可以搞一搞. 尽管因为经验不能像那些文章那般专业, 但至少能把我的理解再简单地表述出来. 下面先从一些概念下手.
PWM(Pulse Width Modulation), 又称为脉冲宽度调制, 是利用MCU输出的数字信号(一般就是调制的矩形波)进而去产生控制模拟信号(各种其他波形等)的方法. PWM一般应用在测量通信方面(度娘如是说). PWM在这些领域如何风光暂且按下不表, 这次只对利用计时器I/O口输出PWM实现DA做思考.
顺便记一下, 单片机要实现PWM, 有两种方法:一种是利用计时器设置, I/O口输出PWM;另一种使用模块输出PWM. 一些功能强劲的MCU自带PWM模块用于产生PWM脉冲信号, 使用前对特定寄存器赋值, 比直接用计时器方便点. 如STC12C5A60S2系列, AVR和PIC等等.
大致的原理是这样的, 利用MCU的timer控制产生特定占空比频率的矩形波, 由傅里叶级数分析知道, 矩形波形函数可以分解为各级三角谐波, 所以运用模拟电子中的低通滤波器, 滤去高次谐波, 低频部分如果视为理想的话, 就能作为DA转换的直流输出. 因此关键是解决三个问题:
- 1.如何调节矩形波频率产生所需占空比, 程序上如何实现.
- 2.理想条件下, 滤去高次谐波后所得电压与控制量之间的关系, 具体来说数学表达式是怎样的.
- 3.低通滤波器设计, 如何使其滤波效果较好.
附带一个 - 4.如此构建的DA转换分辨率如何及误差.
为了说明简单, 先假设通过PWM设定输出了一个稳定周期不变矩形波, 然后引入一些变量, 思路大概是这样:
上图是调制后产生的稳定的矩形波, 参数说明如下:
- T - 由单片机定时器设定的最小取样时间间隔
- N - 一个周期包含的最小时间间隔数, 图中是10
- n - 一个周期内输出高电平的最小时间间隔数, 图中是7
函数方程:
采用展成复指数形式的傅里叶级数分析可能更简单些. 众所周知, 其级数系数$a_{k}$计算公式即:
简便起见, $V_{L}$视为0.
考虑$k=0$时, 在一个周期内积分得$a_{0}$:
这就是直流分量部分.
再考虑$k \neq 0$时:
这是滤波器需要去除的高次谐波部分.
从计算结果中可以看出, 如果能滤去较高次谐波, 只剩下$\frac{n}{N}V_{H}$, 当n从0变化到N, 输出电压范围从$V_{L}\sim0$. 设计滤波器需要计算计算截止频率以一次谐波频率为参照. 若使用最简单的RC低通滤波器, 特征频率应设置为$f_{0}=\frac{1}{NT}$,又因为RC滤波器$f_{c}=\frac{1}{2\pi RC}$, 应使$f_{c}$大于$f_{0}$, 得到NT小于2πRC,应该先设置好N与T再选择R与C, 在程序中N与T应该是设定不变的.
再稍微考虑下如何设置T与N, 这关乎到DA转换的精确度与分辨率.
说DAC芯片的时候有分辨率这一概念, 用以描述DA转换精度, 定义成能分辨出来的最小电压与最大电压之比. 比如10位DAC芯片, 分辨率表示为$\frac{1}{2^{10}}$.
而在用脉宽调制的方法时, 也是同样, 即n=1与n=N之比, 分辨率简单表示为$\frac{1}{N}$. 当然n也可以不以1作为变化间隔. 如令N=1024, 应该就可以大致模拟出10位DAC.
这里就引出一个矛盾, 增大N的设定值, 能够提高分辨率, 但也会增大NT, 使得高次谐波的频率降低, 这又为低通滤波器的工作带来麻烦, 会夹杂更多的纹波而降低精确度. 因此并不是N越大越好. 同时在选择R与C时, 也可以考虑留一些余地.
那么减小T如何呢, 这是个不错的选择, T往往受限于单片机的工作频率与其速度性能.
叙述完毕, 先用Proteus绘制仿真电路, 最终方案采用RC二阶无源低通滤波, 为能有一定带载能力输出采用电压跟随器. 如果是需要驱动大功率设备, 需要再加个功放.
程序的实现是这样的(先让n固定, 也就是输出电压不变):
1 |
|
粗略仿真波形结果
从上到下ABCD通道分别是:
A - P2.1口输出调制后的矩形脉冲
B - 经过一次RC低通滤波
C - 二次RC低通滤波
D - 电压跟随器输出
由于定时器定时1us, 已经达到了指令周期级别, 输出的矩形波会有一些不稳定, 这恐怕是这种方法难以避免的.
利用protues中的电压探针可以更为精确的测定输出的电压与程序中设定n的关系. 为了计算简单把N设定为1000吧.
从仿真测试结果来看, 还是可以的嘛o(* ̄▽ ̄*)ブ
简单地应用下实现 LED呼吸灯
在原来程序上稍微改改, 嗯…
1 |
|
参考: 《基于PWM实现DA转换电路设计》
.
.
.
.
.
.
.
.
.
終わり