发个烙铁 老贴!

[复制链接]
2923|1
 楼主| fleshyao 发表于 2007-12-14 21:27 | 显示全部楼层 |阅读模式
AD, AN, ADM, DM, ov
求平均值的简捷方法&nbsp;<br />&nbsp;xieyuanbin&nbsp;发表于&nbsp;2005-3-16&nbsp;08:29&nbsp;PIC&nbsp;单片机&nbsp;←返回版面&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />求平均值的简捷方法(PIC系列)<br />首先说明,这是前人所推荐的求平均值的方法,只是经过我的一点点加工整理<br />这里开头先说一个重要的概念,在二进制数值表示方法中,一个无限长的二进制数顺序向左移动一位就是原值乘以二,而如果二进制数顺序向右移一位就是原值除以二。我们利用这个特性在PIC单片机中可以很方便地求得两个数的平均值:将两个数相加,然后将和右移一位便是两个数的平均值,如果和是奇数,那么余数就在C里面。这里的所有移位指令均为带进位移动。<br />更进一步的方法,比如我们要求一段时间内AD值的平均值,通常需要把几十次的和再除以几十,而利用移位其实非常方便,甚至求和后都可以不用再作任何运算就可以得到平均值。举一个很特殊的例子说明:<br />我们要为8位的AD结果做平均值运算,如果我们一次做256次(注意刚好是2的8次方哦)AD转换,将每次的AD结果相加,这样256次AD转换之后我们得到一个16位的和,这时我们就不用再把和除以256了,实际上我们已经得到了8位的平均值整数部分,那就是16位和的高8位!怎么证明?很简单:我们求得的和要除以256,将256拆开,就是这样一个方程(假设平均值为X,和为Y):<br />X=Y/(2*2*2*2*2*2*2*2)<br />也就是将Y除以8次2,换句话说按照上面的说法就是要将“和”右移8位————刚好将16位和的高8位移入低8位,而原低8位如果作为小数舍去的话,那么原高8位就是平均值的整数部分!既然如此简单就没有理由再去自找麻烦移位8次了,直接取16位和的高8位多简单?若是有人拿了那个16位的和直接去冒充16位精度的AD结果,我也不反对。<br />让我们再来思考一下10位AD值的平均值如何求:再做256次?太麻烦了,取得的和要18位占用3个字节,而且时间太长不允许,怎么样才更简便呢?右对齐的10位AD值占用两个字节,高字节前面还有6位空的,6位就是2的6次方=64,这就是我们需要做AD的次数,做完64次AD之后结果相加的和刚好是10位的左对齐值!当然要舍去低字节的低6位,那是小数,我们取整的时候并不关心的。有人说:我还是需要结果是右对齐的以方便计算————那就右移6位…………有必要吗?其实还有更简单的:那就是只需要左移2位!呵呵大家都是明眼人不用我多说为什么了,可以看得出来这有多方便。<br />推而广之,如果我们要作若干整数的平均值,只需要先求2的n次方次的和然后右移n次或者左移(8-n)次就可得到它们的平均值整数了。往哪移,看往哪近喽。<br />附:10位AD转换求64次平均值程序:<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVLW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D'64'<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVWF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COUNT<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVLW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADRESL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVWF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FSR<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLRF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANH<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLRF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;这个不要忘了<br />LOOPAD<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AD转换<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADRESH,W<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADDWF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANL,F&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;加高字节,因为高字节只有最低两位,64次求和不会溢出,所以不用判断是否有进位。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;INDF,W<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADDWF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANH,F&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;加低字节<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BTFSC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STATUS,C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;是否有进位<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;INCF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECFSZ&nbsp;&nbsp;&nbsp;&nbsp;COUNT<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GOTO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOOPAD<br />平均值调整<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BCF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STATUS,C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;这是一个移位之前的好习惯,许多找不到原因的错误就源于此<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RLF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANH<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RLF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RLF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANH<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RLF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RLF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;思考:为什么要做两次半左移?为什么先前加的时候AD结果高字节加到暂存低字节?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVLW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B'11'<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ANDLW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADMEANH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;舍掉高字节高六位的余数。<br />;至此,64次AD的结果平均值高字节两位结果在ADMEANH中,低字节8位在ADMEANL中<br />;=============================================================<br />AD转换<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;重新选择AD通道<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;重新开启AD模块&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;这两项比较重要,在同一个通道反复采样中,必须每次都重新采样才能得到准确的AD结果<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;采样延时&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;大约几十微秒使采样电容充饱,此延时视AD口输入阻抗而定。若阻抗大于10K,应适当延长采样时间。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADCON0,GO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BTFSC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADCON0,GO<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GOTO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$-1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AD返回<br />&nbsp;<br />&nbsp;<br />
aihe 发表于 2007-12-14 21:58 | 显示全部楼层

学习一下

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

45

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部