搜索
bottom↓
回复: 22

关于A/D采样值 ->送显示平滑处理思想求助?

[复制链接]

出0入0汤圆

发表于 2010-8-6 13:34:19 | 显示全部楼层 |阅读模式
我使用的单片机是dspic30f2012 A/D产考基准采样的是MC1403 -> 2.5V 在电力系统中有1.2倍过载也就是X * 1.2 = 2.5v 单片机A/D最高被限定在2V。但单片机采样不了负极性,加1V偏移。12Bit A/D采样满度值就变成了±1638;如果想显示满度值866.0W  有:1638*21655>>12; ≈8659.8 这样处理是因为单片机内部含有16bit乘法器。处理除法要稍慢些。有此系数带来的就是A/D每变化一个字,显示值就变化了5个字!相对误差为0.6‰虽然可以达到技术要求但是5个字的蹦字看着难看!软件滤波方法不用说(采样频率6.4K,采样128点去掉一个最大值一个最小值平均,1s输出5次结果);我的问题来了,有什么样的思想可以稍微牺牲点响应速度,让显示值为一个字蹦字的假象!在输入信号不变的情况下,显示值尾数是±1为变化的范围还是5。要不然我也不会问这样的问题,刚在市场上买了一块表。也是用12位A/D的单片机处理的。回来测试,加上信号源。显示却很平滑。跳字范围也是5个字,但是他是以±1的循环变化。虽然响应速度有所下降,但是这种低价位的表,对于使用者来说没什么。希望处理过的同志给点思想!

前级采样的是时分割乘法器

(原文件名:plx.png)
Proteus仿真

(原文件名:dspic33fj32gp204.png)
Altium PCB

(原文件名:754.png)
硬件已经固定

(原文件名:752.png)

出0入0汤圆

发表于 2010-8-6 20:09:31 | 显示全部楼层
设一个数组(比如32个整数), 保存最后的32个显示值(不是AD值), 然后显示(n0+n2..n31)/32, 不知可否?

出0入0汤圆

发表于 2010-8-6 22:10:06 | 显示全部楼层
滑动平均

出0入0汤圆

 楼主| 发表于 2010-8-6 22:44:35 | 显示全部楼层
回复【1楼】my2009
-----------------------------------------------------------------------

保存最后的32个显示值(不是AD值)

1S设定出5次结果。6.4k的采样频率采样128点最多1S可以出50个结果;20ms就能完成128次采样。保持32个显示值时间应该没问题,思路没太理解,好像还是在滤波。并不能解决比如8660与8655两个数之间蹦字!可能我没叙述清楚,比如显示值当前显示的是8655对应AD值3275,当AD值为3276时显示直接就蹦到8660.虽然可以达到技术指标,但是对于用户来讲看着难看,我想牺牲点显示响应时间。采样速度不变,每秒钟输出显示结果最多可大50次。我用的是定时采样。1S出5次显示值,有800ms时间AD在休息。我在市场买的那块表说明书写着,消除临界值跳字,不知道指的是不是这个。我用标准源检那块表如8655 - 8660之间 他是8655、8656、8657、8658、8659、8660变化,只要给定输入值不变,这几个数在不定期变化,变化并不快,大概在500ms左右,上升一会,又落下!而我设计的表虽然很稳,但是是8655、8660两个数之间蹦。我用安捷伦监视AD输入信号有<0.6mv的临界值变化,蹦字跨度大我知道这是由于我乘的系数导致。且是正常的;12bitAD也就能做到这样了。我想弄成±1且变化,范围还是5个字的范围,我不知道这能不能说是用软件造出类似把AD位数提高的假象!似乎我买的那块表的软件设计者实现了。让显示变化更平滑一些。不想看到如显示尾数2、7/3、8这么蹦。

出0入0汤圆

 楼主| 发表于 2010-8-6 22:45:27 | 显示全部楼层
回复【2楼】888888888888
-----------------------------------------------------------------------

可能你这个词更贴切!但方法是怎样的呢?希望能提供可行思想!

出0入0汤圆

发表于 2010-8-7 00:12:28 | 显示全部楼层
论坛上有人回复

有过采样成14位或16位 后再来运算...

出0入0汤圆

发表于 2010-8-7 15:23:30 | 显示全部楼层
过采样

出0入0汤圆

发表于 2010-8-7 15:27:21 | 显示全部楼层
【4楼】 wangqh1983
------------------------------------------
“滑动平均"----就是这个意思, 我设想一个算法:

*   6.4k的采样频率, 取得8个AD值后平均AD值, AD_x=(AD0+AD1..+AD7)/8
*   AD_x 转换为显示值 disp_x

