📄 pcf8563.asm
字号:
;大字6位钟PCF8563 12MHz 6 digitals display
;2008/4/6 V2.0 PASSED!
SECFL BIT 08H;1S FLAG
READ EQU 0A3H;PCF8563读地址
WRIT EQU 0A2H;PCF8563写地址
SDA EQU P1.7;数据传送
SCL EQU P1.6;时钟控制状态
SETUP EQU P1.4;时间设定
UP EQU P1.3;加
DOWN EQU P1.2;减
DOT EQU P3.7;显示冒号
SEC DATA 30H;秒寄存器
MIN DATA 31H;分寄存器
HOUR DATA 32H;时寄存器
DAY DATA 33H;日寄存器
WEEK DATA 34H;周寄存器
MONTH DATA 35H;月寄存器
YEAR DATA 36H;年寄存器
SLA DATA 37H;37H为被控器的地址
NUMBYT DATA 38H;38H为数据字节计数器
DISBUF DATA 3AH;显示缓冲区
MRD DATA 40H;接收数据缓冲区首地址
MTD DATA 50H;发送数据缓冲区首地址
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP IN0INT
;主程序
MAIN: MOV SP,#5FH
MOV SCON,#0
MOV TCON,#1;INT0下降沿触发
SETB EA
SETZ:
LCALL DEL100
LCALL DEL100
LCALL INIT
LCALL DEL100
LCALL SETCLK;设定起始时间
P_INI: LCALL PCF_INI;PCF8563初始化
LCALL DEL100
LCALL PCF_SET;写入当前时间
SETB EX0
REACT: JNB SECFL, $
CLR SECFL
CLR DOT
LCALL DEL100
LCALL DEL100
LCALL DEL100
LCALL DEL100
LCALL DEL100
SETB DOT
LJMP REACT
;-----------------------------------
;初始化
INIT: MOV SEC,#00H;初始时间设定为12:30:00
MOV MIN,#30H
MOV HOUR,#12H
LCALL CLOCK;时分秒写入显示缓存
LCALL DISP
RET
;-------------------------------------------------------------------------
;PCF8563定时器工作模式,每秒产生一次中断
PCF_INI: MOV MTD,#0EH ;定时器控制寄存器地址送发送缓存MTD=50H
MOV MTD+1,#81H ;设置PCF8563的0EH为81H,启动定时器,定时器频率64Hz
MOV MTD+2,#64 ;设置PCF8563的0FH为64,定时器倒计数值为64
MOV NUMBYT,#3 ;写字节
MOV SLA,#0A2H ;取写器件地址
LCALL WRNBYT ;写8563
RET
;------------------------------
;每秒产生一次中断,读PCF8563
;IN0 INTERRUPT SERVICE
IN0INT:
PUSH PSW
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
MOV PSW,#8
LCALL PCF_RD ;读实时钟
LCALL CLOCK
LCALL DISP
SETB SECFL ;置秒标志
POP DPL
POP DPH
POP B
POP ACC
POP PSW
RETI
;PCF8563当前时间写入
PCF_SET: MOV SLA,#0A2H ;取写器件地址
MOV NUMBYT,#10 ;写字节数
MOV MTD,#00H ;写入8563寄存器首地址为00H
MOV MTD+1,#00H ;启动时钟
MOV MTD+2,#11H ;定时器为中断模式,脉冲形式
MOV MTD+3,SEC ;将秒至年的数据写入发送缓冲区
MOV MTD+4,MIN
MOV MTD+5,HOUR
MOV MTD+6,DAY
MOV MTD+7,WEEK
MOV MTD+8,MONTH
MOV MTD+9,YEAR
LCALL WRNBYT ;10个字节写入8563
RET
;-------------------------------------------------------
PCF_RD: MOV MTD,#02H ;读时钟寄存器首字节地址02H
MOV SLA,#0A2H ;取写器件地址
MOV NUMBYT,#1 ;写字节数
LCALL WRNBYT ;写n字节到8563
MOV SLA,#0A3H ;取读器件地址
MOV NUMBYT,#7 ;读7个时钟数据
LCALL RDNBYT ;读取时间并放入缓冲区
MOV A,MRD ;接收数据缓冲区首地址
ANL A,#7FH ;屏蔽无效位
MOV SEC,A ;送秒寄存器
MOV A,MRD+1 ;取分字节
ANL A,#7FH ;屏蔽无效位
MOV MIN,A ;送分寄存器
MOV A,MRD+2 ;取小时字节
ANL A,#3FH ;屏蔽无效位
MOV HOUR,A ;送时寄存器
MOV A,MRD+3 ;取天字节
ANL A,#3FH ;屏蔽无效位
MOV DAY,A ;送天寄存器
MOV A,MRD+4 ;取星期字节
ANL A,#07H ;屏蔽无效位
MOV WEEK,A ;送星期寄存器
MOV A,MRD+5 ;取月字节
ANL A,#1FH ;屏蔽无效位
MOV MONTH,A ;送月寄存器
MOV A,MRD+6 ;取年字节
MOV MONTH,A ;送年寄存器
RET
;-------------------------------------------------------------------------
;IIC总线操作子程序
STAR: SETB SDA;启动IIC总线
SETB SCL
NOP
NOP
CLR SDA
NOP
NOP
CLR SCL
RET
STOP: CLR SDA ;停止IIC总线数据传送
SETB SCL
NOP
NOP
SETB SDA
NOP
NOP
CLR SDA
CLR SCL
RET
MACK: CLR SDA ;发送应答位
SETB SCL
NOP
NOP
CLR SCL
SETB SDA
RET
MNACK: SETB SDA ;发送非应答位
SETB SCL
NOP
NOP
CLR SCL
CLR SDA
RET
CACK: SETB SDA ;应答位检查
SETB SCL
CLR F0
MOV C,SDA
JNC CEND
SETB F0
CEND: CLR SCL
RET
WRBYT: MOV R0,#08H ;向SDA线上发送1个数据字节
WLP: RLC A
JC WR1
AJMP WR00
WLP1: DJNZ R0,WLP
RET
WR1: SETB SDA
SETB SCL
NOP
NOP
CLR SCL
CLR SDA
AJMP WLP1
WR00: CLR SDA
SETB SCL
NOP
NOP
CLR SCL
AJMP WLP1
WRNBYT: MOV R3,NUMBYT ;向IIC总线发送n个字节数据
LCALL STAR
MOV A,SLA ;取写器件地址
LCALL WRBYT ;写入写器件地址
LCALL CACK
JB F0,WRNBYT
MOV R1,#MTD ;写入数据缓存首地址
WRDA: MOV A,@R1
LCALL WRBYT
LCALL CACK
JB F0,WRNBYT
INC R1
DJNZ R3,WRDA
LCALL STOP
RET
RDBYT: MOV R0,#08H ;从SDA线上读取1个数据字节
RLP: SETB SDA
SETB SCL
MOV C,SDA
MOV A,R2
RLC A
MOV R2,A
CLR SCL
DJNZ R0,RLP
RET
;从IIC总线接收n个字节数据
RDNBYT: MOV R3, NUMBYT ;读n个字节数据
LCALL STAR
MOV A,SLA ;取读器件地址
LCALL WRBYT ;写入读器件地址
LCALL CACK
JB F0,RDNBYT
MOV R1,#MRD ;读数据缓存首地址
RDN1: LCALL RDBYT ;读一个字节数据
MOV @R1,A
DJNZ R3,ACK
LCALL MNACK
LCALL STOP
RET
ACK: LCALL MACK
INC R1
SJMP RDN1
;------------------------------------
;时分秒写入显示缓存
CLOCK: MOV R0,#DISBUF
MOV R1,#SEC
MOV R2,#3
CL0: MOV A,@R1
ANL A,#0FH
MOV @R0,A
MOV A,@R1
SWAP A
ANL A,#0FH
INC R0
MOV @R0,A
INC R0
INC R1
DJNZ R2,CL0
RET
;delay 1Ms@12MHz
DEL01: MOV R7,#20
DEL00: MOV R6,#23
DJNZ R6,$
DJNZ R7,DEL00
RET
;delay 10Ms@12MHz
DEL10: MOV R7,#45
DEL1: MOV R6,#109
DJNZ R6,$
DJNZ R7,DEL1
RET
;Delay 100ms@12MHz
DEL100: MOV R7,#250
DEL11: MOV R6,#198
DJNZ R6,$
DJNZ R7,DEL11
RET
;显示子程序
DISP: PUSH PSW
MOV PSW,#10H
MOV R0,#DISBUF;显示
MOV A,#06H
MOV R2,A
DISP1: MOV A,@R0
ISPOT: MOV DPTR,#TABEL
MOVC A,@A+DPTR
LCALL REVERS
MOV SBUF,A
JNB TI,$
CLR TI
INC R0
DJNZ R2,DISP1
POP PSW
RET
TABEL:;共阴
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH;0123456789
DB 77H,7CH,39H,5EH,79H,71H,73H,76H,6EH,40H,00H;AbCdEFPHY-
REVERS: CLR C
RRC A
MOV 07H,C
RRC A
MOV 06H,C
RRC A
MOV 05H,C
RRC A
MOV 04H,C
RRC A
MOV 03H,C
RRC A
MOV 02H,C
RRC A
MOV 01H,C
RRC A
MOV 00H,C
MOV A,20H
RET
;设定当前时间子程序SETCLK
SETCLK: CLR DOT
MOV R0,#MRD
MOV @R0,#12
INC R0
MOV @R0,#30
DEC R0
SHOR: LCALL DEL100 ;小时加减
WAIT1: ORL P1,#1CH
MOV A,P1
JNB ACC.4,MINU ;转设定分
JNB ACC.3,ADDH
JNB ACC.2,SUBH
AJMP WAIT1
ADDH: LCALL DEL10
SETB UP
JB UP, WAIT1
MOV A,@R0
INC A
MOV @R0,A
AJMP DIS1
SUBH: LCALL DEL10
SETB DOWN
JB DOWN,WAIT1
MOV A,@R0
DEC A
MOV @R0,A
DIS1: MOV R1,#HOUR ;存入小时位
LCALL TOBCD
LCALL CLOCK
LCALL DISP
LCALL BP
AJMP SHOR
MINU: LCALL DEL10 ;分加减
SETB SETUP
JB SETUP,WAIT1
LCALL BP
SMIN: LCALL DEL100
INC R0
WAIT2: ORL P1,#1CH
MOV A,P1
JNB ACC.4,EXI
JNB ACC.3,ADDMI
JNB ACC.2,SUBMI
AJMP WAIT2
ADDMI: LCALL DEL10
SETB UP
JB UP,WAIT2
MOV A,@R0
INC A
MOV @R0,A
AJMP DIS2
SUBMI: LCALL DEL10
SETB DOWN
JB DOWN,WAIT2
MOV A,@R0
DEC A
MOV @R0,A
DIS2: MOV R1,#MIN ;存入分位
LCALL TOBCD ;转为BCD码
LCALL CLOCK ;时分秒写入显示缓存子程序
LCALL DISP ;显示子程序
LCALL BP
AJMP SMIN
EXI: LCALL DEL10
SETB SETUP
JB SETUP,WAIT2
LCALL BPL
SETB DOT
RET
;--------------------------------
;转为BCD码,存入时分位存储器
TOBCD: MOV B,#10
DIV AB ;A除以10,商在A中
SWAP A ;十位数换至高半字节
ADD A,B ;十位数加个位数
MOV @R1,A
RET
;=================================
BP: CLR DOT
LCALL DEL100
SETB DOT
RET
;===================================
BPL: MOV R5,#8;长声
BB: LCALL BP
DJNZ R5,BB
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -