编程实验
;*********************************************************************
;R0 单片机读写地址
;R1 DS1302读写地址
;
;
;R5/R6 延时程序的循环次数A
;R7 存储单元的循环次数
;0CH及第1组寄存器的R4 读写数据位的循环次数
SCLK Bit P2.5 ;实时时钟时钟线引脚
IO Bit P2.6 ;实时时钟数据线引脚
RST Bit P2.7 ;实时时钟复位线引脚
RS BIT P2.4
RW BIT P2.3
E BIT P2.2
LCD_FLAG BIT 20H.0
Pdate EQU P0
ZZ BIT P1.0
ZF BIT P1.1
YZ BIT P1.2
YF BIT P1.3
MUSIC BIT P1.4
REDNO1 EQU 40H
REDNO2 EQU 41H
DER EQU 43H ;方向变量
MKG EQU 42H ;音乐开关变量
Second EQU 44H ;秒
Minute EQU 45H ;分
Hour EQU 46H ;时
Day EQU 47H ;日
Month EQU 48H ;月
Week EQU 49H ;星期
Year EQU 4AH ;年
ORG 0000H
SJMP MAIN
ORG 0003H
LJMP INPUT0
ORG 0030H
MAIN: MOV SP,#50H
MOV MKG,#' '
MOV DER,#' '
SETB P3.2
CLR MUSIC
SETB EX0
SETB IT0 ;下降沿申请中断有效
SETB EA ;允许外部INT0申请中断
MOV REDNO1,#00H
MOV REDNO2,#00H
LCALL LCD_INIT ;LCD初始化
LCALL LCD_WORD ;把自创字符写入CGRAM?
;LCALL SET1302 ;第一次初始赋值之后,有备用电源就不用再初始
MAIN_1: LCALL GET1302
LCALL DISPLAY
LJMP MAIN_1
;========================================================================================================
;========================================================================================================
;========================================================================================================
;========================================================================================================
;***********************中断服务子程序INPUT0***********************
;程序功能:接收遥控码、解码、控制小车运行状态
;入口条件:P3.2
;出口参数:P1.4~P1.7
INPUT0: CLR EA ;关闭外部中断
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
SETB RS0 ;中断期间都是用第1组工作寄存器?
MOV REDNO1,#00H
MOV REDNO2,#00H
LCALL IRIN ;调用解码子程序
MOV A,REDNO1
CJNE A,#0E2H,BACK ;1110 0010判断用户码是否正确,不正确则退出
MOV A,REDNO2
CJNE A,#10H,KEY4
LCALL GO ;前进
SJMP BACK
KEY4: CJNE A,#18H,KEY5
LCALL LZ ;左转
SJMP BACK
KEY5: CJNE A,#04H,KEY6
LCALL STOP ;停止
SJMP BACK
KEY6: CJNE A,#14H,KEY9
LCALL RZ ;右转
SJMP BACK
KEY9: CJNE A,#1CH,KEYDG
LCALL HT ;后退
SJMP BACK
KEYDG: CJNE A,#0CCH,KEYTC
LCALL DG ;点歌
SJMP BACK
KEYTC: CJNE A,#054H,BACK
LCALL TC ;停唱
BACK: MOV R0,#10
I5: JNB P3.2,BACK ;10MS之内P3.2都为1再退出
LCALL DELAY882
DJNZ R0,I5
POP PSW
POP DPL
POP DPH
POP B
POP ACC
SETB EA ;开中断
RETI ;中断返回
;*****************************红外遥控解码子程序IRIN********************************
;程序功能:对接收编码进行解码,获取键号
;入口条件:P3.2
;出口参数:REDNO1和REDNO2
;红外线前导码
IRIN: ;开始读取操作数据
MOV R1,#REDNO1 ;读取数据存放的初始地址
MOV R2,#2 ;REDNO1和REDNO2共2个存放数据单元
IR_8B: MOV R3,#8
IR_4B: JNB P3.2,$ ;等待高电平出现
LCALL DELAY882 ;间隔882us判断P3.2的高低电平
MOV C,P3.2
JNC IR_0_1 ;C=0跳转
LCALL DELAY1120 ;延时1120us跳过查询下一波形
IR_0_1: MOV A,@R1
RLC A
MOV @R1,A
DJNZ R3,IR_4B ;8位用户码接收完了吗?
INC R1
DJNZ R2,IR_8B ;完成识别码、数据码解码
RET
;*********************判断按键号后的具体操作****************
GO: SETB ZZ
CLR ZF
SETB YZ
CLR YF
MOV DER,#3H
RET
STOP: CLR ZZ
CLR ZF
CLR YZ
CLR YF
MOV DER,#' '
RET
RZ: SETB ZZ
CLR ZF
CLR YZ
CLR YF
MOV DER,#7EH;向右箭号代码
RET
LZ: CLR ZZ
CLR ZF
SETB YZ
CLR YF
MOV DER,#7FH;向左箭号代码
RET
HT: CLR ZZ
SETB ZF
CLR YZ
SETB YF
MOV DER,#4H
RET
DG: SETB MUSIC
MOV MKG,#'$'
RET
TC: CLR MUSIC;停唱
MOV MKG,#' '
RET
;**************300us延时子程序******************
DELAY300:
MOV R7,#130
TIM0:
NOP
NOP
DJNZ R7,TIM0
RET
;**************882us延时子程序******************
DELAY882:
MOV R7,#202
TIM1: NOP
NOP
DJNZ R7,TIM1
RET
;**************1120US延时子程序******************
DELAY1120:
MOV R7,#224
TIM2: NOP
NOP
NOP
DJNZ R7,TIM2
RET
;========================================================================================================
;========================================================================================================
;========================================================================================================
;========================================================================================================
;==========LCM初始化程序===========
LCD_INIT: ;热启动
CALL DL10MS
MOV A,#38H
CLR LCD_FLAG
CALL LCD_WRC
CALL DL5MS
CALL LCD_WRC
CALL DL120US
CALL LCD_WRC
CALL DL120US
SETB LCD_FLAG;设忙
MOV A,#38H ;功能设置为2行显示,8位数据?
ACALL LCD_WRC
MOV A,#01H
ACALL LCD_WRC
MOV A,#06H
ACALL LCD_WRC
MOV A,#0CH
ACALL LCD_WRC
RET
;==============显示子程序============
;功 能:时钟显示
;入口条件:50H~ 56H ,存放秒~年
DISPLAY:MOV DPTR,#TAB
MOV A,#80H ;在第一行中间位置
CALL LCD_WRC ;写命令
MOV A,Year
CALL CHAIZI
MOV A,#0 ;显示年
CALL LCD_WRTD
MOV A,Month
CALL CHAIZI
MOV A,#1 ;显示月
CALL LCD_WRTD
MOV A,Day
CALL CHAIZI
MOV A,#2 ;显示日
CALL LCD_WRTD
MOV A,#' ' ;显示' '
CALL LCD_WRTD
MOV A,#' '
CALL LCD_WRTD
MOV A,Week ;显示星期
CALL CHAIZI
MOV A,#0C3H ;在第二行中间位置
CALL LCD_WRC
MOV A,Hour
CALL CHAIZI
MOV A,#':' ;显示时间分隔符
CALL LCD_WRTD
MOV A,Minute
CALL CHAIZI
MOV A,#':' ;显示时间分隔符
CALL LCD_WRTD
MOV A,Second
CALL CHAIZI
MOV A,#0CEH ;在第二行后面位置显示小车行走方向
CALL LCD_WRC
MOV A,DER
CALL LCD_WRTD
MOV A,MKG ;音乐开与关
CALL LCD_WRTD
RET
;============拆字显示==============
CHAIZI: MOV B,A ;先保存原始数据
ANL A,#0F0H;相与 ;先显示十位
SWAP A
MOVC A,@A+DPTR
CALL LCD_WRTD
MOV A,B ;后显示个位
ANL A,#0FH
MOVC A,@A+DPTR
CALL LCD_WRTD
RET
;=============写命令===========
;入口地址:A
LCD_WRC:
JNB LCD_FLAG,L1 ;不忙时直接跳转
CALL DL5MS ;等待到不忙
L1: CLR RS
CLR RW
SETB E
MOV Pdate,A
CLR E
RET
;============写数据=============
;入口地址:A
LCD_WRTD:
CALL DL5MS ;延时代查忙
SETB RS
CLR RW
SETB E
MOV Pdate,A
CLR E
RET
;==============延时子程序===============
DL10MS: CALL DL5MS
CALL DL5MS
RET
DL5MS: MOV R6,#5
D0: MOV R5,#250
D1: NOP
NOP
DJNZ R5,D1
DJNZ R6,D0
RET
DL120US:MOV R5,#30
D2: NOP
NOP
DJNZ R5,D1
RET
;===========把自创字符写入CGRAM程序==============
;=====
LCD_WORD:
MOV A,#40H ;设置CGRAM的首地址为00H
LCALL LCD_WRC ;写命令
MOV R3,#56 ;写入24个字符码
MOV DPTR,#TAB1
MOV R4,#00H ;偏移量初始值
NEXT: MOV A,R4
MOVC A,@A+DPTR
LCALL LCD_WRTD
INC R4
DJNZ R3,NEXT
RET
TAB: DB '0','1','2','3','4','5','6','7','8','9'
TAB1: DB 08H,0FH,12H,0FH,0AH,1FH,02H,00H ;年
DB 0FH,09H,0FH,09H,0FH,09H,13H,00H ;月
DB 0FH,09H,09H,0FH,09H,09H,0FH,00H ;日
;向上
;-- 宽度x高度=8x8 --
DB 00H,04H,0EH,15H,04H,04H,04H,00H
;向下
;-- 宽度x高度=8x8 --
DB 04H,04H,04H,15H,0EH,04H,00H,00H
;========================================================================================================
;========================================================================================================
;========================================================================================================
;========================================================================================================
;DS1302时钟芯片
;**********************************************************
;功 能:设置DS1302 初始时间,并启动计时。
;**********************************************************
SET1302:MOV Second,#38H ;给初始值
MOV Minute,#39H
MOV Hour,#18H
MOV Day,#20H
MOV Month,#12H
MOV WEEK,#01H
MOV Year,#10H
MOV A,#8EH ;写操作寄存器
MOV B,#00H ;允许写,将WP =0
LCALL CLOCK_WR ;调用写子程序
MOV R0,#Second ;单片机年地址
MOV R7,#7 ;循环7次
MOV R1,#80H ;DS1302秒写地址
S13021: MOV A,R1 ;秒 分 时 日 月 星期 年 的地址
MOV B,@R0 ;单片机地址R0所对应的值
LCALL CLOCK_WR ;调用写子程序
INC R0
INC R1
INC R1
DJNZ R7,S13021
MOV A,#8EH ;写操作寄存器
MOV B,#80H ;WP=1,写保护
LCALL CLOCK_WR
RET
Get1302:MOV A,#8DH ;年
LCALL CLOCK_RD
MOV YEAR,A
MOV A,#8BH ;星期
LCALL CLOCK_RD
MOV WEEK,A
MOV A,#89H ;月
LCALL CLOCK_RD
MOV Month,A
MOV A,#87H ;日
LCALL CLOCK_RD
MOV Day,A
MOV A,#85H ;时
LCALL CLOCK_RD
MOV Hour,A
MOV A,#83H ;分
LCALL CLOCK_RD
MOV Minute,A
MOV A,#81H ;秒
LCALL CLOCK_RD
MOV Second,A
RET
;**********************************************************
;**********************************************************
;功 能:从DS1302 读数据子程序
;**********************************************************
;功 能:读数据子程序 八位
;入口参数:A存放要读的数据 地址
;出口参数:A存放读取的数据
;**********************************************************
CLOCK_RD:
CLR RST
CLR SCLK
SETB RST ;选通DS1302
MOV R4,#8
Outbit1:RRC A
MOV IO,C ;通过IO口输出一位寄存器写地址
CLR SCLK
SETB SCLK ;发个输出脉冲
DJNZ R4,Outbit1
CLR SCLK
NOP ;延时,防止后面串行读数据丢失
SETB IO ;将单片机对应的IO口设为输入端口
MOV R4,#8
Outbit2:MOV C,IO ;经IO口读入一位数据
RRC A ;通过IO口输出一位寄存器写地址
SETB SCLK
CLR SCLK
DJNZ R4,Outbit2
RET
;**********************************************************
;功 能:写数据子程序 八位
;入口参数:A/B分别存放要写入的地址和数据
;**********************************************************
CLOCK_WR:
CLR RST
CLR SCLK
SETB RST ;选通DS1302
MOV R4,#8
Inbit1: RRC A
MOV IO,C ;通过IO口输出一位寄存器写地址
CLR SCLK
SETB SCLK
DJNZ R4,Inbit1
NOP
MOV A,B ;将待写入数据送到A
MOV R4,#8
Inbit2: RRC A
MOV IO,C ;通过IO口输出一位寄存器写地址
CLR SCLK
SETB SCLK
DJNZ R4,Inbit2
RET
END
全部0条评论
快来发表一下你的评论吧 !
看不懂 收起回复