汇编例子二
;*************************************************************
;名称: 51实现三种任务的功能例子:
;1. 开机后,继电器LED0以约1秒间隔不停地"亮-灭"循环
;2. 继电器LED1以约3秒间隔不停地"亮-灭"循环
;3. 按下S1(P3.2),继电器闭合(也可看到点亮LED);若再次按下S1则关闭
;提示: 单片机要实现多个任务,就必须启用定时计数器和中断
;硬件: XY900_USB型单片机开发板
;编写:月夜听风2009.10.15 http://www.mcusy.cn
;*************************************************************
Count_1 EQU 30H ;定义Count_1为软件计数器1,
Count_2 EQU 31H ;定义Count_2为软件计数器2,
S1 EQU P3.2 ;定义S1(P3.2)为控制继电器开/关键
LED0 EQU P2.0 ;定义LED0
LED1 EQU P2.1 ;定义LED1
Relay EQU P2.4 ;定义继电器
;----------------------------------------------------------
ORG 0000H
AJMP START
ORG 000BH ;定时器0的中断向量地址
AJMP TIME0 ;跳到定时器程序处
ORG 30H
;-------------------T0初始化和检测按键--------------------
START :
MOV Count_1,#00H ;软件计数器1先清0
MOV Count_2,#00H ;软件计数器2先清0
MOV TMOD,#01H ;定时/计数器0工作于方式1
MOV TH0,#4FH ; (以11.0592计算)
MOV TL0,#99H ;立即数 / 约50ms
SETB EA ;开总中断允许
SETB ET0 ;开定时/计数器0允许
SETB TR0 ;定时/计数器0开始运行
LOOP: ;检测继电器输出状态
JNB Relay,NEXT_ON ;若是0,跳到NEXT_ON
JB Relay,NEXT_OFF ;若是1,跳到NEXT_OFF
AJMP LOOP ;返回LOOP不断检测
;-----------------------定时器计数-------------------------
TIME0:
PUSH ACC ;堆栈保护
PUSH PSW ;
INC Count_1 ;两个计数器都加1
INC Count_2 ;
MOV A,Count_1 ; 先把Count_1的数放入累加器
CJNE A,#20,Next_1 ;Count_1的数值到了20?(20*50=1000ms)
;若没到跳到Next_1
CPL LED0 ;到了-取反LED0
MOV Count_1,#0 ;清Count_1
Next_1:
MOV A,Count_2 ;再把Count_2的数放入累加器
CJNE A,#60,Next_2 ;Count_2的数值到了60?(60*50=3000ms)
;若没到跳到Next_2
CPL LED1 ;到了-取反LED1
MOV Count_2,#0 ;清Count_2
Next_2:
MOV TH0,#4FH ;
MOV TL0,#99H ;重置定时常数
POP PSW ;取出
POP ACC ;
RETI ;
;----------------------处理按键----------------------------
NEXT_ON:
JNB S1,$ ;是否按下了S1键?
ACALL Delay_10ms ;防抖
JB S1,$ ;放开了按键?
SETB Relay ;继电器释放!
SETB P2.7 ;
ACALL Delay_10ms ;延时一下
AJMP LOOP ;返回LOOP继续去检测输出状态
NEXT_OFF:
JNB S1,$ ;是否按下了S1键?
ACALL Delay_10ms ;防抖
JB S1,$ ;放开了按键?
CLR Relay ;继电器吸合!
CLR P2.7
ACALL Delay_10ms ;延时一下
AJMP LOOP ;返回LOOP继续去检测输出状态
;---------------------延时约10MS----------------------------
Delay_10ms:
MOV R7,#23
F1: MOV R6,#200
DJNZ R6,$
DJNZ R7,F1
RET
END ;程序结束