- UID
- 111482
- 帖子
- 5976
- 积分
- 19792
- 威望
- 13159
- 金币
- 4654721
- 贡献
- 6623
- 职业
- 单片机编程家电维修
- 注册时间
- 2007-9-21
- 最后登录
- 2012-1-7
|
1#
发表于 2009-4-13 12:45
| 只看该作者
TLOW EQU 0B0H ;50ms定时初值
THIGH EQU 3CH
HOUR EQU 30H ;时存放单元
MIN EQU 31H ;分存放单元
SEC EQU 32H ;秒存放单元
SEC0 EQU 33H ;10MS计数值存放单元
LCD_X EQU 33H ;LCD 地址变量
JSJC EQU 34H ;遥控接收寄存器
num equ 35h ;键值
KEYCS EQU 36H ;按键次数
KGJS EQU 37H ;开关计数
HOUR1 EQU 38H ;时存放单元
MIN1 EQU 39H ;分存放单元
SEC1 EQU 3AH ;秒存放单元
SW EQU 00H ;开关标志
key_dn EQU 01H ;键盘按下标志
BEEPBZ EQU 02H ;蜂鸣器控制标志
BEEPBZ1 EQU 03H ;1分钟倒计时蜂鸣器标志
BEEP EQU P3.7 ;蜂鸣器控制端口
JST EQU P3.2 ;接收头
JDQ EQU P1.0 ;继电器
LCD_RS EQU P2.0 ;LCD控制端口
LCD_RW EQU P2.1
LCD_EN EQU P2.2
************************************************
*知识产权徐州天联电子城曹广连 *
*原创程序不得用于商业用途 *
*晶振12MHZ *
*液晶屏1602 *
*遥控器M50462 *
************************************************
ORG 0000H
JMP MAIN
org 0003h
ljmp red
ORG 0BH
JMP T0_INT
ORG 0030H
;----------------------------------------------------
MAIN: MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH
MOV 20,#00H
MOV R1,#11
MOV R0,#30H
DF: MOV @R0,#00H
INC R0
DJNZ R1,DF
MOV SP,#60H ;设堆栈初值
LCALL BEEP_BL ;开接收键音
CALL INIT_LCD ;初始化LCD
CALL SET_LCD1 ;第一行显示信息
MOV R5,#30
CALL MENU ;第二行滚动显示
MAIN1: CALL DELAY100 ;停留3S。
DJNZ R5,MAIN1
CALL INIT_LCD ;初始化LCD
CALL SET_LCD1 ;第一行显示信息
CALL INIT ;初始化变量
CALL INIT_TIMER ;初始化定时器
CALL CONV
LOOP: NOP
NOP
AJMP LOOP
;-------------------------------以下遥控接收程序
red: PUSH Acc
PUSH PSW ;加中断保护
SETB RS0
clr ex0 ;关中断
mov r2,#16 ;接收16位数抛弃前8位
mov a,#00 ;后8位是真正需要的数据
jnb p3.2,red1 ;有跳变转识别
redret: CLR RS0 ;没有返回
POP PSW
POP Acc ;恢复中断现场
setb ex0 ;开中断
reti ;返回
;----------------------------------------------------
red1: jnb JST,$ ;识别红外数据
lcall d920us ;因为M50462遥控器0是1.05MS
mov c,JST ;读入
jnc setdata0 ;0是1.05MS代表
lcall d1050us ;1是2.10MS代表
mov c,JST
jnc setdata1
ajmp redret ;错误抛弃返回
setdata0: rrc a ;数据0移入A
djnz r2,red1
ajmp redout
setdata1: setb c
rrc a ;数据1移入A
djnz r2,red1
redout: MOV NUM,A ;得到键值暂存
CJNE A,#00001001B,TT1 ;0
MOV NUM,#0 ;保存键值
AJMP TT12
TT1: CJNE A,#00000000B,TT2 ;1
MOV NUM,#1 ;保存键值
AJMP TT12
TT2: CJNE A,#00001000B,TT3 ;2
MOV NUM,#2 ;保存键值
AJMP TT12
TT3: CJNE A,#00010000B,TT4 ;3
MOV NUM,#3 ;保存键值
AJMP TT12
TT4: CJNE A,#00011000B,TT5 ;4
MOV NUM,#4 ;保存键值
AJMP TT12
TT5: CJNE A,#00100000B,TT6 ;5
MOV NUM,#5 ;保存键值
AJMP TT12
TT6: CJNE A,#00101000B,TT7 ;6
MOV NUM,#6 ;保存键值
AJMP TT12
TT7: CJNE A,#00110000B,TT8 ;7
MOV NUM,#7 ;保存键值
AJMP TT12
TT8: CJNE A,#00111000B,TT9 ;8
MOV NUM,#8 ;保存键值
AJMP TT12
TT9: CJNE A,#00000001B,TT10 ;9
MOV NUM,#9 ;保存键值
AJMP TT12
TT10: CJNE A,#00000010B,TT11 ;K
MOV NUM,#10 ;保存键值
TT12:
AJMP JCL ;以上键值有效
TT11: LCALL BEEP_BL ;开接收键音
ajmp redret
d920us:
mov r6,#2
d920us2:
mov r7,#228
d920us1:
djnz r7,$
djnz r6,d920us2
ret
d1050us:
mov r6,#10
d1050us2:
mov r7,#52
d1050us1:
djnz r7,$
djnz r6,d1050us2
ret
;得到的M50462键值声明码值是反的------------------------------
; 0 00001001B
; 1 00000000B
; 2 00001000B
; 3 00010000B
; 4 00011000B
; 5 00100000B
; 6 00101000B
; 7 00110000B
; 8 00111000B
; 9 00000001B
; K 00000010B
;-------------------------------------以上遥控接收程序
;键值处理---------------------------------------------
JCL: MOV A,NUM
CJNE A,#10,HJK
AJMP RETLOOP
HJK:
INC KEYCS ;按键次数
CLR BEEPBZ1 ;1分钟倒计时蜂鸣器标志
CLR TR0
SETB JDQ ;关继电器
CLR SW ;倒计时关
MOV SEC,#00H
MOV A,KEYCS
CJNE A,#1,TU0 ;1
ANL HOUR,#0FH ;加载小时数据
MOV A,NUM
SWAP A
ORL HOUR,A ;十时
CALL CONV
AJMP TT11
TU0: CJNE A,#2,TU1
ANL HOUR,#0F0H ;加载小时数据
MOV A,NUM
ORL HOUR,A ;小时个位
CALL CONV
AJMP TT11
TU1: CJNE A,#3,TU2
ANL MIN,#0FH ;3次分十位
MOV A,NUM
SWAP A
ORL MIN,A
CALL CONV
AJMP TT11
TU2: CJNE A,#4,TU3
ANL MIN,#0F0H ;4次分个位
MOV A,NUM
ORL MIN,A
TU3:
MOV KEYCS,#00H
CALL CONV
AJMP TT11
RETLOOP: JB SW,TU5
MOV A,HOUR ;判断小时十位
ANL A,#0F0H
SWAP A
JNZ TU4 ;=0
TU7: MOV A,MIN
ANL A,#0F0H
SWAP A
CLR C
SUBB A,#6
JNC TU5
AJMP TU6
TU4: CJNE A,#1,TU5
MOV A,HOUR
ANL A,#0FH
CLR C
SUBB A,#3
JNC TU5
AJMP TU7
TU5: CLR TR0
SETB JDQ ;关继电器
CLR SW ;倒计时关
MOV KEYCS,#00H
AJMP TT11
TU6:
SETB TR0
SETB SW ;倒计时开始
CLR JDQ ;继电器开
MOV KEYCS,#00H
AJMP TT11
;设置LCD初始化显示
;--------------------------------------------------------
SET_LCD1:
MOV DPTR,#LMESS1 ;指针指到显示信息1
MOV A,#1 ;显示在第一行
CALL LCD_PRINT
RET
SET_LCD2:
MOV DPTR,#LMESS2 ;指针指到显示信息2
MOV A,#2 ;显示在第二行
CALL LCD_PRINT
RET
LMESS1:
DB " TIME ",0 ;LCD 第一行显示
LMESS2:
DB " 00:00:00 ",0 ;LCD 第二行显示
;--------------------------------------------------------
;LCD 初始化子程序
;8位数据传送方式,双行显示,字形5*7点阵。
;开显示,不显示光标。
;--------------------------------------------------------
INIT_LCD:
CALL DELAY5MS ;延时15MS
CALL DELAY5MS
CALL DELAY5MS
MOV A,#38H ;双行显示,字形5*7点阵,8位数据。
CALL WCOM_NC ;不检测忙信号
CALL DELAY5MS
MOV A,#38H ;双行显示,字形5*7点阵
CALL WCOM_NC ;不检测忙信号
CALL DELAY5MS
MOV A,#38H ;双行显示,字形5*7点阵
CALL WCOM_NC ;不检测忙信号
CALL DELAY5MS
MOV A,#38H ;双行显示,字形5*7点阵
CALL WCOM ;检测忙信号
CALL DELAY5MS
MOV A,#0CH ;开显示,不显示光标,光标不闪烁。
CALL WCOM
CALL DELAY5MS
MOV A,#01H ;清除 LCD 显示屏
CALL WCOM
CALL DELAY5MS
RET
;--------------------------------------------------------
;初始化控制变量
;--------------------------------------------------------
INIT:
CLR A
MOV SEC0,A
MOV SEC,A
MOV MIN,A
MOV HOUR,A
SETB BEEP
CLR TR0
RET
;--------------------------------------------------------
;初始化定时器子程序
;设置定时器0 工作模式为模式1
;启用定时器0 产生中断
;--------------------------------------------------------
INIT_TIMER:
MOV TMOD,#01H
MOV IE, #83H
MOV TL0,#TLOW
MOV TH0,#THIGH
RET
;--------------------------------------------------------
;定时器0计时中断服务子程序
;定时器0,方式1
;50ms中断一次
;--------------------------------------------------------
T0_INT: PUSH PSW
PUSH ACC
MOV TL0,#TLOW
MOV TH0,#THIGH
JNB SW,NEXTT ;判断当前倒计时1开状态0关跳出
INC SEC0
MOV A,SEC0 ;10MS 计数值加1
CJNE A,#20,NEXTT ;1秒到
MOV SEC0,#0 ;清20MS单元
T0_INTM: LCALL BCDH
MOV A,SEC1
CJNE A,#00,JIANMIAO;判断秒是否为0,不为0就秒减1
MOV SEC1,#59
MOV A,MIN1
CJNE A,#00,JIANFEN;判断分是否为0,不为0则分减1
MOV MIN1,#59
MOV A,HOUR1
CJNE A,#00,JIANSHI;判断时是否为0,不为0则时减1
MOV SEC0,#0
MOV SEC,#0 ;秒、分、时单元清零
MOV MIN,#0
MOV HOUR,#0
SETB JDQ ;关继电器
CLR SW ;倒计时停止标志
SETB BEEP
CLR BEEPBZ1 ;1分钟倒计时蜂鸣器标志
NEXTT:
POP ACC
POP PSW
RETI
QAZ: CLR BEEPBZ ;1分钟没倒清蜂鸣器标志
AJMP T0_INTM
JIANMIAOEC SEC1 ;SEC减1
JNB BEEPBZ1,KIO
CPL BEEP
KIO:
LCALL HBCD
CALL CONV
AJMP NEXTT
JIANFEN: MOV A,MIN1
CJNE A,#01H,JIANFEN1
SETB BEEPBZ1 ;1分钟倒计时蜂鸣器标志----
JIANFEN1EC MIN1
LCALL HBCD
CALL CONV
AJMP NEXTT
JIANSHI: DEC HOUR1;HOUR减1
LCALL HBCD
CALL CONV
AJMP NEXTT
;--------------------------------------------------------
;时间数据转换为 ASCII 码并显示
;--------------------------------------------------------
CONV:
MOV A,HOUR ;加载小时数据
MOV LCD_X,#5 ;设置位置
CALL SHOW_DIG2 ;显示数据
INC LCD_X ;
MOV A,#':' ;显示“:”
MOV B,LCD_X ;
CALL LCDP2 ;
MOV A,MIN ;加载分钟数据
INC LCD_X ;设置位置
CALL SHOW_DIG2 ;显示数据
INC LCD_X ;
MOV A,#':' ;显示“:”
MOV B,LCD_X ;
CALL LCDP2 ;
MOV A,SEC ;加载秒数数据
INC LCD_X ;设置位置
CALL SHOW_DIG2 ;显示数据
RET
;--------------------------------------------------------
;在LCD1602的第二行显示数字
;--------------------------------------------------------
SHOW_DIG2:MOV B,A
ANL A,#0F0H
SWAP A
ADD A,#30H ;A为十位数,转换为字符
PUSH B ;B放入堆栈暂存
MOV B,LCD_X ;设置 LCD 显示的位置
CALL LCDP2 ;由 LCD 显示出来
POP B ;
MOV A,B ;B为个位数
ANL A,#0FH
ADD A,#30H ;转换为字符
INC LCD_X ;LCD 显示位置加1
MOV B,LCD_X ;设置 LCD 显示的位置
CALL LCDP2 ;由 LCD 显示出来
RET
;--------------------------------------------------------
;在LCD的第二行显示字符
;--------------------------------------------------------
LCDP2:
PUSH ACC ;入栈保护
MOV A,B ;设置显示地址
ADD A,#0C0H ;设置LCD的第二行地址
CALL WCOM ;写入命令
POP ACC ;由堆栈取出A
CALL WDATA ;写入数据
RET
;--------------------------------------------------------
;在LCD的第一行或第二行显示字符
;--------------------------------------------------------
LCD_PRINT:
CJNE A,#1,LINE2 ;判断是否为第一行
LINE1: MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
JMP FILL
LINE2: MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM
FILL: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息区取出字符
CJNE A,#0,LC1 ;判断是否为结束码
RET
LC1: CALL WDATA ;写入数据
INC DPTR ;指针加1
JMP FILL ;继续填入字符
RET
;--------------------------------------------------------
;清除 LCD 指定行的字符
;“空白”的ASCII代码为20H。
;--------------------------------------------------------
CLR_LINE:
MOV R0,#24
CL1: MOV A,#20H ;' '
CALL WDATA
DJNZ R0,CL1
RET
;--------------------------------------------------------
;写控制指令子程序
;写控制指令到LCD
;传入参数: ACC(要写入的指令)
;RS=L,RW=L,E=高脉冲,D0-D7=指令码 。
;--------------------------------------------------------
WCOM:
ACALL CHECKBUSY
WCOM_NC:
MOV P0,A ;写入指令
CLR LCD_EN
NOP
NOP
CLR LCD_RS
CLR LCD_RW
SETB LCD_EN
ACALL DEL_250
CLR LCD_EN
RET
;--------------------------------------------------------
;写数据子程序
;写显示数据到LCD
;传入参数: ACC(要写入的数据)
;RS=H,RW=L,E=高脉冲,D0-D7=数据码 。
;--------------------------------------------------------
WDATA:
ACALL CHECKBUSY
MOV P0,A ;写入数据
CLR LCD_EN
NOP
NOP
SETB LCD_RS
CLR LCD_RW
SETB LCD_EN
CALL DEL_250
CLR LCD_EN
RET
DEL_250:
MOV R7,#125 ;延时250微秒
DJNZ R7,$
RET
;--------------------------------------------------------
;检测LCD控制器忙碌状态
;正常读写操作之前必须检测LCD控制器状态
;BUSY FLAG(P0.7)=1时,忙,不能接收MCU送来的指令和数据。
;BUSY FLAG(P0.7)=0时,闲,能够接收MCU送来的指令和数据。
;读数据时
;RS=L,RW=H,E=H,输出:D0-D7=数据
;--------------------------------------------------------
CHECKBUSY:
PUSH ACC
MOV P0,#0FFH ;置P0口为输入状态
CLR LCD_EN
NOP
NOP
SETB LCD_RW
CLR LCD_RS
SETB LCD_EN
BUSYLOOP:
NOP
JB P0.7,BUSYLOOP
CLR LCD_EN
POP ACC
RET
;--------------------------------------------------------
;蜂鸣器响一声子程序
;驱动蜂鸣器
;--------------------------------------------------------
BEEP_BL:
MOV R4,#100
CLR BEEP
BL1: CALL DELAY5MS
DJNZ R4,BL1
SETB BEEP
RET
;--------------------------------------------------------
;延时5MS子程序
;--------------------------------------------------------
DELAY5MS:
MOV R6,#25
DEL1: MOV R7,#100
DJNZ R7,$
DJNZ R6,DEL1
RET
;--------------------------------------------------------
;第二行滚动显示子程序
;--------------------------------------------------------
MENU:
MOV A,#06H ;移动光标(光标加1)
CALL WCOM
CALL DELAY5MS
MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM
MOV DPTR,#CHAR
FILL1: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息区取出字符
CJNE A,#0,LC2 ;判断是否为结束码
RET
LC2: CALL WDATA ;写入数据
INC DPTR ;指针加1
CALL DELAY100
CALL DELAY100
JMP FILL1 ;继续填入字符
RET
CHAR:
DB " XZJZZYJSXY",0;开机显示字符随便你该
;--------------------------------------------------
;延时100MS子程序
;--------------------------------------------------
DELAY100:
MOV r7,#200
DL1: MOV r6,#250
DL2: DJNZ R6,DL2
DJNZ R7,DL1
RET
;16-BCD子程序为了加快转换程序速度---分别转换--------
HBCD:
MOV A,HOUR1
MOV B,#10 ;余数继续分离十位和个位
DIV AB
SWAP A
ORL A,B ;将十位和个位拼装成BCD码
MOV HOUR,A
MOV A,MIN1
MOV B,#10 ;余数继续分离十位和个位
DIV AB
SWAP A
ORL A,B ;将十位和个位拼装成BCD码
MOV MIN,A
MOV A,SEC1
MOV B,#10 ;余数继续分离十位和个位
DIV AB
SWAP A
ORL A,B ;将十位和个位拼装成BCD码
MOV SEC,A
RET
BCDH:
MOV A,HOUR
ANL A,#0F0H
SWAP A
MOV B,#10
MUL AB
MOV R4,A
MOV A,HOUR
ANL A,#0FH
ADD A,R4
MOV HOUR1,A
MOV A,MIN
ANL A,#0F0H
SWAP A
MOV B,#10
MUL AB
MOV R4,A
MOV A,MIN
ANL A,#0FH
ADD A,R4
MOV MIN1,A
MOV A,SEC
ANL A,#0F0H
SWAP A
MOV B,#10
MUL AB
MOV R4,A
MOV A,SEC
ANL A,#0FH
ADD A,R4
MOV SEC1,A
RET
;--------------------------------------------------
END |
|