51单片机实用程序库
一、前言
科技的进步需要技术不断的提升。一块大而复杂的模
拟电路花费了您巨大的精力,繁多的元器件增加了您的成 本。而现在,只需要一块几厘米见方的单片机,写入简单 的程序,就可以使您以前的电路简单很多。相信您在使用 并掌握了单片机技术后,不管在您今后开发或是工作上, 一定会带来意想不到的惊喜。 二、单片机简介
我国开始使用单片机是在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/t
s51 使用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,#H
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,#H
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,#H
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,#H
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,#H
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,#H
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:
;定义频率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,#H
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,#H
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,H,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, H, 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机发送
“我爱单片机”字符串。图16 PC机用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 \"我爱单片机\END
十、编程器
S51——S52
操作说明:s51(52)编程器利用了ATMEL公司S52
的在线可编程功能(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
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
因篇幅问题不能全部显示,请点此查看更多更全内容