矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 2603|回复: 5

请教单片机程序问题

[复制链接]
     
发表于 2018-5-29 10:55:50 | 显示全部楼层 |阅读模式
XJW01老师发表在仪表工专区的"6位半表头制作完成"一文,是初入门单片机的朋友进一步学习的好材料.可惜程序注释太少.故我在此发帖求教:
1)程序第67行void get_adc( ){   }中,通过for( )循环使V取得AD转换结果的32位数据.虽然在65行有#define en 5;但是get_adc()函数并未被执行5
次.在第81行:如本次采样值V跟上次采样值pv/en之差的绝对值大于经验值50,则抛弃本次采样值V,用上次采样值pv/en作为本次采样值,令
pv=v*en. 这里把一次采样值V扩大5倍作为"AD转换均值pv",而不是运行get_adc()5次,把各次读得的结果累加,再除以5得均值,是何原因?注意到
在T0中断等待时间内,第125行的无限循环while(1) {  }可能循环了5次,但是各次取得的V并未累加,怎么求5次平均值呢?

2)按照软件一阶滤波公式:  本次滤波输出=a*上次滤波输出 + (1-a)*本次采样输入,其中 a=RC/(RC+T).但是程序第82行是:
                                pv=v+pv-pv/en
如果赋值号右边的pv是上次滤波输出,那么a=?   跟公式对不上号.
                            恳请懂单片机的老师赐教!谢谢! 相关程序在附件里,请查看. get_adc()函数相关语句.txt (7.05 KB, 下载次数: 48)
     
 楼主| 发表于 2018-6-1 16:15:45 | 显示全部楼层
    这一阵我又反复研究电路图,自己有一些认识,不知道对不对,写出来请内行们指正.
1)查LTC2400,电路图里其8脚F0是接在VCC上的.这样,一次AD转换要160ms.此外还有限幅,一阶滤波,判断K1是否按下,负号的判断及显示等等,如此一来,执行
一次while()循环至少要200ms,循环5次就要1秒,因此真的把5次转换值累加再平均,仪器的反应就会比较迟钝.那么把一次转换值*5有什么用呢?由于AD转换时
输入信号里混杂着各种干扰,使得有些转换值会偏离正常值.扩大5倍,误差也随着被放大5倍,就容易用限幅语句抛弃那些偏差略大的转换值.再说,用一次T0中断使while(1)循环退出是不可能的:电路图中所用的晶振是32MHz,即使采用fosc/12做机器时钟,16位的T0溢出计数值是65536,那么一次T0中断仅需24.567ms
跟200ms相比小多了,因此如果不用多次循环,仅靠T0或是int0无法使while(1)循环停止的.

2)由一阶滤波公式可知:a=RC/(RC+T).要起滤波作用,则RC必须大于T.如果大得多,则a就接近1.把公式的括号展开:本次滤波结果=a*上次滤波结果+本次转换
值 - a*本次转换值.记赋值号左边的"本次滤波结果"为PV,第一个a取1,记右边"上次滤波结果"为PV, a*本次转换值要比本次转换值略小,就用上次转换值pv/en
来代替,这样得到:
                          PV=V+PV-PV/en
  不知这样的解释是否合理?请您发表看法,谢谢!


补充内容 (2018-8-4 08:54):
160ms应该是160μs吧,当时μ字不知道怎么打.
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2018-6-4 11:51:08 | 显示全部楼层
  在程序的91行有:void  zd0(void) interrupt0{    //int0中断,下降沿 }
                96行有:void  timerinter(void) interrupt1 {//T0中断     }
  可见这两个中断都没有处理程序.那么,设置这两个中断有什么用处呢?
注意到后来的电路图发生了变化:6只日字形的数码管变成了7只,原来只有1只K1,后来变成了4只.但是单片机的10-13脚仍然空着,其中12脚是INT0 .  K1--K4分别接在14--17脚上,其中14脚第二功能是T0,15脚的第二功能是T1.如此看来,后来的K1功能不再是最右一位是否显示的选择键,而应该是T0中断的输入信号,
则K1按下再松开,就应该执行T0中断处理程序.因此我想后来的K1键处理肯定不同于最初的了.附上后来的7只LED数码管的电路图供参考. 六位半数字表头最后增加共4个按键7只数码管的电路图.PNG
回复 支持 反对

使用道具 举报

     
发表于 2018-6-28 22:02:51 | 显示全部楼层
要是以前看到就会被吸引了,哇6位半的!现在感觉又不需要了,现在感觉用TLC1549与TLC5615就够了
回复 支持 反对

使用道具 举报

     
发表于 2018-6-28 22:19:15 | 显示全部楼层
没看懂问题,文字太多
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2018-7-14 18:23:59 | 显示全部楼层
程序第78行: if(!plo) v=0x20000000-v;

程序第79行: v=5000000.0*v/0x10000000;
我想78行里的plo是读取到AD转换的符号位,根据AD片的说明,0代表负数,取反后条件为真,读得的v按补码来计算.这里模为什么取32位呢,2400不是20位AD转换芯片吗?
如果读得的v是正数,就不执行78行的赋值语句,而执行79行.哪位能解释79行是什么意思吗?按照20位AD转换,参考电压是5伏,读得的v转换成电压值应该是:
v=v*5.0/0x100000吧?后来看到一个实物照片,5v在屏上显示成500000,由于该程序对应的是6只日字型LED数码管,那么是否应将v扩大100000倍而非
1000000倍?
将有行号的程序附于后,供核对.若能指点一二,则不胜感谢! XJW最初的六位半表程序有行号.txt (3.69 KB, 下载次数: 38) XJW的六位半表头却显示8位.jpg
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-4-25 23:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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