概述
基于累加的PDM算法的原理
- 基于累加的PDM算法(2)
PDM编码原理如下:
单片机能输出Sin(t)吗?能,DA。
没有DA怎么办?PWM。
没有PWM怎么办?
事情就是这么来的。20多年前,不要说单片机内没有PWM,而且当时的MCS-51系列内连Timer2还没有呢。这个算法就是20多年前逼出来的。
下面看我怎样在数字端口输出SQRT(0.5)= 0.70710678…。
假设我们要输出实数值x,x在[0,1)。
我们只需要一个变量存累计数,事实上,我们只须保存尾数,不妨就叫它为Mantissa。Mantissa可以有[0,1)范围内的任意初始值。
下面一段程序是在定时中断内执行的。中断间隔是由你系统的需要和MCU的能力确定的。
Timer_ISR:
…
Mantissa += x ;
If (Mantissa >= 1) { Pout = 1 ; Mantissa -= 1 ; }
Else Pout = 0 ; //从哪个数字口Pout输出由你定
…
END of Timer_ISR.
每中断一次,端口输出一个0或1。
我们看一下当x= 0.7071…和初值Mantissa=0.5时,每次中断输出的实例:
1,0,1,1,1,0,1,1,0,1,1,0,1,…
那么输出序列中1的个数(h)/中断次数(n):
h/n=
1/1,1/2,2/3,3/4,4/5,4/6,5/7,6/8,6/9,7/10,8/11,8/12,9/13,…,11/16,…,23/32,…,45/64,…,91/128,…,181/256,…,…,23170/32768,…
化做小数容易对比,h/n=
1,0.5,0.6667,0.75,0.8,0.6667,0.7143,0.75,0.6667,0.7,0.7273,0.6667,0.6923,…,0.6875(n=16),…,0.71875(n=32),…,0.7031(n=64),…,0.7109(n=128),…,0.70703(n=256),…,…,0.70709(n=32768),…
我们可以看到,h/n是0.70710678…的最佳分数逼近(就同样的分母而言),而且随着n的增加,逼近的精度就越来越高了。如何选择中断间隔和输出端的滤波参数,就看系统对精度的要求了。当然,还受到MCU能力的限制。
在实际运用中,考虑到MCU的能力限制,我们要把算法变得更高效。例如:
由精度的要求,考虑一个合适的整数N(N=256,一般就够1%了),那么x也放大N倍成H=x*N;Mantissa也用整数CNT。那么,算法也就如上一篇中抛出的:
Timer_ISR:
…
CNT += H ;
If (CNT >= N) { Pout = 1 ; CNT %= N; } //或CNT -= N,就看哪个快
Else Pout = 0 ;
…
END of Timer_ISR.
这个算法的特点就是:在N个时钟周期内,均匀地送出H个1。
对8位、16位、32位MCU,我们选特定的N=256、N=65536、N=2^32。
那么一次加法就够了:
Timer_ISR:
…
CNT += H ;
Pout = Carry_Bit ; //直接输出进位到端口。
…
END of Timer_ISR.
20多年前,在8051中,我每一次定时器中断管3个PDM输出。就这么几句汇编:
Timer_ISR:
...
MOV A,CNT1
ADD A,H1
MOV CNT1,A
MOV Px.1,C
MOV A,CNT2
ADD A,H2
MOV CNT2,A
MOV Px.2,C
MOV A,CNT3
ADD A,H3
MOV CNT3,A
MOV Px.3,C
...
RETI
顺便说,在ARM Cortex-M中,用N=2^32比用N=2^8、N=2^16都要快。反一下汇编就知道了,因为运算是32位的,要8位、16位,还要从32位截下来,白白花费一些CPU周期。ARM Cortex-M系统,在Systick中,用汇编做软件PDM,挺不错的。
这种算法,用中国的成语说,就叫做“集腋成裘”,狐狸的腋毛积累到够做一件裘衣,就先做一件,剩下的零头归到下次继续积。
另外,AD、DA也常用到“Sigma-Delta”,我们的这种算法,洋叫法是不是可以叫做“Software Sigma-Delta” ?
现在MCU内,DA、PWM都不当回事了,还要翻这老黄历干吗?老黄历还有新用场,这就是我晒这粒陈芝麻的用意。后面慢慢道来。
The Priciple of The PWM Algorithm Based On Addition
- A PDM Algorithm Based On Addition (2)
===
最后
以上就是威武彩虹为你收集整理的基于累加的PDM算法的原理的全部内容,希望文章能够帮你解决基于累加的PDM算法的原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复