请教单片机程序问题
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=? 跟公式对不上号.
恳请懂单片机的老师赐教!谢谢! 相关程序在附件里,请查看. 这一阵我又反复研究电路图,自己有一些认识,不知道对不对,写出来请内行们指正.
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吧,当时μ字不知道怎么打. 在程序的91行有:voidzd0(void) interrupt0{ //int0中断,下降沿 }
96行有:voidtimerinter(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数码管的电路图供参考. 要是以前看到就会被吸引了,哇6位半的!现在感觉又不需要了,现在感觉用TLC1549与TLC5615就够了 没看懂问题,文字太多 程序第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倍?
将有行号的程序附于后,供核对.若能指点一二,则不胜感谢!
页:
[1]