六、数显
0——9999显示
程序介绍:利用S51的串行口功能,实现数码管0—
—9999 的循环显示。实际应用例如:电子计分牌。
程序实例(9999.ASM):
ORG 0000H
MAIN:
GEE EQU 30H
SHI EQU 31H
BEI EQU 32H
QIAN EQU 33H ;定义个十百千
MOV GEE,#00H
MOV SHI,#00H
MOV BEI,#00H
MOV QIAN,#00H ;赋初值
MOV SCON,#00H ;串行口工作于方式
0.同步移位
;显示个,十,百,千//////////////////////////////////
DISPLAY:
ACALL DELAY ;延时
MOV DPTR,#SETTAB
MOV A,GEE
MOVC A,@A+DPTR
MOV SBUF,A
D1: JNB TI,D1
17
CLR TI
MOV DPTR,#SETTAB
MOV A,SHI
MOVC A,@A+DPTR
MOV SBUF,A
D2: JNB TI,D2
CLR TI
MOV DPTR,#SETTAB
MOV A,BEI
MOVC A,@A+DPTR
MOV SBUF,A
D3: JNB TI,D3
CLR TI
MOV DPTR,#SETTAB
MOV A,QIAN
MOVC A,@A+DPTR
MOV SBUF,A
D4: JNB TI,D4
CLR TI
;/////////////////////////////////////////////
;个,十,百,千的依次加一/////////////////////
INC GEE
MOV A,GEE
CJNE A,#0AH,DISPLAY
MOV GEE,#00H
INC SHI
MOV A,SHI
CJNE A,#0AH,DISPLAY
18
MOV SHI,#00H
INC BEI
MOV A,BEI
CJNE A,#0AH,DISPLAY
MOV BEI,#00H
INC QIAN
MOV A,QIAN
CJNE A,#0AH,DISPLAY
MOV QIAN,#00H
AJMP DISPLAY
;//////////////////////////////////////////////////
;延时//////////////////////////////////////////////
DELAY: MOV R1,#0FFH
E1: MOV R2,#0FFH
DJNZ R2,$
DJNZ R1,E1
RET
;/////////////////////////////////////////////
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,
F6H,0EEH,3EH,9CH,7AH,9EH,8EH ;数显代码
END
七、AD 转换
7.1 AD转换(数码显示)
程序介绍:利用ADC0809模拟通道3输入电压,经单片机
19
处理后在数码管上用相对应的16进制数显示出来,0—5V对
应为0--0FFH,实际应用例如:数据采集。
程序操作:程序写完上电运行后,用本机配带的专用起微调
图15所示电位器,会在数码管上看到随不同电压而变化的对
应16进制值。也可以用
万用表实ADC0809IN3脚
电压,来检验所对应显
示的16进制数。
图15
程序实例(ad.asm):
ORG 0000H
MAIN1:
ACALL DELAY ;延时
ACALL AD ;呼叫AD子程序
;将转换的数字量屏蔽高位低位送显////////////////////
MOV 31H,30H
MOV A,30H
ANL A,#0FH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D1: JNB TI,D1
CLR TI
;//////////////////////////////////////////////////
;将转换的数字量屏蔽低位高位送显////////////////////
MOV A,30H
20
ANL A,#0F0H
SWAP A
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D2: JNB TI,D2
CLR TI
;//////////////////////////////////////////////////
AJMP MAIN1 ;返回主程序
AD: MOV DPTR,#7F00H ;指向转换地址
MOV A,#03H ;指向转换口
MOVX @DPTR,A ;转换
MOV R1,#64H
D3: DJNZ R1,D3 ;等100微秒转换完
MOVX A,@DPTR ;转换后的值给A
MOV 30H,A ;转换的值给30H
RET
DELAY: ;延时
MOV R2,#0FFH
D14: MOV R3,#0FFH
D12: DJNZ R3,D12
DJNZ R2,D14
RET
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH
21
7.2 十六进制两位数加法器(数码显示)
程序介绍:将ADC0809输入的两个不同电压(相同电
压也可相加,只是为举例说明,所以取不同电压)所对应
的16进制数相加显示出来。实际应用例如:取代加法运放
电路。
程序操作:程序写完上电运行后,用本机配带的钟表
起微调图16所示电位器,输入两个不同电压,数码管会显
示两个不同的对应16进制数,随后数码管会显示两个16
进制数相加的值。
程序实例(add2.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
;赋初值////////////////////////////////////////////
MOV ADDHOLD,#00H
MOV ADDNUMBER,#00H
MOV ADL,#00H
MOV ADH,#00H
MOV DISL,#00H
22
MOV DISH,#00H
MOV ADDJW,#00H
MOV ADDTOTAL,#00H
;//////////////////////////////////////////////////
MAIN1:
ACALL AD ;呼叫AD子程序
ACALL DELAY ;延时
ACALL CAIFEN ;呼叫AD值拆分为高
低的程序
ACALL DISPLAY ;呼叫显示子程序
MOV A,ADNUMBER ;取AD值
CJNE A,ADDHOLD,ADD3 ;与上次AD值比
较,不相等,即输入了新的AD值,去AD3执行
AJMP MAIN1 ;是相等的,证
明没有输入新的AD值,回去显示老的AD值
ADD3: MOV A,ADDHOLD
CJNE A,#00H,ADD4
MOV ADDHOLD,ADNUMBER ;有一种情况就
是是第一次进来,AD保持值里面是放的初值00,与取的AD值
不同,是这种情况,也返回去
AJM MAIN1
ADD4: MOV ADDNUMBER,ADDHOLD ;是真的输入
了新的AD值,将上次AD值给加数,为调加法程序做准备
MOV ADDHOLD,ADNUMBER ;将这次的AD
值也保持起来。准备与上一个AD值相加
;显示这次输入的AD值////////////////////////////////
ACALL DELAY
ACALL CAIFEN
23
ACALL DISPLAY
;//////////////////////////////////////////////////
DISPLAY1:
ACALL DELAY ;延时
ACALL ADD1 ;呼叫加法子程序
ACALL DISPLAY ;显示
LOOP: AJMP LOOP ;返回主程序
;///////////////////////////////////////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值程序//////////////////////////////////////
CAIFEN:
MOV A,ADNUMBER
ANL A,#0FH
MOV ADL,A ;取低位
MOV A,ADNUMBER
ANL A,#0F0H
SWAP A
MOV ADH,A ;取高位
MOV DISL,ADL
24
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
MOVC A,@A+DPTR
MOV SBUF,A
D5: JNB TI,D5
CLR TI
MOV SBUF,#00H
D6: JNB TI,D6
CLR TI
RET
;//////////////////////////////////////////////////
25
;加法程序//////////////////////////////////////////
ADD1:
CLR C
MOV A,ADDNUMBER ;取上次AD值
ADDC A,ADDHOLD ;与这次AD值相加
MOV ADDTOTAL,A ;将此次加的值给和
值
JNC ADDJW1 ;有无进位?
INC ADDJW ;有进位,进位值给
ADDJW
ADDJW1: ANL A,#0FH
MOV DISL,A ;加值取低位
MOV A,ADDTOTAL
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,
26
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH
END
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
7.33 求减去最大和最小值后的值(数码显示)
程序实例(add62.asm)
ORG 0000H
MAIN:
ADNUMBER EQU 30H ;AD转换值
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
ADH1 EQU 41H ;AD中最大的值
40
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
MOV ADHOLDH,#00H
MOV FOUR,#00H
MOV ADHOLDL,#00H
MOV JWHOLD,#00H
MOV SUB,#00H
;//////////////////////////////////////////////////
MAIN1:
ACALL DELAY
ACALL DELAY
41
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
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL CAIFEN1 ;拆最小值
ACALL CAIFEN2 ;拆最大值
ACALL DISPLAY ;显示最大值最小值
ACALL DELAY
42
ACALL DELAY
ACALL JIAN1 ;呼叫减最大值最小
值程序
ACALL CAIFEN3 ;拆分
ACALL DISPLAY ;显示减去最大值最
小值后的值
ACALL DELAY
ACALL DELAY
ACALL DELAY
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
43
;//////////////////////////////////////////////////
;拆分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
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
44
MOV A,ADDJW
MOV DPTR,#SETTAB
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
45
SWAP A
MOV DISH,A ;加值取高位
RET
;/////////////////////////////////////////////////
;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
46
RE1: RET
;//////////////////////////////////////////////////
;分解AD最小值的个,十位////////////////////////////
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
47
;//////////////////////////////////////////////////
;分解减去最高位和最低位的数////////////////////////
CAIFEN3:
MOV A,SUB
ANL A,#0FH
MOV ADL,A
MOV A,SUB
ANL A,#0F0H
SWAP A
MOV ADH,A
MOV DISL,ADL
MOV DISH,ADH
RET
;//////////////////////////////////////////////////
;减去最高位和最低位////////////////////////////////
JIAN1:
MOV FOUR,#00H
MOV ADDJW,JWHOLD
MOV A,ADDHOLD ;取和值
CLR C
SUBB A,ADH1 ;减最高位
JNC JIAN2
DEC ADDJW ;有进位,高位减一
JIAN2:
CLR C
SUBB A,ADL1 ;减低位
JNC TUI ;无进位出去,有进
位高位减一
48
DEC ADDJW
TUI: MOV SUB,A ;取减的值给SUB
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.34 除4所得软件滤波值(数码显示)
程序实例(add63.asm):
ORG 0000H
MAIN:
ADNUMBER EQU 30H ;AD转换值
ADL EQU 32H ;//
ADH EQU 33H ;ADL转换高低位值
DISL EQU 34H ;//
49
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
MOV ADHOLDH,#00H
MOV FOUR,#00H
50
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
ACALL DELAY
ACALL DELAY
51
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL CAIFEN1 ;拆最小值
ACALL CAIFEN2 ;拆最大值
ACALL DISPLAY ;显示最大值最小值
ACALL DELAY
ACALL DELAY
ACALL JIAN1 ;呼叫减最大值最小值程序
ACALL CAIFEN3 ;拆分
ACALL DISPLAY ;显示减去最大值最小值后的
值
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL LUBO ;滤波程序
ACALL DELAY
ACALL CAIFEN3
ACALL DISPLAY ;显示
LOOP: AJMP LOOP
;判有没有来新AD值,没有显示以前,有显示现在的///////
MAIN2:
ACALL DELAY
ACALL AD
MOV A,ADNUMBER
CJNE A,ADDTOTAL,MAIN3
AJMP MAIN2
;//////////////////////////////////////////////////
52
;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值程序//////////////////////////////////
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
53
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
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
54
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
;//////////////////////////////////////////////////
;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:
55
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最小值的个,十位////////////////////////////
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
56
MOV ADL,A ;取低位
MOV A,ADH1
ANL A,#0F0H
SWAP A
MOV ADH,A ;取高位
MOV JWHOLD,ADDJW
MOV ADDJW,ADL
MOV FOUR,ADH ;给显示值
RET
;//////////////////////////////////////////////////
;分解减去最高位和最低位的数////////////////////////
CAIFEN3:
MOV A,SUB
ANL A,#0FH
MOV ADL,A
MOV A,SUB
ANL A,#0F0H
SWAP A
MOV ADH,A
MOV DISL,ADL
MOV DISH,ADH
RET
;//////////////////////////////////////////////////
;减去最高位和最低位////////////////////////////////
JIAN1:
MOV FOUR,#00H
MOV ADDJW,JWHOLD
MOV A,ADDHOLD ;取和值
57
CLR C
SUBB A,ADH1 ;减最高位
JNC JIAN2
DEC ADDJW ;有进位,高位减一
JIAN2:
CLR C
SUBB A,ADL1 ;减低位
JNC TUI ;无进位出去,有进位高位
减一
DEC ADDJW
TUI: MOV SUB,A ;取减的值给SUB
RET
;//////////////////////////////////////////////////
;滤波//////////////////////////////////////////////
LUBO:
;除2//利用二进制右移位来实现///////////////////////
CLR C
MOV A,ADDJW
RRC A
MOV ADDJW,A
MOV A,SUB
RRC A
MOV SUB,A
;//////////////////////////////////////////////////
;再除一次2,达到除4的效果//// //////////////////////
CLR C
MOV A,ADDJW
RRC A
58
MOV ADDJW,A
MOV A,SUB
RRC A
MOV SUB,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.4过程检定
程序介绍(7.41—7.43):本程序用软件模拟了一个振
动传感器软件搜频的全过程。振动传感器是通过在激励端
给传感器一定频率的电压,在感应端感应一定频率的电压
值。所以它能测很多东西,比如不同的压力所感应不同电
压值,不同油品粘度也可以感应不同电压值,等等。但是
59
这存在一个问题?就是传感器何时才能达到谐振状态呢,
于是这就要给激励端变化的频率来测感应端的电压,感应
端的电压在这个变化频率内何时最大,这时所给的频率就
是所搜到的谐振频率。以前没有单片机软件控制时,我们
只能通过硬件不断的给激励端变化频率电压,然后测感应
端电压,来搜到谐振频率。7.41是在p1.0口输出并显示变
化的频率200-250hz(省略了2的显示),7.42在7.41的基础
上增加了AD输入量的显示。
7.43将会在您输入变化AD值后,将搜到的AD值与
频率值显示出来。实际应用如压力检测,粘度检测。
程序操作:因为7.41和7.42只是7.43的铺垫。所以在
将7.43程序写入并上电后,您将会在数码管左两位看到
200-250HZ变化频率的显示(省略2),右边看到输入AD
值的显示。您可以用钟表起微调AD输入的电位器,使AD
值上升,下降。在变化频率显示完后,程序将会把您所输
入的最大的AD值与其所对应的频率一起显示出来,这就是
软件模拟的全过程。
7.41 P1.0口产生200——250HZ变化频率输出(数
码显示)
程序实例(f25dis.asm):
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP DIN1
MAIN:
;定义频率200和300//////////////////////////////////
F2H EQU 30H
60
F2L EQU 31H
F3H EQU 32H
F3L EQU 33H
;/////////////////////////////////////////////////
DISFLAG EQU 34H ;显示标志
DISL EQU 35H ;显示低位
DISH EQU 36H ;显示高位
;定义频率保持初值//////////////////////////////////
MOV R1,#50
MOV R2,#02H
;//////////////////////////////////////////////////
;显示赋初值////////////////////////////////////////
MOV DISFLAG,#00H
MOV DISL,#00H
MOV DISH,#00H
;//////////////////////////////////////////////////
;频率赋初值////////////////////////////////////////
MOV F2H,#0F6H
MOV F2L,#3BH
MOV F3H,#0F8H
MOV F3L,#2FH
;/////////////////////////////////////////////////
CLR P1.0 ;在P1.0口产生一个低电
平,一个脉冲是由一个高电平和一个低电平组成的
MOV TMOD,#00010000B;定时器工作于方式1
MOV TH1,F2H
MOV TL1,F2L ;200HZ输出
SETB EA ;开总中断
61
SETB TR1 ;开定时器1运行
SETB ET1 ;开定时器1允许
DISPLAY:
MOV SBUF,#00H
D1: JNB TI,D1
CLR TI
MOV SBUF,#00H
D2: JNB TI,D2
CLR TI
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
ACALL DELAY
AJMP DISPLAY
LOOP: AJMP LOOP
DIN1:
CPL P1.0 ;取反P1.0口,实际是为了不断
的将p1.0的电平关系转换,即产生了频率
;频率保持时间//////////////////////////////////////
62
DJNZ R1,RE
MOV R1,#50
DJNZ R2,RE
MOV R2,#02H
;//////////////////////////////////////////////////
INC DISFLAG
MOV A,DISFLAG
CJNE A,#0AH,FF
MOV DISFLAG,#00H
INC DISL
MOV A,DISL
CJNE A,#0AH,FF
MOV DISL,#00H
INC DISH
;/////////////////////////////////////////////////
FF: MOV A,F2H
CJNE A,F3H,XIA ;频率高位到300HZ的高位
了吗?
AJMP JIA
;频率高位没到300HZ的高位值,直接将低位值加1///////
XIA: INC F2L
MOV A,F2L
CJNE A,#00H,RE
INC F2H
MOV A,F2H
CJNE A,F3H,RE
;//////////////////////////////////////////////////
;频率高位加到300HZ的高位值了,低位加一,到300HZ的低
63
位值了吗,没到出去,到了关定时器///////////////////
JIA:
INC F2L ;到了将200HZ频率的低位加1
MOV A,F2L
CJNE A,#F3L,RE
CLR TR1
;//////////////////////////////////////////////////
RE:
MOV TH1,F2H
MOV TL1,F2L
RETI
DELAY:
MOV R3,#0FFH
D5: DJNZ R3,D5
RET
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH ;数显代码
END
7.42 在显示频率输出的同时显示AD值(数码显示)
程序实例(ad25dis.asm):
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP DIN1
MAIN:
64
;定义频率200和300//////////////////////////////////
F2H EQU 30H
F2L EQU 31H
F3H EQU 32H
F3L EQU 33H
;//////////////////////////////////////////////////
DISFLAG EQU 34H ;显示标志
DISL EQU 35H ;显示低位
DISH EQU 36H ;显示高位
ADNUMBER EQU 37H ;AD值
DISADL EQU 38H ;显示AD低位
DISADH EQU 39H ;显示AD高位
;定义频率保持初值//////////////////////////////////
MOV R1,#100
MOV R2,#02H
;//////////////////////////////////////////////////
MOV ADNUMBER,#00H ;AD转换数初值
;显示高低位初值///////////////////////////////
MOV DISADL,#00H
MOV DISADH,#00H
;//////////////////////////////////////////////////
;显示赋初值////////////////////////////////////////
MOV DISFLAG,#00H
MOV DISL,#00H
MOV DISH,#00H
;//////////////////////////////////////////////////
;频率赋初值////////////////////////////////////////
MOV F2H,#0F6H
65
MOV F2L,#3BH
MOV F3H,#0F8H
MOV F3L,#2FH
;//////////////////////////////////////////////////
CLR P1.0 ;在P1.0口产生一
个低电平,一个脉冲是由一个高电平和一个低电平组成的
MOV TMOD,#00010000B;定时器工作于方
式1
MOV TH1,F2H
MOV TL1,F2L ;200HZ输出
SETB EA ;开总中断
SETB TR1 ;开定时器1运行
SETB ET1 ;开定时器1允许
ADDIS:
ACALL AD ;呼叫AD子程序
;将转换的数字量屏蔽高位低位送DISADL保存////////////
MOV A,ADNUMBER
ANL A,#0FH
MOV DISADL,A
;//////////////////////////////////////////////////
;将转换的数字量屏蔽低位,将高位送DISADH保存////////
MOV A,ADNUMBER
ANL A,#0F0H
SWAP A
MOV DISADH,A
;//////////////////////////////////////////////////
DISPLAY:
MOV A,DISADL
66
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D1: JNB TI,D1
CLR TI
MOV A,DISADH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D2: JNB TI,D2
CLR TI
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
ACALL DELAY
AJMP ADDIS
LOOP: AJMP LOOP
DIN1:
PUSH ACC
67
CPL P1.0 ;取反P1.0口,实际是为了
不断的将p1.0的电平关系转换,即产生了频率
;频率保持时间//////////////////////////////////////
DJNZ R1,RE
MOV R1,#100
DJNZ R2,RE
MOV R2,#02H
;//////////////////////////////////////////////////
INC DISFLAG
MOV ` A,DISFLAG
CJNE A,#0AH,FF
MOV DISFLAG,#00H
INC DISL
MOV A,DISL
CJNE A,#0AH,FF
MOV DISL,#00H
INC DISH
;//////////////////////////////////////////////////
FF: MOV A,F2H
CJNE A,F3H,XIA ;频率高位到300HZ的高位
了吗?
AJMP JIA
;频率高位没到300HZ的高位值,直接将低位值加1///////
XIA: INC F2L
MOV A,F2L
CJNE A,#00H,RE
INC F2H
MOV A,F2H
68
CJNE A,F3H,RE
;//////////////////////////////////////////////////
;频率高位加到300HZ的高位值了,低位加一,到300HZ的低
位值了吗,没到出去,到了关定时器///////////////////
JIA:
INC F2L ;到了将200HZ频率的低位
加1
MOV A,F2L
CJNE A,#F3L,RE
CLR TR1
;//////////////////////////////////////////////////
RE:
MOV TH1,F2H
MOV TL1,F2L
POP ACC
RETI
AD: MOV DPTR,#7F00H ;指向转换地址
MOV A,#03H ;指向转换口
MOVX @DPTR,A ;转换
MOV 40H,#64H
D6: DJNZ 40H,D6 ;等100微秒转换完
MOVX A,@DPTR ;转换后的值给A
MOV ADNUMBER,A ;转换的值给30H
RET
DELAY:
MOV R3,#0FFH
D5: DJNZ R3,D5
RET
69
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH ;数显代码
END