|

楼主 |
发表于 2009-3-10 13:41:11
|
显示全部楼层
7.3 软件滤波
程序介绍(7.31—7.34):您如果接触过模电就知道,
在采集电压量时经常会碰到干扰,而在模电中经常所采用
的方法就是加电容滤波,这是用硬件实现的。实际上软件
完全可以达到滤波的效果,现在介绍的是一种最经典的方
法。在一次电压量的采集中,在很短的时间内对它进行6
次采集,将它转换为数字量后求和(7.31),分析出6次
输入中的最大值和最小值(7.32),然后减去最大值和最
小值(7.33),除以4(7.44)得到平均值。这样实际上
就完成了一次软件滤波。省去了复杂的硬件,而且取得了
好而精确的效果。实际应用例如:精确数据采集。
程序操作:程序写入上电运行后,用本实验仪自带的
钟表起微调电位器依次输入6个电压量。7.31程序会显示
和值,7.32会继续显示最大和最小值,7.33程序会继续显
示减后所剩的值,7.34程序会继续显示除4后的值。
算法说明:为什么要选择取6个数进行计算呢?因为
在汇编中做计算是非常麻烦的,取6个数,减去最大值和
最小值后,取平均值是除4.计算机的内部计算都是二进
制,而二进制每除一个2,实际上是向右移一次。所以为
了计算方便,我们选择取6个数,最后在算除法的时候,
只需要用单片机自带的右移位命令移2次就行了。
27
7.31 十六进制六位数加法(数码显示)
程序实例(add6.asm):
ORG 0000H
MAIN:
ADNUMBER EQU 30H ;AD转换值
ADDNUMBER EQU 31H ;加数值1
ADL EQU 32H ;//
ADH EQU 33H ;ADL转换高低位值
DISL EQU 34H ;//
DISH EQU 35H ;显示高低位值
ADDTOTAL EQU 36H ;第一次AD转换值
ADDJW EQU 37H ;加法进位数
ADDHOLD EQU 38H
ADDFLAG EQU 39H ;加标志
ENDFLAG EQU 40H
;赋初值////////////////////////////////////////////
MOV ADDHOLD,#00H
MOV ADDNUMBER,#00H
MOV ADL,#00H
MOV ADH,#00H
MOV DISL,#00H
MOV DISH,#00H
MOV ADDJW,#00H
MOV ADDFLAG,#00H
MOV ENDFLAG,#00H
MOV ADDTOTAL,#00H
;//////////////////////////////////////////////////
MAIN1:
28
;显示AD值//////////////////////////////////////////
ACALL DELAY
ACALL DELAY
ACALL AD
MAIN3:
ACALL CAIFEN
ACALL DISPLAY
;//////////////////////////////////////////////////
;加这次的AD值,并判是否加了六次,是的话就进入死循环
ACALL DELAY
ACALL ADD1
ACALL DISPLAY
INC ADDFLAG
MOV A,ADDFLAG
CJNE A,#06H,MAIN2
LOOP: AJMP LOOP
;//////////////////////////////////////////////////
;没有加到六次,继续取值加,如果没有来新AD值,还是去
显示上次加的值,有新AD值来了,显示这次AD值,并加上上
次AD值,显示///////////////////////////////////////
MAIN2: ACALL DELAY
ACALL AD
MOV A,ADNUMBER
CJN A,ADDTOTAL,MAIN3
AJM MAIN2
;//////////////////////////////////////////////////
;////////////////////////////////////////////AD转换
AD:
29
MOV DPTR,#7F00H ;指向转换地址
MOV A,#03H ;指向转换口
MOVX @DPTR,A ;转换
MOV R1,#64H
D1: DJNZ R1,D1 ;等100微秒转换完
MOVX A,@DPTR ;转换后的值给A
MOV ADNUMBER,A ;转换的值给30H
RET
;//////////////////////////////////////////////////
;拆分AD值程序//////////////////////////////////////
CAIFEN:
MOV A,ADNUMBER
ANL A,#0FH
MOV ADL,A ;取低位
MOV A,ADNUMBER
ANL A,#0F0H
SWAP A
MOV ADH,A ;取高位
MOV DISL,ADL
MOV DISH,ADH ;给显示值
RET
;//////////////////////////////////////////////////
;显示//////////////////////////////////////////////
DISPLAY:
MOV A,DISL
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
30
D3: JNB TI,D3
CLR TI
MOV A,DISH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D4: JNB TI,D4
CLR TI
MOV A,ADDJW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D5: JNB TI,D5
CLR TI
MOV SBUF,#00H
D6: JNB TI,D6
CLR TI
RET
;//////////////////////////////////////////////////
;加法程序//////////////////////////////////////////
ADD1:
CLR C
MOV ADDTOTAL,ADNUMBER
MOV A,ADNUMBER
ADDC A,ADDHOLD
MOV ADDHOLD,A
JNC ADDJW1
INC ADDJW
31
ADDJW1: ANL A,#0FH
MOV DISL,A ;加值取低位
MOV A,ADDHOLD
ANL A,#0F0H
SWAP A
MOV DISH,A ;加值取高位
RET
;///////////////////////////////////////////////
DELAY: ;延时
MOV R3,#0AH
DD1: MOV R1,#0FFH
D2 : MOV R2,#0FFH
DJNZ R2,$
DJNZ R1,D2
DJNZ R3,DD1
RET
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH
END
7.32 求六位和中的最大值和最小值(数码显示)
程序实例(add61.asm):
ORG 0000H
MAIN:
ADNUMBER EQU 30H ;AD转换值
ADL EQU 32H ;//
32
ADH EQU 33H ;ADL转换高低位值
DISL EQU 34H ;//
DISH EQU 35H ;显示高低位值
ADDTOTAL EQU 36H ;第一次AD转换值
ADDJW EQU 37H ;加法进位数
ADDHOLD EQU 38H
ADDFLAG EQU 39H ;加标志
ENDFLAG EQU 40H
ADH1 EQU 41H ;AD中最大的值
ADL1 EQU 42H ;AD中最小的值
ADHOLDH EQU 43H
ADHOLDL EQU 44H ;求AD最大值与最小
值时AD的比较值,即以此两个值为比较中转
FOUR EQU 45H
SUB EQU 46H ;减去高低位后的值
JWHOLD EQU 47H ;保存进位值
;赋初值////////////////////////////////////////////
MOV ADDHOLD,#00H
MOV ADL,#00H
MOV ADH,#00H
MOV DISL,#00H
MOV DISH,#00H
MOV ADDJW,#00H
MOV ADDFLAG,#00H
MOV ENDFLAG,#00H
MOV ADDTOTAL,#00H
MOV ADH1,#00H
MOV ADL1,#00H
33
MOV ADHOLDH,#00H
MOV FOUR,#00H
MOV ADHOLDL,#00H
MOV JWHOLD,#00H
MOV SUB,#00H
;//////////////////////////////////////////////////
MAIN1:
ACALL DELAY
ACALL DELAY
ACALL AD ;取AD值
MAIN3: ACALL CAIFEN
ACALL DISPLAY ;显示
ACALL DELAY
ACALL DELAY
;算最大值和最小值//////////////////////////////////
ACALL ADDH
ACALL ADDL
;//////////////////////////////////////////////////
;加和值显示///////////////////////////////////////
ACALL ADD1
ACALL DISPLAY
;//////////////////////////////////////////////////
;判是否加到了6次///////////////////////////////////
INC ADDFLAG
MOV A,ADDFLAG
CJNE A,#06H,MAIN2
;/////////////////////////////////////////////////
ACALL DELAY
34
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL CAIFEN1 ;拆最小值
ACALL CAIFEN2 ;拆最大值
ACALL DISPLAY ;显示最大值最小值
LOOP: AJMP LOOP
;判有没有来新AD值,没有显示以前,有显示现在的///////
MAIN2:
ACALL DELAY
ACALL AD
MOV A,ADNUMBER
CJNE A,ADDTOTAL,MAIN3
AJMP MAIN2
;//////////////////////////////////////////////////
;AD转换////////////////////////////////////////////
AD: MOV DPTR,#7F00H ;指向转换地址
MOV A,#03H ;指向转换口
MOVX @DPTR,A ;转换
MOV R1,#64H
D1: DJNZ R1,D1 ;等100微秒转换完
MOVX A,@DPTR ;转换后的值给A
MOV ADNUMBER,A ;转换的值给30H
RET
;//////////////////////////////////////////////////
;拆分AD值程序//////////////////////////////////////
35
CAIFEN:
MOV A,ADNUMBER
ANL A,#0FH
MOV ADL,A ;取低位
MOV A,ADNUMBER
ANL A,#0F0H
SWAP A
MOV ADH,A ;取高位
MOV DISL,ADL
MOV DISH,ADH ;给显示值
RET
;//////////////////////////////////////////////////
;显示//////////////////////////////////////////////
DISPLAY:
MOV A,DISL
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D3: JNB TI,D3
CLR TI
MOV A,DISH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D4: JNB TI,D4
CLR TI
MOV A,ADDJW
MOV DPTR,#SETTAB
36
MOVC A,@A+DPTR
MOV SBUF,A
D5: JNB TI,D5
CLR TI
MOV A,FOUR
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D6: JNB TI,D6
CLR TI
RET
;////////////////////////////////////////////////
;加法程序////////////////////////////////////////
ADD1:
CLR C
MOV ADDTOTAL,ADNUMBER
MOV A,ADNUMBER
ADDC A,ADDHOLD
MOV ADDHOLD,A
JNC ADDJW1
INC ADDJW
ADDJW1: ANL A,#0FH
MOV DISL,A ;加值取低位
MOV A,ADDHOLD
ANL A,#0F0H
SWAP A
MOV DISH,A ;加值取高位
RET
37
;//////////////////////////////////////////////////
;AD值中的最大值////////////////////////////////////
ADDH:
MOV A,ADH1
CJNE A,#00H,ADDH1
MOV ADH1,ADNUMBER
AJMP RE
ADDH1: MOV A,ADNUMBER
CLR C
SUBB A,ADH1
JC RE
MOV ADH1,ADNUMBER
RE: RET
;//////////////////////////////////////////////////
;AD值中的最小值////////////////////////////////////
ADDL:
MOV A,ADL1
CJNE A,#00H,ADDL1
MOV ADL1,ADNUMBER
AJMP RE1
ADDL1: MOV A,ADNUMBER
CLR C
SUBB A,ADL1
JNC RE1
MOV ADL1,ADNUMBER
RE1: RET
;//////////////////////////////////////////////////
;分解AD最小值的个,十位////////////////////////////
38
CAIFEN1:
MOV A,ADL1
ANL A,#0FH
MOV ADL,A ;取低位
MOV A,ADL1
ANL A,#0F0H
SWAP A
MOV ADH,A ;取高位
MOV DISL,ADL
MOV DISH,ADH ;给显示值
RET
;/////////////////////////////////////////////
;分解AD最大值的个,十位///////////////////////
CAIFEN2:
MOV A,ADH1
ANL A,#0FH
MOV ADL,A ;取低位
MOV A,ADH1
ANL A,#0F0H
SWAP A
MOV ADH,A ;取高位
MOV JWHOLD,ADDJW
MOV ADDJW,ADL
MOV FOUR,ADH ;给显示值
RET
;//////////////////////////////////////////////////
DELAY: ;延时
MOV R3,#0AH
39
DD1: MOV R1,#0FFH
D2 : MOV R2,#0FFH
DJNZ R2,$
DJNZ R1,D2
DJNZ R3,DD1
RET
;//////////////////////////////////////////////////
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH
END |
|