科技的进步需要技术不断的提升。一块大而复杂的模拟电路花费了您巨大的精力,繁多的元器件增加了您的成本。而现在,只需要一块几厘米见方的单片机,写入简单的程序,就可以使您以前的电路简单很多。相信您在使用并掌握了单片机技术后,不管在您今后开发或是工作上,一定会带来意想不到的惊喜。
二、单片机简介
我国开始使用单片机是在1982 年,短短五年时间里发展极为迅速。1986 年在上海召开了全国首届单片机开发与应用交流会,有的地区还成立了单片微型计算机应用协会,那是全国形成的第一次高潮。截止今日,单片机应用技术飞速发展,我们上因特网输入一个“单片机”的搜索,将会看到上万个介绍单片机的网站,这还不包括国外的。与它相应的专业杂志现在也有很多,比如由单片机界的权威何立民主编的《单片机与嵌入式系统应用》杂志现以风靡电子界,在2003年7月,91student.com(91 猎头网)在上海、广州、北京等大城市所做的一次专业人才需求报告中,单片机人才的需求量位居第一。
一块小小的片子,为何有这样的魔力?
我们首先从它的构成说起:单片机,亦称单片微电脑或单片微型计算机。它是把中央处理器(CPU)、随机存取存储器(RAM)、只读存储器(ROM)、输入/输出端口
(I/0)等主要计算机功能部件都集成在一块集成电路芯片上的微型计算机。
计算机的产生加快了人类改造世界的步伐,但是它毕竟体积大。微计算机(单片机)在这种情况下诞生了,它为我们改变了什么?纵观我们现在生活的各个领域,从导弹的导航装置,到飞机上各种仪表的控制,从计算机的网络通讯与数据传输,到工业自动化过程的实时控制和数据处理,以及我们生活中广泛使用的各种智能IC 卡、电子宠物等,这些都离不开单片机。以前没有单片机时,这些 东西也能做,但是只能使用复杂的模拟电路,然而这样做出来的产品不仅体积大,而且成本高,并且由于长期使用,
元器件不断老化,控制的精度自然也会达不到标准。在单片机产生后,我们就将控制这些东西变为智能化了,我们只需要在单片机外围接一点简单的接口电路,核心部分只是由人为的写入程序来完成。这样产品的体积变小了,成本也降低了,长期使用也不会担心精度达不到了。所以,它的魔力不仅是在现在,在将来将会有更多的人来接受它、使用它。据统计,我国的单片机年容量已达1——3 亿片,且每年以大约16%的速度增长,但相对于世界市场我国的占有率还不到1%。特别是沿海地区的玩具厂等生产产品多数用到单片机,并不断地辐射向内地。所以,学习单片机在我国是有着广阔前景的。
学习单片机,推广单片机,做现代生活的领航人,你还在等什么呢?
① 流水灯② 数码显示
③ AD 转换④ 波形输出
⑤ 编程接口⑥ PC通讯接口
⑦ 遥控解码接收头⑧ 功能扩展插槽
⑨ 编程插座⑩ 程序运行插座
四、I/O 口功能实例
4.1 流水灯
程序介绍:利用P1 口通过一定延时轮流产生低电平输出,以达到发光二极管轮流亮的效果。实际应用中例如:广告灯箱彩灯、霓虹灯闪烁。
程序实例(LAMP.ASM)
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:
MOV A,#00H
MOV P1,A ;灭所有的灯
MOV A,#11111110B
MAIN1:
MOV P1,A ;开最左边的灯
ACALL DELAY ;延时
RL A ;将开的灯向右边移
AJMP MAIN ;循环
DELAY:
MOV 30H,#0FFH
D1: MOV 31H,#0FFH
D2: DJNZ 31H,D2
DJNZ 30H,D1
RET
END
4.2 方波输出
程序介绍:P1.0 口输出高电平,延时后再输出低电平,循环输出产生方波。实际应用中例如:波形发生器。
程序实例(FAN.ASM):
ORG 0000H
MAIN:;直接利用P1.0口产生高低电平地形成方波//
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.0
AJMP MAIN
;//
DELAY:
MOV R1,#0FFH
DJNZ R1,$
RET
END
五、定时器功能实例
5.1 定时1秒报警
程序介绍:定时器1每隔1秒钟将p1.o的输出状态改变1次,以达到定时报警的目的。实际应用例如:定时报警器。
程序实例(DIN1.ASM):
ORG 0000H
AJMP MAIN
ORG 000BH
AJMP DIN0 ;定时器0入口
MAIN:
TFLA G EQU 34H ;时间秒标志,判是否到50个0.2秒,即50*0.2=1秒
MOV TMOD,#00000001B;定时器0工作于方式1
MOV TL0,#0AFH
MOV TH0,#3CH ;设定时时间为0.05秒,定时20次则一秒
SETB EA ;开总中断
SETB ET0 ;开定时器0中断允许
SETB TR0 ;开定时0运行
SETB P1.0
LOOP: AJMP LOOP
DIN0:
;是否到一秒
INCC: INC TFLAG
MOV A,TFLAG
CJNE A,#20,RE
MOV TFLAG,#00H
CPL P1.0
;//
RE:
MOV TL0,#0AFH
MOV TH0,#3CH ;设定时时间为0.05秒,定时20次则一秒
RETI
END
5.2 频率输出公式
介绍:f=1/ts51 使用12M晶振,一个周期是1微秒使用定时器1工作于方式0,最大值为65535,以产生200HZ的频率为例:200=1/t:推出t=0.005 秒,即5000 微秒,即一个高电平或低电平的时间为2500 微秒。这样,定时值应设为65535-2500=63035,将它转换为十六进制则为:F63B。
具体程序请看f200.asm
频率递增:
200HZ:63035:F63B
250HZ:63535:F82F
300HZ:63868:F97C
5.3 200HZ频率输出程序介绍:利用定时器定时,在P1.0 口产生200HZ的频率输出。实际应用例如:传感器前级推动。
程序实例(F200.ASM):
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP DIN0
MAIN:
CLR P1.0 ;产生一个低电平,实际上是从p1.0口产生频率
MOV TMOD,#00010000B ;定时器1工作于方式0
MOV TH1,#0F6H
MOV TL1,#3BH ;频率产生的时间,详细请见频率公式
SETB EA ;开总中断
SETB TR1 ;开定时器1运行
SETB ET1 ;开定时器1允许
LOOP: AJMP LOOP ;无限循环
DIN0: CPL P1.0 ;产生一个高电平,
下次来就是低电平(因为取反),一个高电平和一个低电平形成一个周期
MOV TH1,#0F6H
MOV TL1,#3BH ;重置频率产生时间
RETI ;返回
END
5.4 200——250HZ变化频率输出
程序介绍:利用定时器定时时间的变化,由P1.0 口产生200——250HZ变化的频率。实际应用例如:传感器前级推动、频率发生器。
程序实例(F250.ASM):
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP DIN1
MAIN:
;定义频率200和300//
F2H EQU 30H
F2L EQU 31H
F3H EQU 32H
F3L EQU 33H
;//
;定义频率保持初值//
MOV R1,#50
MOV R2,#02H
;//
;频率赋初值
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 ;开总中断
SETB TR1 ;开定时器1运行
SETB ET1 ;开定时器1允许
LOOP: AJMP LOOP
DIN1:
CPL P1.0 ;取反P1.0口,实际是为了不断的将p1.0的电平关系转换,即产生了频率
;频率保持时间//
DJNZ R1,RE
MOV R1,#50
DJNZ R2,RE
MOV R2,#02H
;//
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的低位值了吗,没到出去,到了关定时器
JIA:
INC F2L ;到了将200HZ频率的低位加1
MOV A,F2L
CJNE A,#F3L,RE
CLR TR1
;/
RE:
MOV TH1,F2H
MOV TL1,F2L
RETI
END
六、数显
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
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
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输入电压,经单片机处理后在数码管上用相对应的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
7.43 过程检定(数码显示)
程序实例(search.asm):
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP DIN1
MAIN:
;定义频率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高位
ADTIME EQU 40H ;AD转换时间值
SCHNUMBER EQU 41H ;搜频比较值
HOLDADL EQU 42H
70
HOLDADH EQU 43H ;搜到的AD值
HOLDFL EQU 44H
HOLDFH EQU 45H ;搜到的频率值
;//
MOV SCHNUMBER,#00H
MOV HOLDADL,#00H
MOV HOLDADH,#00H
MOV HOLDFL,#00H
MOV HOLDFH,#00H ;赋初值
;/
;定义频率保持初值/
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
MOV F2L,#3BH
MOV F3H,#0F8H
71
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
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D1: JNB TI,D1
72
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
;过程检定,即模拟搜到极值//
MOV A,ADNUMBER
CLR C
SUBB A,SCHNUMBER ;取AD值与初值比较
JNC SW
;搜频是否完成,完成去显示搜到的值,没有继续搜//
MOV A,DISH
CJNE A,#05H,ADDIS1
73
MOV A,DISL
CJNE A,#00H,ADDIS1
AJMP DISSEARCH
;/
;始终将初值赋于最大值,并将此时的频率与AD值保存
SW: MOV SCHNUMBER,ADNUMBER
MOV HOLDADL,DISADL
MOV HOLDADH,DISADH
MOV HOLDFL,DISL
MOV HOLDFH,DISH
;/
CJNE A,#05H,ADDIS1
MOV A,DISL
CJNE A,#00H,ADDIS1
AJMP DISSEARCH
ADDIS1:
AJMP ADDIS
;搜到的频率与AD值显示/
DISSEARCH:
MOV A,HOLDADL
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D11: JNB TI,D11
CLR TI
MOV A,HOLDADH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
74
MOV SBUF,A
D12: JNB TI,D12
CLR TI
MOV A,HOLDFL
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D13: JNB TI,D13
CLR TI
MOV A,HOLDFH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D14: JNB TI,D14
CLR TI
;/
LOOP: AJMP LOOP
DIN1:
PUSH ACC
CPL P1.0 ;取反P1.0口,实际是为了不断的将
p1.0的电平关系转换,即产生了频率
;频率保持时间/
DJNZ R1,RE
MOV R1,#100
DJNZ R2,RE
MOV R2,#02H
;/
INC DISFLAG
75
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的低‘
位值了吗,没到出去,到了关定时器//
JIA:
INC F2L ;到了将200HZ频率的低位加1
MOV A,F2L
CJNE A,#F3L,RE
CLR TR1
76
;/
RE:
MOV TH1,F2H
MOV TL1,F2L
POP ACC
RETI
AD: MOV DPTR,#7F00H ;指向转换地址
MOV A,#03H ;指向转换口
MOVX @DPTR,A ;转换
MOV ADTIME,#64H
D6: DJNZ ADTIME,D6 ;等100微秒转换完
MOVX A,@DPTR ;转换后的值给A
MOV ADNUMBER,A ;转换的值给30H
RET
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
77
八、DA 转换
8.1 三角波
程序介绍:单片机通过DAC0832转换在LM358的7脚输出三角波。实际应用如:函数波形发生器。
程序实例(0832shan.asm):
ORG 0000H
MAIN:
MOV DPTR,#0BFFFH ;选通地址
STR1:
MOV R6,#00H
;通过上升和下降来产生三角波///
;电压随时间上升///
STR2: MOV A,R6
MOVX @DPTR,A
INC R6
CJNE R6,#0FFH,STR2
;/
;电压随时间下降///
STR3: DEC R6
MOV A,R6
MOVX @DPTR,A
CJNE R6,#00H,STR3
;/
AJMP STR1
END
78
8.2 方波
程序介绍:程序介绍:单片机通过DAC0832转换在LM358的7脚输出方波。实际应用如:函数波形发生器。
程序实例(0832fan.asm):
ORG 0000h
MAIN: MOV DPTR,#0BFFFH
;通过高低电平地的变化来输出方波///
LOOP1:
MOV A,0
MOVX @DPTR,A ;向选通地址送低电平地
ACALL DELAY
MOV A,#0FFH
MOVX @DPTR,A ;向选通地址送高电平
ACALL DELAY
AJMP LOOP1
;/
DELAY: MOV 30H,#0FFH ;延时,通过改变它的大小
可以改变占空比
D2: DJNZ 30H,D2
RET
END
8.3 正弦波
程序介绍:程序介绍:单片机通过DAC0832转换在LM358的7脚输出正弦波。实际应用如:函数波形发生器。
程序实例(0832xuan.asm):
ORG 000H
MAIN: MOV R1,#00H ;取表格初值
79
LOOP1:
;在表格里取数送到指定地址/
MOV A,R1
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV DPTR,#0BFFFH
MOVX @DPTR,A
;/
INC R1 ;表格加一
AJMP LOOP1 ;循环
SETTAB:
;正弦表格/
DB 80H,83H,86H,89H,8DH,90H,93H,96H
DB 99H,9CH,9FH,0A2H,0A5H,0A8H,0ABH,0AEH
DB 0B1H,0B4H,0B7H,0BAH,0BCH,0BFH,0C2H,0C5H
DB 0C7H,0CAH,0CCH,0CFH,0D1H, 0D4H,0D6H,0D8H
DB 0DAH,0DDH,0DFH,0E1H,0E3H, 0E5H,0E7H,0E9H
DB 0EAH,0ECH,0EEH,0EFH,0F1H, 0F2H,0F4H,0F5H
DB 0F6H,0F7H,0F8H,0F9H,0FAH, 0FBH,0FCH,0FDH
DB 0FDH,0FEH,0FFH,0FFH,0FFH, 0FFH,0FFH,0FFH
DB 0FFH,0FFH,0FFH,0FFH,0FFH, 0FFH,0FEH,0FDH
DB 0FDH,0FCH,0FBH,0FAH,0F9H, 0F8H,0F7H,0F6H
DB 0F5H,0F4H,0F2H,0F1H,0EFH, 0EEH,0ECH,0EAH
DB 0E9H,0E7H,0E5H,0E3H,0E1H, 0DEH,0DDH,0DAH
DB 0D8H,0D6H,0D4H,0D1H,0CFH, 0CCH,0CAH,0C7H
DB 0C5H,0C2H,0BFH,0BCH,0BAH, 0B7H,0B4H,0B1H
DB 0AEH,0ABH,0A8H,0A5H,0A2H, 9FH, 9CH, 99H
DB 96H, 93H, 90H, 8DH, 89H, 86H, 83H, 80H
80
DB 80H, 7CH, 79H, 78H, 72H, 6FH, 6CH, 69H
DB 66H, 63H, 60H, 5DH, 5AH, 57H, 55H, 51H
DB 4EH, 4CH, 48H, 45H, 43H, 40H, 3DH, 3AH
DB 38H, 35H, 33H, 30H, 2EH, 2BH, 29H, 27H
DB 25H, 22H, 20H, 1EH, 1CH, 1AH, 18H, 16H
DB 15H, 13H, 11H, 10H, 0EH, 0DH, 0BH, 0AH
DB 09H, 08H, 07H, 06H, 05H, 04H, 03H, 02H
DB 02H, 01H, 00H, 00H, 00H, 00H, 00H, 00H
DB 00H, 00H, 00H, 00H, 00H, 00H, 01H, 02H
DB 02H, 03H, 04H, 05H, 06H, 07H, 08H, 09H
DB 0AH, 0BH, 0DH, 0EH, 10H, 11H, 13H, 15H
DB 16H, 18H, 1AH, 1CH, 1EH, 20H, 22H, 25H
DB 27H, 29H, 2BH, 2EH, 30H, 33H, 35H, 38H
DB 3AH, 3DH, 40H, 43H, 45H, 48H, 4CH, 4EH
DB 51H, 55H, 57H, 5AH, 5DH, 60H, 63H, 66H
DB 69H, 6CH, 6FH, 72H, 76H, 79H, 7CH, 80H
END
8.4 梯形波
程序介绍:程序介绍:单片机通过DAC0832转换在LM358的7脚输出梯形波。实际应用如:函数波形发生器。
程序实例(0832ti.asm):
ORG 0000h
MAIN:
MOV DPTR,#0BFFFH
STEP: MOV R6,#19H
MOV R4,#0AH
MOV A,0
81
LOOP1: MOVX @DPTR,A ;选通地址
ACALL DELAY ;延时
ADD A,R6 ;每次以19H的梯度增加
DJNZ R4,LOOP1 ;梯度等待的时间
AJMP STEP ;循环
DELAY:
D2: MOV 31H,#0FFH
D1: DJNZ 31H,D1
RET
END
九、PC通讯
发送到上位机显示程序介绍:单片机利用串口与定时器功能,以9600的波特率向PC机发送
“我爱单片机”字符串。图16PC机用comedebug.com程序接收。波特率计算请详
见课本。实际应用如: 监控
报警系统。
操作说明:程序写入后,将数据线插入图16所
示插口,如图17所示,按下图17
波特率按键,这时单片机晶振将会由12M切换到11.0592M工作(这样做是为了波特率计算方便)最后,打开PC机运行程序“comedebug.com”,如图18所示,设置好波特率,
点击打开串口,将会看到如图所示画面——“我爱单片
82
机”。
图18
程序实例(dispc.asm):
ORG 0000H
MAIN:
MOV TMOD,#20H ;定时器1模式2
MOV TL1,#0FDH
MOV TH1,#0FDH ;波特率9600
SETB TR1 ;开定时器运行
MOV SCON,#01000000B ;串行口工作于方式1
MOV R1,#00H
MAIN1:
MOV A,R1
;/
MOV DPTR,#SETTAB
MOVC A,@A+DPTR ;取表格数据送显
MOV SBUF,A
JNB TI,$
CLR TI
INC R1
;/
83
CJNE A,#0AH,MAIN1 ;没到结束标志0A继续去
送显
MOV R1,#00H ;到了从头开始送显
AJMP MAIN1
SETTAB:
DB "我爱单片机",0AH
END
十、编程器
89S51——89S52操作说明:89s51(52)编程器利用了ATMEL公司89S52的在线可编程功能(ISP)。通过计算机串口将程序下载到单片机中。编程时,首先连接串口线,一端连实验仪接口,一端接PC机串口中。MYCOM.EXE程序打开后如图19所示。首先点擦除,建议擦两次。然后点读取。在右边的文本框里会看到全是FF,这样表示擦掉了。接着点读取,在弹出的对话框中找到想要写入程序的16 进制文件(后缀名为hex).最后单击写入,程序即写入。将单片机换到程序运行插座上,就可以看到程序运行结果了。
注意:不管是编程时还是程序运行时,一定不要将单片机的方向放反,否则将会烧坏单片机。
84
图19
十一、中断
11.1 按键数显
程序介绍:程序写入上电后,数码管显示0000,每按一次按键数显键,数码管显示就会加一。实际应用如:数码调温显示
程序实例(ajian.asm):
ORG 0000H
AJMP MAIN
ORG 0003H ;外中断0入口
AJMP INT
ORG 0020H
MAIN:
MOV SCON,#00H ;串行口工作于方式0(同步移位方式)
85
MOV 33H,#00H
MOV 34H,#00H ;显示个,十位初值
SETB EA ;开总中断
SETB EX0 ;开外中断0允许
SETB IT0 ;设为下降沿触发
DISPLAY:
MOV A,33H
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D1: JNB TI,D1
CLR TI
MOV A,34H
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D2: JNB TI,D2
CLR TI ;显示个,十位
MOV 35H,#0FFH
D6: MOV 36H,#0FFH
D5: DJNZ 36H,D5
DJNZ 35H,D6 ;延时
AJMP DISPLAY ;循环
INT:
PUSH ACC
JB P3.2,RE
MOV 30H,#0FFH
D4: MOV 31H,#0FFH
86
D3: DJNZ 31H,D3
DJNZ 30H,D4
JB P3.2,RE ;断键抖动
;是按键了,个位加一,加到10后,十位加一,加到99,回
到00
INC 33H
MOV A,33H
CJNE A,#0FH,RE
MOV 33H,#00H
INC 34H
MOV A,34H
CJNE A,#0FH,RE
MOV 34H,#00H
;/
RE:
POP ACC
RETI
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH ;数显代码
END
11.2 PWM码简介及解码原理
PWM 码是一种脉宽调制码,它的组成为9MS 高电平和4MS 低电平引导脉冲,16 位系统识别码,8 位数据正码和8 位数据反码。我们要解的就数据码。一个PWM码的0是由一个0.58ms的低电平和一个0.58ms的高电平
87
组成,1 是由一个0.58ms 的低电平地和一个1.58ms 的高电平组成。解码原理是这样的。首先通过延时来丢开引导码,然后通过解码丢掉16 位系统识别码,最后解系统正码和反码。解开后将正码取反看是否与反码相同,如果相同,即解开保存其值。解码0 或1是这样的。在低电平的时候等待,直到为高了后,用一个0.882ms 的延时去量,量完后,如果为低了,证明前面是一个0.58ms 低电平和一个0.58ms 高电平地组成,即保存一个0.如果为高,则证明是由一个0.58ms 低电平地和一个1.58ms 高电平组成,即保存一个1 .为1则再调一个延时,让它延到低电平。等待到高电平后重复上述过程解码。
11.3 遥控器解码
程序介绍:通过上述的解码原理,利用单片机的中断口来测PWM码的宽度,通过本实验仪配备的遥控,单片机解码在数码管上显示(图20)。实际应用例如:红外遥控。
图20
程序实例(disvcd.asm):
ORG 0000H
AJMP MAIN
ORG 0013H
AJMP INT
ORG 0030H
MAIN:
88
SETB EA ;开所有中断
SETB IT1
SETB EX1;
MOV 33H,#00H
TIN:
;显示/
MOV A,33H
ANL A,#0FH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D4: JNB TI,D4
CLR TI
MOV A,33H
ANL A,#0F0H
SWAP A
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D5: JNB TI,D5
CLR TI
ACALL YS1
AJMP TIN
;/
INT: ;中断解码
CLR EA ;关所有中断
MOV R6,#10
SB: ACALL YS1 ;延时882m
89
JB P3.3,EXIT ;为高退出
DJNZ R6,SB ;延时9ms
JNB P3.3,$ ;避开9ms高电平引导
脉冲
ACALL YS2 ;避开4ms低电平引导脉冲
MOV R7,#16 ;忽略16位系统码
JJJJA: JNB P3.3,$
LCALL YS1
MOV C,P3.3
JNC UUUA
LCALL YS3 ;延时1ms
UUUA: DJNZ R7,JJJJA
;解系统正码和反码,取反后比较相等保存//
MOV R1,#1AH
MOV R2,#2
PP: MOV R3,#8
JJJJ: JNB P3.3,$
LCALL YS1
MOV C,P3.3
JNC UUU
LCALL YS3
UUU: MOV A,@R1
RRC A
MOV @R1,A
DJNZ R3,JJJJ
INC R1
DJNZ R2,PP
MOV A,1AH
90
CPL A
CJNE A,1BH,EXIT
;/
MOV 33H,1AH
EXIT: SETB EA
RETI
YS1: MOV R4,#20
D1: MOV R5,#20
DJNZ R5,$
DJNZ R4,D1
RET
YS2: MOV R4,#10
D2: MOV R5,#235
DJNZ R5,$
DJNZ R4,D2
RET
YS3: MOV R4,#2
D3: MOV R5,#248
DJNZ R5,$
DJNZ R4,D3
RET
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,
0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH
END
91
十二、综合
12.1 电子钟
程序及操作指南:程序写入上电后,将在四个数码管上显示0000,然后每隔一分钟,数码管将从低位跳变,该程序模拟的就是时钟。用按键数显键可将时间调至正确时间。按按键数键一下,数码管将在低位闪烁,然后依次按一下,数码管的闪烁位置就向前移一个数码管,按到第五下时,退出。将对应的数码管按闪烁以后,长按按键数显键,数码管将会显示从1至9,显示到所需时间,松开按键数显键,数码管显示对应所设时间,程序也会记下这个值。
例设置成2334,
即晚上11点34分。设置步骤如下:按键一下长按至数码管分低显示到4时松开按键一下长按至数码管分高位显示到3时松开按键一下长按至数码管时低位显示到3时松开按键一下长按至数码管时高位显示到2时松开。
注意:如果小时设置超过23,数码管将显示ERR(错误),再按一下键恢恢复。
程序实例(clock.asm):
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP INT ;外中断0入口
ORG 000BH
AJMP DIN0 ;定时器0入口
MAIN:
92
DISML EQU 30H
DISMH EQU 31H
DISHL EQU 32H
DISHH EQU 33H ;显示分,时的个时位
TFLAG EQU 34H ;时间秒标志,判是否到50
个0.2秒,即50*0.2=1秒
SETFLAG EQU 35H ;设置标志,依次从个位到
十位到百位到千位
ADDFLAG EQU 36H
MFLAG EQU 37H ;时间分标志,判是否到60
个一秒,即一分
MOV DISML,#00H
MOV DISMH,#00H
MOV DISHL,#00H
MOV DISHH,#00H ;显示分,时的个时位初值
MOV TFLAG,#00H ;时间秒标志初值
MOV SETFLAG,#00H ;设置标志初值
MOV ADDFLAG,#00H ;设数加标志
MOV MFLAG,#00H ;时间分标志
MOV SCON,#00H ;串行口工作于方式0(同
步移位)
MOV TMOD,#00000001B;定时器0工作于方式1
MOV TL0,#0EEH
MOV TH0,#31H ;设定时时间为0.05秒,定
时20次则一秒
SETB EA ;开总中断
SETB ET0 ;开定时器0中断允许
SETB EX0 ;开外中断0允许
93
SETB TR0 ;开定时0运行
SETB IT0 ;外中断0下降沿触发
DIS:
ACALL DISPLAY ;调用显示时钟程序
AJMP CRITERION ;调判断程序,按键是否按
了。
; ACALL DELAY
; AJMP DIS
DIN0:
PUSH ACC
;设置时是否出错,比如小时设到超过了23//
MOV A,DISHH
CJNE A,#02H,INCC
MOV A,DISHL
CLR C
SUBB A,#04H
JC INCC
MOV SETFLAG,#06H
AJMP RE
;/
;是否到一秒///
INCC: INC TFLAG
MOV A,TFLAG
CJNE A,#19,RE
MOV TFLAG,#00H
;/
;是否到一分///
INC MFLAG
94
MOV A,MFLAG
CJNE A,#60,RE
MOV MFLAG,#00H
;/
;计分/
INC DISML
MOV A,DISML
CJNE A,#0AH,RE
MOV DISML,#00H
INC DISMH
MOV A,DISMH
CJNE A,#06H,RE
MOV DISMH,#00H
;/
;计时/
;计时分两种情况,分为小时的高位到2和没到2,没到2时时低位是逢10进位,到2后,时低位到4则全归0
MOV A,DISHH
CJNE A,#02H,HJ
;/
;第一种情况///
INC DISHL
MOV A,DISHL
CJNE A,#04H,RE
MOV DISHL,#00H
MOV DISHH,#00H
AJMP RE
;/
95
;第二种情况///
HJ: INC DISHL
MOV A,DISHL
CJNE A,#0AH,RE
MOV DISHL,#00H
INC DISHH
;/
RE:
MOV TL0,#0EEH
MOV TH0,#31H ;设定时时间为0.02秒,定时50次则一秒
POP ACC
RETI ;退出中断
INT:
PUSH ACC
JB P3.2,EXIT
MOV R3,#0FFH
DJNZ R3,$
JB P3.2,EXIT ;判键抖
MOV A,SETFLAG
CJNE A,#00H,ADD2
AJMP SETKEY
ADD2: CJNE A,#06H,B0 ;是错误了吗,是的,去恢复
MOV SETFLAG,#00H
AJMP SETKEY
B0: MOV R4,#15H
ADD1: JB P3.2,SETKEY
96
ACALL DELAY
DJNZ R4,ADD1
MOV ADDFLAG,#01H
AJMP EXIT
;状态增值/
SETKEY: INC SETFLAG
MOV A,SETFLAG
CJNE A,#05H,EXIT
MOV SETFLAG,#00H
;/
EXIT:
POP ACC
RETI
;显示时钟/
DISPLAY:
MOV A,DISML
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D1: JNB TI,D1
CLR TI
MOV A,DISMH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D2: JNB TI,D2
CLR TI
MOV A,DISHL
97
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D3: JNB TI,D3
CLR TI
MOV A,DISHH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D4: JNB TI,D4
CLR TI
RET
;/
;判按键标志///
CRITERION:
MOV A,SETFLAG
CJNE A,#00H,ERFLAG ;设置标志为0,即没有按键,继续去显示
AJMP RET1
ERFLAG: CJNE A,#06H,SETML1 ;设置标志为6,即错误了,去显示错误
AJMP ERR
SETML1: CJNE A,#01H,SETMH1
AJMP SETML ;设置标志为1,显示设分低
SETMH1: CJNE A,#02H,SETHL1
AJMP SETMH ;设置标志为2,显示设分高
98
SETHL1: CJNE A,#03H,SETHH1
AJMP SETHL ;设置标志为3,显示设时低
SETHH1: CJNE A,#04H,RET1 ;设置标志为5,是退出标志
AJMP SETHH ;设置标志为4,显示设时高
RET1: SETB TR0
ACALL DELAY
AJMP DIS
;/
;设分低(分低位闪烁)/
SETML:
CLR TR0
MOV A,ADDFLAG
CJNE A,#01H,SETML2 ;是否按下了2秒钟,是就开始闪烁设置
JNB P3.2,ADD3
MOV ADDFLAG,#00H ;松开了,清闪标志
AJMP SETML2
ADD3: INC DISML
MOV A,DISML
CJNE A,#0AH,SETML2
MOV DISML,#00H
SETML2: ACALL DELAY2
ACALL DISPLAY
ACALL DELAY2
MOV SBUF,#00H
99
E1: JNB TI,E1
CLR TI
MOV A,DISMH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
E2: JNB TI,E2
CLR TI
MOV A,DISHL
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
E3: JNB TI,E3
CLR TI
MOV A,DISHH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
E4: JNB TI,E4
CLR TI
AJMP CRITERION
;//
;设分高(分高位闪烁)
SETMH:
CLR TR0
MOV A,ADDFLAG
CJNE A,#01H,SETMH2 ;是否按下了2秒钟,是就开始闪烁设置
100
JNB P3.2,ADD4
MOV ADDFLAG,#00H ;松开了,清闪标志
AJMP SETMH2
ADD4: INC DISMH
MOV A,DISMH
CJNE A,#0AH,SETMH2
MOV DISMH,#00H
SETMH2: ACALL DELAY2
ACALL DISPLAY
ACALL DELAY2
MOV A,DISML
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
F1: JNB TI,F1
CLR TI
MOV SBUF,#00H
F2: JNB TI,F2
CLR TI
MOV A,DISHL
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
F3: JNB TI,F3
CLR TI
MOV A,DISHH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
101
MOV SBUF,A
F4: JNB TI,F4
CLR TI
AJMP CRITERION
;//
;设时低位(时低位闪烁)
SETHL:
CLR TR0
MOV A,ADDFLAG
CJNE A,#01H,SETHL2 ;是否按下了2秒钟,
是就开始闪烁设置
JNB P3.2,ADD5
MOV ADDFLAG,#00H ;松开了,清闪标志
AJMP SETHL2
ADD5: INC DISHL
MOV A,DISHL
CJNE A,#0AH,SETHL2
MOV DISHL,#00H
SETHL2: ACALL DELAY2
ACALL DISPLAY
ACALL DELAY2
MOV A,DISML
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
G1: JNB TI,G1
CLR TI
MOV A,DISMH
102
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
G2: JNB TI,G2
CLR TI
MOV SBUF,#00H
G3: JNB TI,F3
CLR TI
MOV A,DISHH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
G4: JNB TI,G4
CLR TI
AJMP C RITERION
;//
;设时高位(时高位闪烁)
SETHH:
CLR TR0
MOV A,ADDFLAG
CJNE A,#01H,SETHH2 ;是否按下了2秒钟,
是就开始闪烁设置
JNB P3.2,ADD6
MOV ADDFLAG,#00H ;松开了,清闪标志
AJMP SETHH2
ADD6: INC DISHH
MOV A,DISHH
CJNE A,#03H,SETHH2
103
MOV DISHH,#00H
SETHH2: ACALL DELAY2
ACALL DISPLAY
ACALL DELAY2
MOV A,DISML
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
H1: JNB TI,H1
CLR TI
MOV A,DISMH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
H2: JNB TI,H2
CLR TI
MOV A,DISHL
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
H3: JNB TI,H3
CLR TI
MOV SBUF,#00H
H4: JNB TI,H4
CLR TI
AJMP CRITERION
;//
;错误显示//
104
ERR: CLR TR0
ACALL DELAY2
MOV SBUF,#0EAH
I1: JNB TI,I1
CLR TI
MOV SBUF,#0EAH
I2: JNB TI,I2
CLR TI
MOV SBUF,#9EH
I3: JNB TI,I3
CLR TI
MOV SBUF,#00H
I4: JNB TI,I4
CLR TI
AJMP CRITERION
;延时/
DELAY:
MOV R1,#100
DE: MOV R2,#100
DJNZ R2,$
DJNZ R1,DE
RET
;//
DELAY1:
MOV R1,#0FFH
DE1: MOV R2,#0FFH
DJNZ R2,$
DJNZ R1,DE1
105
RET
DELAY2: MOV 38H,#02H
DE3: MOV R2,#0FFH
DE2: MOV R1,#0FFH
DJNZ R1,$
DJNZ R2,DE2
DJNZ 38H,DE3
RET
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH ;数显代码
END
12.2 智能红外工业控制器程序介绍:这个产品是通过遥控器控制定时时间来决定P1.0口输出高电平和低电平的时间,在P1.0口接一个继电器后,从而控制电磁阀开和关,以达到对石油含水量的定时智能排放。现已应用在上海金山炼油厂,反映良好。本实验仪完全模拟了这个产品,它的详细操作请参照附一
(以用于上海金山炼油厂的产品说明)。 程序实例(honwai.asm):
ORG 0000H
AJMP MAIN
ORG 000BH
AJMP DIN0 ;TIME
ORG 00013H
AJMP INT
106
MAIN:
;DATA DEFINE
ON_MINUTE_LOW EQU 30H
ON_MINUTE_HIGH EQU 31H
ON_HOUR_LOW EQU 32H
ON_HOUR_HIGH EQU 33H
OFF_MINUTE_LOW EQU 34H
OFF_MINUTE_HIGH EQU 35H
OFF_HOUR_LOW EQU 36H
OFF_HOUR_HIGH EQU 37H
DIS_MINUTE_LOW EQU 38H
DIS_MINUTE_HIGH EQU 39H
DIS_HOUR_LOW EQU 40H
DIS_HOUR_HIGH EQU 41H
TIMES_ADD_NUMBER EQU 42H
TIMEM_ADD_NUMBER EQU 3FH
INTERRUPT_NUMBER EQU 43H
INTSET_FLAG EQU 44H
ETTYPE_FLAG EQU 4FH
BL EQU 3EH
BL1 EQU 4EH
SET_ON_MLOW EQU 3AH
SET_ON_MHIGH EQU 3BH
SET_ON_HLOW EQU 3CH
SET_ON_HHIGH EQU 3DH
SET_OFF_MLOW EQU 4AH
SET_OFF_MHIGH EQU 4BH
SET_OFF_HLOW EQU 4CH
107
SET_OFF_HHIGH EQU 4DH
;//
;DATA GIVE FIRST NUMBER//
MOV ON_MINUTE_LOW,#00H
MOV ON_MINUTE_HIGH,#02H
MOV ON_HOUR_LOW,#00H
MOV ON_HOUR_HIGH,#00H
MOV OFF_MINUTE_LOW,#00H
MOV OFF_MINUTE_HIGH,#06H
MOV OFF_HOUR_LOW,#03H
MOV OFF_HOUR_HIGH,#00H
MOV DIS_MINUTE_LOW,#00H
MOV DIS_MINUTE_HIGH,#00H
MOV DIS_HOUR_LOW,#00H
MOV DIS_HOUR_HIGH,#00H
MOV TIMES_ADD_NUMBER,#00H
MOV TIMEM_ADD_NUMBER,#00H
MOV INTERRUPT_NUMBER,#00H
MOV INTSET_FLAG,#00H
MOV SETTYPE_FLAG,#00H
MOV BL,#00H
MOV BL1,#00H
MOV SET_ON_MLOW,#00H
MOV SET_ON_MHIGH,#00H
MOV SET_ON_HLOW,#00H
MOV SET_ON_HHIGH,#00H
MOV SET_OFF_MLOW,#00H
MOV SET_OFF_MHIGH,#00H
108
MOV SET_OFF_HLOW,#00H
MOV SET_OFF_HHIGH,#00H
;//
MOV TMOD,#00010001B
MOV TL0,#0AFH
MOV TH0,#3CH
SETB IT1
SETB EX1
SETB TR0
SETB ET0
SETB PT0
SETB EA
CLR P1.0
;//
;DISPLAY///
DISPLAY:
MOV BL1,#00H
MOV A,DIS_MINUTE_LOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D1: JNB TI,D1
CLR TI
MOV A,DIS_MINUTE_HIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D2: JNB TI,D2
109
CLR TI
MOV A,DIS_HOUR_LOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D3: JNB TI,D3
CLR TI
MOV A,DIS_HOUR_HIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D4: JNB TI,D4
CLR TI
LCALL DELAY1
;INTSETFLAG//
MOV A,INTSET_FLAG
CJNE A,#00H,AONFE
AJMP DISP
AONFE: CJNE A,#01H,AONSH
AJMP ONFE
AONSH: CJNE A,#02H,AOFFE
AJMP ONSH
AOFFE: CJNE A,#03H,AOFSH
AJMP OFFFE
AOFSH: AJMP OFFSH
;/
DISP: JNB P1.0,DISON
AJMP DISOFF
110
DISON: MOV A,#0ECH
MOV SBUF,A
D8: JNB TI,D8
CLR TI
MOV A,#0FCH
MOV SBUF,A
D7: JNB TI,D7
CLR TI
MOV A,#00H
MOV SBUF,A
D6: JNB TI,D6
CLR TI
MOV A,#00H
MOV SBUF,A
D5: JNB TI,D5
CLR TI
LCALL DELAY1
;INTSETFLAG
MOV A,INTSET_FLAG
CJNE A,#00H,BONFE
AJMP D1ISP
BONFE: CJNE A,#01H,BONSH
AJMP ONFE
BONSH: CJNE A,#02H,BOFFE
AJMP ONSH
BOFFE: CJNE A,#03H,BOFSH
AJMP OFFFE
BOFSH: AJMP OFFSH
111
;/
D1ISP: AJMP DISPLAY
DISOFF:
MOV A,#8EH
MOV SBUF,A
D12: JNB TI,D12
CLR TI
MOV A,#8EH
MOV SBUF,A
D11: JNB TI,D11
CLR TI
MOV A,#0FCH
MOV SBUF,A
D10: JNB TI,D10
CLR TI
MOV A,#00H
MOV SBUF,A
D9: JNB TI,D9
CLR TI
LCALL DELAY1
LCALL DELAY1
;INTSETFLAG///
STATUS: MOV A,INTSET_FLAG
CJNE A,#00H,CONFE
AJMP D2ISP
CONFE: CJNE A,#01H,CONSH
AJMP ONFE
CONSH: CJNE A,#02H,COFFE
112
AJMP ONSH
COFFE: CJNE A,#03H,COFSH
AJMP OFFFE
COFSH: AJMP OFFSH
;/
D2ISP: AJMP DISPLAY
;//
;STATUS ONFEN///
ONFE:
MOV A,#9EH
MOV SBUF,A
DD1: JNB TI,DD1
CLR TI ;E
MOV A,#8EH
MOV SBUF,A
DD2: JNB TI,DD2
CLR TI ;F
MOV A,#0ECH
MOV SBUF,A
DD3: JNB TI,DD3
CLR TI ;N
MOV A,#0FCH
MOV SBUF,A
DD4: JNB TI,DD4
CLR TI ;O
LCALL DELAY2
MOV A,BL1
CJNE A,#01H,ONFE
113
MOV A,SETTYPE_FLAG
CJNE A,#01H,STA
AJMP SETONFEN
STA: AJMP STATUS
;//
;STATUS ON SH/
ONSH:
;display onus//
MOV A,#6EH
MOV SBUF,A
DD8: JNB TI,DD8
CLR TI ;H
MOV A,#0B6H
MOV SBUF,A
DD7: JNB TI,DD7
CLR TI ;S
MOV A,#0ECH
MOV SBUF,A
DD6: JNB TI,DD6
CLR TI ;N
MOV A,#0FCH
MOV SBUF,A
DD5: JNB TI,DD5
CLR TI ;O
LCALL DELAY2
MOV A,BL1
CJNE A,#01H,ONSH
MOV A,SETTYPE_FLAG
114
CJNE A,#01H,STA1
AJMP SETONSH
STA1:
AJMP STATUS
;//
;STATUS OFF FE///
OFFFE:
;display ofad///
MOV A,#09EH
MOV SBUF,A
DD10 : JNB TI,DD10
CLR TI ;E
MOV A,#8EH
MOV SBUF,A
DD9: JNB TI,DD9
CLR TI ;F
MOV A,#8EH
MOV SBUF,A
DD12: JNB TI,DD12
CLR TI ;F
MOV A,#0FCH
MOV SBUF,A
DD11: JNB TI,DD11
CLR TI ;O
LCALL DELAY
MOV A,BL1
CJNE A,#01H,OFFFE
MOV A,SETTYPE_FLAG
115
CJNE A,#01H,STA2
AJMP SETOFFEN
STA2:
AJMP STATUS
;//
;STATUS OFF SH///
OFFSH:
MOV A,#6EH
MOV SBUF,A
DD14: JNB TI,DD14
CLR TI ;H
MOV A,#0B6H
MOV SBUF,A
DD13: JNB TI,DD13
CLR TI ;S
MOV A,#8EH
MOV SBUF,A
DD16: JNB TI,DD16
CLR TI ;F
MOV A,#0FCH
MOV SBUF,A
DD15: JNB TI,DD15
CLR TI ;O
LCALL DELAY2
MOV A,BL1
CJNE A,#01H,OFFSH
MOV A,SETTYPE_FLAG
CJNE A,#01H,STA3
116
AJMP SETOFFSH
STA3:
AJMP STATUS
;/
SETONFEN:
CLR TR0
MOV C,P1.0
JNC FI
AJMP FI1
FI: MOV DIS_MINUTE_LOW,#00H
MOV DIS_MINUTE_HIGH,#00H
MOV DIS_HOUR_LOW,#00H
MOV DIS_HOUR_HIGH,#00H
FI1: MOV SET_ON_MLOW,#00H
MOV SET_ON_MHIGH,#00H
SETONFEN2:
INC SET_ON_MLO
MOV A,SET_ON_MLOW
CJNE A,#0AH,CJ
MOV SET_ON_MLOW,#00H
INC SET_ON_MHIGH
MOV A,SET_ON_MHIGH
CJNE A,#0AH,CJ
MOV SET_ON_MHIGH,#00H
CJ:
MOV A,SET_ON_MLOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
117
MOV SBUF,A
D13: JNB TI,D13
CLR TI
MOV A,SET_ON_MHIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D14: JNB TI,D14
CLR TI
MOV A,SET_ON_HLOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D15: JNB TI,D15
CLR TI
MOV A,SET_ON_HHIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D16: JNB TI,D16
CLR TI
LCALL DELAY1
LCALL DELAY1
MOV ON_MINUTE_LOW,SET_ON_MLOW
MOV ON_MINUTE_HIGH,SET_ON_MHIGH
MOV ON_HOUR_LOW,SET_ON_HLOW
MOV ON_HOUR_HIGH,SET_ON_HHIGH
MOV A,SETTYPE_FLAG
118
CJNE A,#00H,SETONFEN1
SETB TR0
AJMP DISPLAY
SETONFEN1:
AJMP SETONFEN2
SETONSH:
CLR TR0
MOV C,P1.0
JNC F2
AJMP FI2
F2: MOV DIS_MINUTE_LOW,#00H
MOV DIS_MINUTE_HIGH,#00H
MOV DIS_HOUR_LOW,#00H
MOV DIS_HOUR_HIGH,#00
FI2: MOV SET_ON_HLOW,#00H
MOV SET_ON_HHIGH,#00H
SETONSH2:
INC SET_ON_HLOW
MOV A,SET_ON_HLOW
CJNE A,#0AH,CJ1
MOV SET_ON_HLOW,#00H
INC SET_ON_HHIGH
MOV A,SET_ON_HHIGH
CJNE A,#0AH,CJ1
MOV SET_ON_HHIGH,#00H
CJ1:
MOV A,SET_ON_MLOW
MOV DPTR,#SETTAB
119
MOVC A,@A+DPTR
MOV SBUF,A
D17: JNB TI,D17
CLR TI
MOV A,SET_ON_MHIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D18: JNB TI,D18
CLR TI
MOV A,SET_ON_HLOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D19: JNB TI,D19
CLR TI
MOV A,SET_ON_HHIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D20: JNB TI,D2
CLR TI
LCALL DELAY1
LCALL DELAY1
MOV ON_MINUTE_LOW,SET_ON_MLOW
MOV ON_MINUTE_HIGH,SET_ON_MHIGH
MOV ON_HOUR_LOW,SET_ON_HLOW
MOV ON_HOUR_HIGH,SET_ON_HHIGH
120
MOV A,SETTYPE_FLAG
CJNE A,#00H,SETONSH1
SETB TR0
AJMP DISPLAY
SETONSH1:
AJMP SETONSH2
SETOFFEN:
CLR TR0
MOV C,P1.0
JC F3
AJMP FI3
F3: MOV DIS_MINUTE_LOW,#00H
MOV DIS_MINUTE_HIGH,#00H
MOV DIS_HOUR_LOW,#00H
MOV DIS_HOUR_HIGH,#00
FI3: MOV SET_OFF_MLOW,#00H
MOV SET_OFF_MHIGH,#00H
SETOFFEN2:
INC SET_OFF_MLOW
MOV A,SET_OFF_MLOW
CJNE A,#0AH,CJJ1
MOV SET_OFF_MLOW,#00H
INC SET_OFF_MHIGH
MOV A,SET_OFF_MHIGH
CJNE A,#0AH,CJJ1
MOV SET_OFF_MHIGH,#00H
121
CJJ1:
MOV A,SET_OFF_MLOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D21: JNB TI,D2
CLR TI
MOV A,SET_OFF_MHIGH
MOV DPTR,#SETTA
MOVC A,@A+DPTR
MOV SBUF,A
D22: JNB TI,D22
CLR TI
MOV A,SET_OFF_HLOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D23: JNB TI,D23
CLR TI
MOV A,SET_OFF_HHIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D24: JNB TI,D24
CLR TI
LCALL DELAY1
LCALL DELAY1
MOV OFF_MINUTE_LOW,SET_OFF_MLOW
122
MOV OFF_MINUTE_HIGH,SET_OFF_MHIGH
MOV OFF_HOUR_LOW,SET_OFF_HLOW
MOV OFF_HOUR_HIGH,SET_OFF_HHIGH
MOV A,SETTYPE_FLAG
CJNE A,#00H,SETOFFEN1
SETB TR0
AJMP DISPLAY
SETOFFEN1:
AJMP SETOFFEN2
SETOFFSH:
CLR TR0
MOV C,P1.0
JC F4
AJMP FI4
F4: MOV DIS_MINUTE_LOW,#00H
MOV DIS_MINUTE_HIGH,#00H
MOV DIS_HOUR_LOW,#00H
MOV DIS_HOUR_HIGH,#00
FI4: MOV SET_OFF_HLOW,#00H
MOV SET_OFF_HHIGH,#00H
SETOFFSH2:
INC SET_OFF_HLOW
MOV A,SET_OFF_HLOW
CJNE A,#0AH,CJJJ1
MOV 4CH,#00H
INC SET_OFF_HHIGH
MOV A,SET_OFF_HHIGH
CJNE A,#0AH,CJJJ1
123
MOV SET_OFF_HHIGH,#00H
CJJJ1:
MOV A,SET_OFF_MLOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D25: JNB TI,D25
CLR TI
MOV A,SET_OFF_MHIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D26: JNB TI,D26
CLR TI
MOV A,SET_OFF_HLOW
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D27: JNB TI,D27
CLR TI
MOV A,SET_OFF_HHIGH
MOV DPTR,#SETTAB
MOVC A,@A+DPTR
MOV SBUF,A
D28: JNB TI,D28
CLR TI
LCALL DELAY1
LCALL DELAY1
124
MOV OFF_MINUTE_LOW,SET_OFF_MLOW
MOV OFF_MINUTE_HIGH,SET_OFF_MHIGH
MOV OFF_HOUR_LOW,SET_OFF_HLOW
MOV OFF_HOUR_HIGH,SET_OFF_HHIGH
MOV A,SETTYPE_FLAG
CJNE A,#00H,SETOFFSH1
SETB TR0
AJMP DISPLAY
SETOFFSH1:
AJMP SETOFFSH2
;TIME/
DIN0:
PUSH ACC
INC TIMES_ADD_NUMBER
MOV A,TIMES_ADD_NUMBER
CJNE A,#19,ONRETT
JNB P1.0,SECOND
MOV TIMES_ADD_NUMBER,#00H
INC TIMEM_ADD_NUMBER
MOV A,TIMEM_ADD_NUMBER
CJNE A,#60,ONRETT
MOV TIMEM_ADD_NUMBER,#00H
AJMP DISADD
SECOND: MOV TIMES_ADD_NUMBER,#00H
AJMP DISADD
ONRETT: AJMP ONRET
DISADD: INC DIS_MINUTE_LOW
MOV A,DIS_MINUTE_LOW
125
CJNE A,#0AH,ONRE
MOV DIS_MINUTE_LOW,#00H
INC DIS_MINUTE_HIGH
MOV A,DIS_MINUTE_HIGH
CJNE A,#0AH,ONRE
MOV DIS_MINUTE_HIGH,#00H
INC DIS_HOUR_LOW
MOV A,DIS_HOUR_LOW
CJNE A,#0AH,ONRE
MOV DIS_HOUR_LOW,#00H
INC DIS_HOUR_HIGH
MOV A,DIS_HOUR_HIGH
CJNE A,#0AH,ONRE
MOV DIS_HOUR_HIGH,#00H
ONRE:
JB P1.0,ONRE2
AJMP ONRE1
ONRE2: MOV A,DIS_MINUTE_LOW
CJNE A,OFF_MINUTE_LOW,ONRET
MOV A,DIS_MINUTE_HIGH
CJNE A,OFF_MINUTE_HIGH,ONRET
MOV A,DIS_HOUR_LOW
CJNE A,OFF_HOUR_LOW,ONRET
MOV A,DIS_HOUR_HIGH
CJNE A,OFF_HOUR_HIGH,ONRET
CLR P1.0
MOV DIS_MINUTE_LOW,#00H
MOV DIS_MINUTE_HIGH,#00H
126
MOV DIS_HOUR_LOW,#00H
MOV DIS_HOUR_HIGH,#00H
AJMP ONRET
ONRE1: MOV A,DIS_MINUTE_LOW
CJNE A,ON_MINUTE_LOW,ONRET
MOV A,DIS_MINUTE_HIGH
CJNE A,ON_MINUTE_HIGH,ONRET
MOV A,DIS_HOUR_LOW
CJNE A,ON_HOUR_LOW,ONRET
MOV A,DIS_HOUR_HIGH
CJNE A,ON_HOUR_HIGH,ONRET
SETB P1.0
MOV DIS_MINUTE_LOW,#00H
MOV DIS_MINUTE_HIGH,#00H
MOV DIS_HOUR_LOW,#00H
MOV DIS_HOUR_HIGH,#00H
ONRET: MOV TL0,#0AFH
MOV TH0,#3CH
RE: POP ACC
RETI
;/
;INTERRUPT
INT: ;Interrupt program
;GET KEY NUMBER///
CLR EA ;OFF ALL Interuppt
PUSH ACC
MOV R6,#10
SB: ACALL YS1 ;DELAY 882us
127
JB P3.3,DISPL ;High break
DJNZ R6,SB ;DELAY 8820us
JNB P3.3,$ ;Wait high
volgate,BIKAI 9ms low volgate
ACALL YS2 ;DELAY
4.74ms,BIKAI 4.5ms JIEGUOMA
MOV R7,#16 ;(HULUE 16BIT
SYSTEM DATA)
JJJJA: JNB P3.3,$
LCALL YS1
MOV C,P3.3
JNC UUUA
LCALL YS3 ;DELAY 1ms
UUUA: DJNZ R7,JJJJA
MOV R1,#1AH
MOV R2,#2
PP: MOV R3,#8
JJJJ: JNB P3.3,$
LCALL YS1
MOV C,P3.3
JNC UUU
LCALL YS3
UUU: MOV A,@R1
RRC A
MOV @R1,A
DJNZ R3,JJJJ
INC R1
DJNZ R2,PP
128
MOV A,1AH
CPL A
CJNE A,1BH,DISPL
MOV 43H,1AH
MOV A,1AH
;/
CJNE A,#041H,CJN3
MOV INTSET_FLAG,#00H
MOV SETTYPE_FLAG,#00H
MOV BL1,#01H
AJMP EXIT
CJN3: CJNE A,#057H,CJN0
MOV A,BL
MOV SETTYPE_FLAG,#01H
AJMP EXIT
CJN0: CJNE A,#046H,CJN1
AJMP OND
CJN1: CJNE A,#10H,CJN2
AJMP OFD
CJN2: CJNE A,#014H,DISPL ;menu flag ?
MOV SETTYPE_FLAG,#00H
;MENU FLAG//
INC INTSET_FLAG
MOV BL1,#01H
MOV A,INTSET_FLAG
CJNE A,#05H,DISPL
MOV INTSET_FLAG,#01H
;//
129
DISPL:
LJMP EXIT
;ON DCF 6
MINUTE/
OND:
MOV C,P1.0
CLR P1.0
LCALL DELAY
MOV P1.0,C
MOV 43H,#00H
LJMP EXIT
;//
;OFF DCF 6 MINUTE//
OFD:
MOV C,P1.*
SETB P1.0
LCALL DELAY3
MOV P1.0,C
MOV 43H,#00H
;
;SET ADD OR JIAN/
EXIT: SETB EA
POP ACC
RETI
YS1: MOV R4,#20
GE1: MOV R5,#20
DJNZ R5,$
DJNZ R4,GE1 ;0.7ms delay RET
130
YS2: MOV R4,#10
GE2: MOV R5,#235
DJNZ R5,$
DJNZ R4,GE2 ;1ms delay
RET
YS3: MOV R4,#2
DE3: MOV R5,#248
DJNZ R5,$
DJNZ R4,DE3
RET
DELAY1:
MOV 50H,#12
DEL3: MOV 51H,#100
DEL2: MOV 52H,#197
DEL1: DJNZ 52H,DEL1
DJNZ 51H,DEL2
DJNZ 50H,DEL3
RET
DELAY2:
MOV 51H,#10
DEEL3: MOV 52H,#100
DEEL1:
DJNZ 52H,DEEL1
DJNZ 51H,DEEL3
RET
DELAY3:
MOV 54H,#150
DEEL6: MOV 55H,#100
131
DEEL5: MOV 56H,#197
DEEL4: DJNZ 56H,DEEL4
DJNZ 55H,DEEL5
DJNZ 54H,DEEL6
RET
DELAY4:
MOV 70H,#10
DKEL3: MOV 51H,#100
DKEL2: MOV 52H,#197
DKEL1: DJNZ 52H,DKEL1
DJNZ 51H,DKEL2
DJNZ 70H,DKEL3
RET
SETTAB:
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH
END