单片机编程学习

2006-05-13 21:31:18

字体变小 字体变大
一、前言

  科技的进步需要技术不断的提升。一块大而复杂的模拟电路花费了您巨大的精力,繁多的元器件增加了您的成本。而现在,只需要一块几厘米见方的单片机,写入简单的程序,就可以使您以前的电路简单很多。相信您在使用并掌握了单片机技术后,不管在您今后开发或是工作上,一定会带来意想不到的惊喜。

二、单片机简介

  我国开始使用单片机是在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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值