初学者:DS12C887与AT89C51
采用AT89C51与DS12C887做一时钟,段驱动用MC14511,位选用74LS154,先是采用总线形式
(P0)失败,后采用模拟DS12C887时序:(AS--ALE)改为(AS--P3.0),其它连线不变,依然失
败。请指点迷津,谢谢!程序如下:
SECOND EQU 00H ;秒暂存器
SECOND_ALARM EQU 01H ;秒闹铃暂存器
MINUTE EQU 02H ;分暂存器
MINUTE_ALARM EQU 03H ;分闹铃暂存器
HOUR EQU 04H ;时暂存器
HOUR_ALARM EQU 05H ;时闹铃暂存器
WEEK EQU 06H ;星期暂存器
DATE EQU 07H ;日暂存器
MONTH EQU 08H ;月暂存器
YEAR EQU 09H ;年暂存器
REG_A EQU 0AH ;暂存器 A
REG_B EQU 0BH ;暂存器 B
REG_C EQU 0CH ;暂存器 C
REG_D EQU 0DH ;暂存器 D
CENTURY EQU 32H ;世纪暂存器
SECOND_BUFFER EQU 50H ;秒缓冲器
MINUTE_BUFFER EQU 51H ;分缓冲器
HOUR_BUFFER EQU 52H ;时缓冲器
WEEK_BUFFER EQU 53H ;星期缓冲器
DATE_BUFFER EQU 54H ;日缓冲器
MONTH_BUFFER EQU 55H ;月缓冲器
YEAR_BUFFER EQU 56H ;年缓冲器
CENTURY_BUFFER EQU 57H ;世纪缓冲器
ORG 0H
START: JMP MAIN
ORG 13H
JMP RTC_INT
ORG 30H
MAIN: MOV SP,#60H
MOV IE,#10000100B ;致能外部中断1
MOV SECOND_BUFFER,#55H ;秒缓冲器,作调试用
MOV MINUTE_BUFFER,#11H ;分缓冲器
MOV HOUR_BUFFER,#15H ;时缓冲器
MOV WEEK_BUFFER,#04H ;星期缓冲器
MOV DATE_BUFFER,#20H ;日缓冲器
MOV MONTH_BUFFER,#02H ;月缓冲器
MOV YEAR_BUFFER,#02H ;年缓冲器
MOV CENTURY_BUFFER,#20H ;世纪缓冲器
;延时-----------------------------------------------------
CALL DELAY3
;设定DS12C887-------------------------------------------------
;------------REG_A=00101111B ;开启振荡器和允许计时,输出方波2Hz
MOV B,#REG_A
MOV A,#00101111B;
CALL WRITE
;------------REG_B=10000000B ;设定SET=1,禁止更新资料
MOV B,#REG_B
MOV A,#80H
CALL WRITE
;------------SECOND=55 ;设定 55 秒
MOV B,#SECOND
MOV A,#55H
CALL WRITE
;------------SECOND_ALARM=10H ;设定闹铃在 10 秒
MOV B,#SECOND_ALARM
MOV A,#10H
CALL WRITE
;------------MINUTE=00 ;设定 00 分
MOV B,#MINUTE
MOV A,#25H
CALL WRITE
;------------MINUTE_ALARM,#0C0H ;设定闹铃在随意码
MOV A,#MINUTE_ALARM
MOV A,#0C0H
CALL WRITE
;------------HOUR,#17H ;设定 17 时
MOV A,#HOUR
MOV A,#15H
CALL WRITE
;------------HOUR_ALARM,#0C0H ;设定闹铃在随意码
MOV A,#HOUR_ALARM
MOV A,#0C0H
CALL WRITE
;------------WEEK,#02H ;设定星期一
MOV B,#WEEK
MOV A,#04H
CALL WRITE
;------------DATE,#18H ;设定 18 日
MOV B,#DATE
MOV A,#20H
CALL WRITE
;------------MONTH,#02H ;设定 02 月
MOV B,#MONTH
MOV A,#02H
CALL WRITE
;------------YEAR,#02H ;设定 02 年
MOV B,#YEAR
MOV A,#02H
CALL WRITE
;------------CENTURY,#19H ;设定 19 世纪
MOV B,#CENTURY
MOV A,#20H
CALL WRITE
;------------REG_B,#00011010B ;设定SET=0,AIE=1,SQWE=1,BCD模式,24小时制
MOV B,#REG_B
MOV A,#00010010B
CALL WRITE
;-显示世纪两位资料------------------------
DISPLAY: MOV A,CENTURY_BUFFER;暂存器中的数值送A
ANL A,#0F0H ;截取高4位
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
ADD A,#00H ;调整显示位(高位)LED
MOV P1,A ;显示高位
CALL DELAY2 ;延时
MOV A,CENTURY_BUFFER;暂存器的数值送A
SWAP A ;低4位送高4位
ANL A,#0F0H ;去掉低4位
ADD A,#01H ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
;-显示年份两位资料------------------------
MOV A,YEAR_BUFFER ;暂存器中的数值送A
ANL A,#0F0H ;截取高4位
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
ADD A,#02H ;调整显示位(高位)LED
MOV P1,A ;显示高位
CALL DELAY2 ;延时
MOV A,YEAR_BUFFER ;暂存器的数值送A
SWAP A ;低4位送高4位
ANL A,#0F0H ;去掉低4位
ADD A,#03H ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
;-显示月份两位资料------------------------
MOV A,MONTH_BUFFER ;暂存器中的数值送A
ANL A,#0F0H ;截取高4位
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
ADD A,#04H ;调整显示位(高位)LED
MOV P1,A ;显示高位
CALL DELAY2 ;延时
MOV A,MONTH_BUFFER ;暂存器的数值送A
SWAP A ;低4位送高4位
ANL A,#0F0H ;去掉低4位
ADD A,#05H ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
;-显示日两位资料------------------------
MOV A,DATE_BUFFER ;暂存器中的数值送A
ANL A,#0F0H ;截取高4位
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
ADD A,#06H ;调整显示位(高位)LED
MOV P1,A ;显示高位
CALL DELAY2 ;延时
MOV A,DATE_BUFFER ;暂存器的数值送A
SWAP A ;低4位送高4位
ANL A,#0F0H ;去掉低4位
ADD A,#07H ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
;-显示星期一位资料------------------------
MOV A,WEEK_BUFFER ;暂存器中的数值送A
SWAP A ;低4位送高4位
ADD A,#08H ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
;-显示小时两位资料------------------------
MOV A,HOUR_BUFFER ;暂存器中的数值送A
ANL A,#0F0H ;截取高4位
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
ADD A,#09H ;调整显示位(高位)LED
MOV P1,A ;显示高位
CALL DELAY2 ;延时
MOV A,HOUR_BUFFER ;暂存器的数值送A
SWAP A ;低4位送高4位
ANL A,#0F0H ;去掉低4位
ADD A,#0AH ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
;-显示分两位资料------------------------
MOV A,MINUTE_BUFFER ;暂存器中的数值送A
ANL A,#0F0H ;截取高4位
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
ADD A,#0BH ;调整显示位(高位)LED
MOV P1,A ;显示高位
CALL DELAY2 ;延时
MOV A,MINUTE_BUFFER ;暂存器的数值送A
SWAP A ;低4位送高4位
ANL A,#0F0H ;去掉低4位
ADD A,#0CH ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
;-显示秒两位资料------------------------
MOV A,SECOND_BUFFER ;暂存器中的数值送A
ANL A,#0F0H ;截取高4位
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
ADD A,#0DH ;调整显示位(高位)LED
MOV P1,A ;显示高位
CALL DELAY2 ;延时
MOV A,SECOND_BUFFER ;暂存器的数值送A
SWAP A ;低4位送高4位
ANL A,#0F0H ;去掉低4位
ADD A,#0EH ;调整显示位(低位)LED
MOV P1,#0FFH ;先关闭LED,以免视觉干扰
CALL DELAY1
MOV P1,A ;显示低位
CALL DELAY2 ;延时
JMP DISPLAY
;更新结束中断服务程序-----------------------------------------------------------
-------
RTC_INT: PUSH ACC
PUSH DPH
PUSH DPL
MOV A,#REG_C
CALL READ ;读取寄存器C,清除寄存器C的所有位
;------------------------------------------------------------------
;-SECOND_BUFFER,SECOND ;读取秒资料
MOV A,#SECOND
CALL READ
MOV SECOND_BUFFER,A
;-MINUTE_BUFFER,MINUTE ;读取分资料
MOV A,#MINUTE
CALL READ
MOV MINUTE_BUFFER,A
;-HOUR_BUFFER,HOUR ;读取时资料
MOV A,#HOUR
CALL READ
MOV HOUR_BUFFER,A
;-WEEK_BUFFER,WEEK ;读取星期资料
MOV A,#WEEK
CALL READ
CJNE A,#01H,N_SUN ;非星期天跳转
ADD A,#08H ;星期天,原为1,加上8,再减1,显示"日"形
N_SUN: DEC A
MOV WEEK_BUFFER,A
;-DATE_BUFFER,DATE ;读取日资料
MOV A,#DATE
CALL READ
MOV DATE_BUFFER,A
;-MONTH_BUFFER,MONTH ;读取月资料
MOV A,#MONTH
CALL READ
MOV MONTH_BUFFER,A
;-YEAR_BUFFER,YEAR ;读取年资料
MOV A,#YEAR
CALL READ
MOV YEAR_BUFFER,A
;-CENTURY_BUFFER,CENTURY ;读取世纪资料
MOV A,#CENTURY
CALL READ
MOV CENTURY_BUFFER,A
pop dpl
pop dph
pop acc
RETI
;DS12887读写子程序,数据入A,地址入B--双寄存器
WRITE: SETB P3.7 ;DS=1,(DS:PIN15)--(89:P3.7RD),
SETB P3.6 ;R/W=1,地址选通输入
SETB P3.0 ;AS=1,(AS:Pin14)-(89:P3.0),拉高以便产生下降沿
MOV P0,B ;将地址送入P0口
CLR P3.0 ;AS=0,地址锁存入DS12887
CLR P3.6 ;写选通/WR(即R/W脚)使能
MOV P0,A ;送数据,把数据写入RAM
SETB P3.6 ;禁止/WR管脚
SETB P3.7 ;关闭12887
NOP
RET
;地址写入A,执行子程序后把数据读入A
READ: SETB P3.7 ;DS=1,(DS:PIN15)--(89:P3.7RD) 地址选通输入置1,下降沿将地址锁
存.P3.1改为P3.0
SETB P3.6 ;R/W=1,地址选通输入
SETB P3.0 ;AS=1,(AS:Pin14)-(89:P3.0),拉高以便产生下降沿
MOV P0,A ;将地址送入P0口
CLR P3.0 ;将地址锁存
MOV P0,#0FFH
CLR P3.7 ;读选通/RD(即DS脚)
MOV A,P0 ;从DS12887中读出数据;可以把下一句调到该句前面试一试
SETB P3.0;
setb P3.7 ;关闭12887
NOP
RET
;延时-----------------------------------------------------------------
DELAY1: MOV R7,#1
MOV R6,#12
d1: DJNZ R6,$
DJNZ R7,d1
RET
DELAY2: MOV R7,#2
MOV R6,#0F0H
d2: DJNZ R6,$
DJNZ R7,d2
RET
DELAY3: MOV R7,#0
MOV R6,#0
MOV R5,#0
d3: DJNZ R5,$
DJNZ R6,d3
DJNZ R7,d3
RET
END
发表时间:2002年2月25日21:01:00