*   buf[pi++]=disp_x,   pi&=0x1f,   ----- 将这个disp_x值存入数组最后一位(不用移动数据, 只需改变指针)
*   disp_w = (buf1[0]+...buf[31)/32
*   显示 disp_w

   数据例子:  disp_x1=disp_x2....    =disp_x20=1000  ---->
               disp_x21=disp_x22......=disp_x32=1005  ---->   20个1000, 12个1005 数据跳变
   disp_w=(1000*20+1005*12)/32=1001.8 ------ 这个数跳变小一些

*  适当改变 参数 "32"  和 "8",  看一下什么数更合适


你的图画的很漂亮

出0入0汤圆

 楼主| 发表于 2010-8-7 17:22:53 | 显示全部楼层
回复【7楼】my2009
-----------------------------------------------------------------------

谢谢你的回复。我看明白了,你的方法是比方先用8个AD值平均,之后处理成显示的数据转存成32个缓冲区,进行递推!这个方法不错。我之前也用过N次AD值平均,之后在把N次结果进行递推但是效果不好。把显示值再进行处理是个不错的方法!
buf[pi++]=disp_x,   pi&=0x1f;这个语句很好。我一直都在用 pi %= 32;与语句应该更快些!3D模型模型只是业余爱好。其实对于某个行业使用的元器件不会太多。处理过一次,一劳永逸了。而其对于装配我觉得会给用户节省时间。

出0入0汤圆

发表于 2010-8-7 18:24:42 | 显示全部楼层
做假的显示也是容易的,以前也做过。
先采取低通滤波,取得最新测量值:
1、当测量值和上次显示值差距比较小,则显示值不变
2、当测量值和上次显示值差距适中,则显示值加1或者减1
3、当测量值和上次显示值差距比较大,则显示值=当前测量值,否则用户会怀疑,还认为反应速度慢
以上是3档处理,也可以多分几档。
经过处理,输入快速大变化,显示实时更新,当输入慢速变化,显示也慢速变化,输入不变,即使测量值有变化,
显示也基本稳定。

出0入0汤圆

发表于 2010-8-7 20:44:21 | 显示全部楼层
一价滤波也是不错的选择

出0入0汤圆

 楼主| 发表于 2010-8-7 21:44:54 | 显示全部楼层
回复【10楼】mcu5i51 学途浪子
-----------------------------------------------------------------------

不要只说名称啊,既然能说上两句,何不好人做到底提供/讲一下思想!欢迎大家多多讨论。俺是个拙人,愿洗耳恭听!或者坛里已有此类的回复;知道链接的方便的话贴出来……

出0入0汤圆

 楼主| 发表于 2010-8-9 07:22:22 | 显示全部楼层
帖子顶起来!高手们多多发表一下自己的看法;小弟愿闻其详……

出0入0汤圆

发表于 2010-8-9 11:19:10 | 显示全部楼层
假如跳动太大,可以让显示不一次性跳到目标值,可以分次进行,比如在2秒内逐步跳到目标值,每次幅度较小。(甚至可以考虑采用非均匀的跳动间隔,类似于图形动画中的那样,物体的移动不是匀速的)。
同时,可能在达到目标值之前,采样到了新的目标值没有那么大跳动,也就没有必要继续跳了。

出0入0汤圆

发表于 2010-8-9 11:38:51 | 显示全部楼层
我使用的方法和9楼的类似。

出0入0汤圆

 楼主| 发表于 2010-8-9 13:36:17 | 显示全部楼层
回复【7楼】my2009
-----------------------------------------------------------------------

*   buf[pi++]=disp_x,   pi&=0x1f;
这种缓冲累计方法,似乎只适合2的整数幂。 8 16 32 ……

出0入0汤圆

发表于 2010-8-9 16:13:06 | 显示全部楼层
大侠:我也在研究这个问题,我的比你跳的更厉害。

出0入0汤圆

发表于 2010-8-10 10:01:24 | 显示全部楼层
【15楼】 wangqh1983  
*   buf[pi++]=disp_x,   pi&=0x1f;
这种缓冲累计方法,似乎只适合2的整数幂。 8 16 32 ……
----------------------------------------
       缓冲区的长度, 肯定选2的整数幂, 并非是指针的问题,
       if (++pi>=20)   pi=0  --->  这样可以解决指针问题, 应该比 pi %= 20 效果好
       但求平均值呢?
           平均值1 = (n0+n1+...n19)/20    ------------ 这个可够费时的
           平均值2 = (n0+n1+...n31) >> 5  ------------ 简单

出0入0汤圆

发表于 2010-8-10 10:52:53 | 显示全部楼层
记得有个低通的方法
a是最新的ADC值 b是输出值
b=a*0.001+b*0.999

出0入0汤圆

发表于 2010-8-10 11:55:29 | 显示全部楼层
LZ你显示的AltiumDesinger的图片是实时3D显示吗?元件的3D模型是库带的还是自己做的啊?很漂亮啊!我的实时3D显示只有焊盘,没有3D效果呢。尤其是最后一张,怎么调整3快板的横竖放置位置组合到一块啊?希望能跟你学习一下,谢谢!

出0入0汤圆

 楼主| 发表于 2010-8-10 12:48:02 | 显示全部楼层
回复【17楼】my2009
-----------------------------------------------------------------------

恩的确,领教了,pi&=0x1f;采用2的整数幂不但缓冲累计方法合适,对平均时也是有利的!

出0入0汤圆

 楼主| 发表于 2010-8-10 13:12:46 | 显示全部楼层
回复【19楼】dragonwww
-----------------------------------------------------------------------

当然是实时的3D效果,看光标的手形就能知道;运行起来感觉比导入到SolidWorks里快得多。目前我还不怎么会做,多是下载的模型,有的自己稍作修改;目前正在看SolidWorks的教程。简单的还能应付;要想画的漂亮估计还得摸索一段……。最后一张图是把上面的PCB用Altium另存为step就可以了,之后再分别添加到另一块PCB中查看安装是否合适。我仔细校验过导出来的模型尺寸分毫不差!

(原文件名:2010-8-10 12-58-51.png)


(原文件名:2010-8-10 12-53-38.png)

出0入0汤圆

 楼主| 发表于 2010-8-10 13:33:56 | 显示全部楼层
回复【16楼】jacky1982512
-----------------------------------------------------------------------

我的跳字是完全正常的。用安捷伦34401A 测AD输入信号电压有<0.6mv的临界值漂移。也就是说±0.2mv左右,debug下AD值也是±1个字。跳动±5.2个字原因是乘的系数与12位AD所决定的!我的目的是让用户看着舒服一些,别一下就跳5个字。让他一个字一个字的跳上去,在一个字一个字的落下来,给人一种温漂的感觉。我认为my2009方法可行!等新做的板子回来马上测试!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-8 16:01

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表