作者:未知 来源:89s52.cn
; *************************************
; * *
; * 遥控编码控制器 *
; * *
; * 采用89C2051 *
; *************************************
;
; P1.0口按纽为前进,P1.1口按纽为后退,P1.2口按纽为左转弯,P1.3口按纽为右转弯,
; P1.4口按纽为自动驾驶,P3.5为编码输出
;
;*************************************
;* *
;* 主程序和中断程序入口 *
;* *
;*************************************
ORG 0000H ;程序执行开始地址
LJMP START ;跳至START执行
ORG 0003H ;外中断0中断入口地址
RETI ;中断返回(不开中断)
ORG 000BH ;定时器T0中断入口地址
RETI ;中断返回(不开中断)
ORG 0013H ;外中断1中断入口地址
RETI ;中断返回(不开中断)
ORG 001BH ;定时器T1中断入口地址
RETI ;中断返回(不开中断)
ORG 0023H ;串行口中断入口地址
RETI ;中断返回(不开中断)
ORG 002BH ;定时器T2中断入口地址
RETI ;中断返回(不开中断)
;
;*************************************
;* *
;* 初始化程序中的各变量 *
;* *
;*************************************
CLEARMEMIO: CLR A ;清A
DEC A ;A为#0FFH
MOV P1,A ; P1口置1
MOV P3,A ; P3口置1
MOV IE,#00H ;关所有中断
RET ;子程序返回
;
;
;
;*************************************
;* *
;* 主 程 序 *
;* *
;*************************************
START: LCALL CLEARMEMIO ;调用初始化
; 主体程序
MAIN: LCALL KEYWORK ;调用查键子程序
LJMP MAIN ;转MAIN循环
NOP ;PC值出错处理
NOP
NOP
LJMP START ;转START重新启动
;
;**************************
;* *
;* 键盘工作子程序 *
;**************************
KEYWORK: MOV P1,#0FFH ;置输入状态
JNB P1.0,KEY0 ; 读P1.0口,为0转KEY0
JNB P1.1,KEY1 ; 读P1.1口,为0转KEY1
JNB P1.4,KEY4 ; 读P1.4口,为0转KEY4
KEYOUT: RET ;没键按下,退出
;
KEY0: LCALL DL10MS ;延时10毫秒消抖
JB P1.0,KEYOUT ;干扰,退出
LJMP KEYFUN00 ;转KEYFUN00
KEY1: LCALL DL10MS ;
JB P1.1,KEYOUT ; 干扰,退出
LJMP KEYFUN01 ; 转KEYFUN01
KEY2: LCALL DL10MS ; 延时10毫秒消抖
JB P1.2,KEYOUT ; 干扰,退出
LJMP KEYFUN02 ; 转KEYFUN02
KEY3: LCALL DL10MS ; 延时10毫秒消抖
JB P1.3,KEYOUT ; 干扰,退出
LJMP KEYFUN03 ; 转KEYFUN03
KEY4: LCALL DL10MS ; 延时10毫秒消抖
JB P1.4,KEYOUT ; 干扰,退出
LJMP KEYFUN04 ; 转KEYFUN04
KEYWORK1: JNB P1.2,KEY2 ;P1.2口为0转KEY2
JNB P1.3,KEY3 ; P1.3口为0转KEY3
LCALL KEYFUN05 ;调转弯复位子程序
RET ;返回
;
KEYFUN00: MOV A,#02H ;发2个脉冲赋值
LCALL REMOTE ;发射2个脉冲(前进)
WAIT0: LCALL KEYWORK1 ;调一次转弯查键子程序
JNB P1.0,WAIT0 ;等待按键释放
LCALL KEYFUN06 ;释放时发8个脉冲(停止)
RET ;返回
;
KEYFUN01: MOV A,#03H ;发3个脉冲赋值
LCALL REMOTE ;发射3个脉冲(前进)
WAIT1: LCALL KEYWORK1 ;调一次转弯查键子程序
JNB P1.1,WAIT1 ;等待按键释放
LCALL KEYFUN06 ;释放时发8个脉冲(停止)
RET ;
;
KEYFUN02: MOV A,#04H ;发4个脉冲赋值
LCALL REMOTE ;发射4个脉冲(左转)
JNB P1.2,KEYOUT1 ;键按下不放,转KEYOUT1返回
LCALL DL10MS ;左转键放开,延时10毫秒
JNB P1.2,KEYOUT1 ;为0(干扰),转KEYOUT1返回
LCALL KEYFUN05 ;左转键放开发7个脉冲(转弯复位)
RET ;返回
;
KEYFUN03: MOV A,#05H ;发5个脉冲赋值
LCALL REMOTE ;发射5个脉冲(右转)
JNB P1.3,KEYOUT1 ;键按下不放,转KEYOUT1返回
LCALL DL10MS ;右转键放开,延时10毫秒
JNB P1.3,KEYOUT1 ;为0(干扰),转KEYOUT1返回
LCALL KEYFUN05 ;右转键放开发7个脉冲(转弯复位)
RET ;返回
KEYOUT1: LJMP KEYOUT ;跳至KEYOUT返回
;
KEYFUN04: JNB P1.4,KEYFUN04 ;等待按键释放
LCALL DL10MS ;延时消抖动
JNB P1.4,KEYFUN04 ;P1.4为0,系干扰,转KEYFUN04再等待
MOV A,#06H ;按键释放,发6个脉冲(进入自动驾驶)
LCALL REMOTE ;发射一次
RET ;返回
;
KEYFUN05: MOV A,#07H ;发7个脉冲程序(转弯复位)
LCALL REMOTE ;发射一次
RET ;返回
KEYFUN06: MOV A,#08H ;发8个脉冲程序(停车)
LCALL REMOTE ;发射一次
RET ;返回
;
;
;*************************************
;* *
;* 编码发送程序 *
;* *
;*************************************
;按A中数值发射脉冲
REMOTE: MOV R1,A ;发射脉数入A
LJMP OUT3 ;第一个脉冲处理
OUT: MOV R0,#55H ;1MS脉宽定时值
OUT1: CLR P3.5 ;发低电平脉宽
NOP ;延时循环(周期约为21微秒)
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R0,OUT1 ;定时时间未到,转OUT1循环
MOV R0,#55H ;1MS脉宽定时值
OUT2: SETB P3.5 ;发高电平脉宽
NOP ;延时循环(周期约为21微秒)
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R0,OUT2 ;定时时间未到,转OUT2循环
DJNZ R1,OUT ;脉冲数未发完转OUT再循环
LCALL DL10MS ;脉冲发完延时10毫秒
RET ;返回
OUT3: MOV R0,#0FFH ;3MS脉宽定时值
LJMP OUT1 ;转OUT1红外线发射
;
;
;
;*************************************
;* *
;* 延时 255 X 2 = 512 us *
;* *
;*************************************
DELAY: MOV R2,#0FFH
DELAY1: DJNZ R2,DELAY1
RET
;
;*************************************
;* *
;* 延时10ms程序 *
;* (消按键抖动用) *
;*************************************
DL10MS: MOV R3,#14H
DL10MS1: LCALL DELAY
DJNZ R3,DL10MS1
RET
DL500MS: MOV R4,#32H
DL500MS1: LCALL DL10MS
DJNZ R4,DL500MS1
RET
;
;
END ;程序结束