Interfacing of DS12887 to 8051

Circuit Diagram:
 
Program:
;AD0-AD7 --> P1.0-P1.7
;AS -->  p3.4
;R/W --> p3.5
;DS -->  p3.7
;IRQ --> if required, to External Interrupt 0 or 1
;
;CS --> 0V
;MOT --> 0V
;Reset --> to +5V
;
$mod51
;
DYTA        equ     12h        ; data byte to be written
addr        equ    13h        ; for address byte
;--------------port 3 Pinout-----------------
Ser_RX    equ    p3.0    ;Serial RX
Ser_TX    equ    p3.1    ;Serial TX
;        equ    p3.2    ;
;        equ    p3.3    ;
;        equ    p3.4    ;
RTC_AS    equ    p3.5    ;
RTC_RW    equ    p3.6    ;
RTC_DS    equ    p3.7    ;Data Strobe
;****************************************
sec         equ     00h
sec_alrm    equ     01h
min         equ     02h
min_alrm    equ     03h
hour        equ     04h
hrs_alrm    equ     05h
day         equ     06h
date        equ     07h
month       equ     08h
year        equ     09h
rega        equ     0ah
regb        equ     0bh
regc        equ     0ch
regd        equ     0dh
set_oscsqwe equ     00100000b   ;set osc to run normally,sqw o/p freq is 1.024 KHz.Reg A
                                ;and a periodic interupt of 976.5625 usec.
                     
set_time    equ     11101010b   ;bit7(1 for time setting),bit6(1 for periodic interrupt
                      ;enable PIEdepends on RS0-RS3),bit5(AIE),bit4(UIE),bit3
                                ;SQWE,bit2(DM=0 for BCD format),bit1(24/12),bit0(DSE).Reg B
update_time equ     00000010b   ;b
;
;storage in ram for date & time
sec_stor        equ    08h
sec_alrm_stor        equ    09h
min_stor             equ    0Ah
min_alrm_stor        equ    0Bh
hour_stor            equ    0Ch
hrs_alrm_stor        equ    0Dh
day_stor             equ    0Eh
date_stor            equ    0Fh
month_stor           equ    10h
year_stor            equ    11h
;--------------------------------------
org    0
Reset:
    ajmp    Start        ;main program

ORG    0030H            ; begin code space
;************************************************
Start:               
    MOV    SP,#06FH        ;Set Stack
    MOV    A,#0FFH        ;
    MOV    P1,A            ;
    MOV    P3,A            ;
    CLR RTC_AS            ;AS always low
Start2:
    lcall    ClrScreen        ;
    lcall intro             ; print menu message
    lcall    newline        ;

ChkInp:
    lcall    Inchar         ;Get a cmd to work with
    cjne    a,#030h,KeyIn    ;
    sjmp    ChkInp
       
KeyIn:
    cjne    a,#031h,KeyIn1    ;its a '1' set time   
    lcall    setime
    sjmp    ChkInp1

KeyIn1:
    cjne    a,#032h,KeyIn2    ;its a '2' read time
    lcall    Get_RTC
    lcall    Print_Time   
    sjmp    ChkInp1
   
KeyIn2:
    cjne    a,#033h,KeyIn3    ;its a '3' read date
    lcall    Get_RTC
    lcall    Print_Date
    sjmp    ChkInp1
KeyIn3:
    cjne    a,#034h,ChkInp    ;its a '4' read registers
    lcall    NewLine   
    lcall    read_reg
    sjmp    ChkInp1   
;************************************************
ChkInp1:
    lcall    Inchar
    ljmp    Start2
;************************************************
RTC_READ:
    MOV P1,addr       
    nop

    SETB RTC_AS        ;send address
    nop
    CLR RTC_AS

    nop   
    MOV P1,#0FFH    ;P1 = input
    nop
    CLR RTC_DS
    nop
    MOV DYTA,P1        ;read to DYTA
    SETB RTC_DS
    RET
;************************************************
RTC_WRITE:
    MOV P1,addr       
    nop

    SETB RTC_AS        ;send address
    nop
    CLR RTC_AS
   
    nop
    nop

    MOV P1,DYTA        ;send data
    nop

    CLR RTC_RW
    nop
    SETB RTC_RW
    RET
;************************************************
;read time and date, store in 8051 ram
Get_RTC:
      MOV    addr, #rega
Wait:
      lcall    RTC_READ
    mov    a,DYTA
      JB    ACC.7, Wait

    MOV    addr, #sec
      lcall    RTC_READ       
      MOV    sec_stor, DYTA

      MOV    addr, #Min
      lcall    RTC_READ       
      MOV    min_stor, DYTA

      MOV    addr, #Hour
      lcall    RTC_READ
      MOV    Hour_stor, DYTA

      MOV    addr, #Day
      lcall    RTC_READ
      MOV    Day_stor, DYTA
   
    MOV    addr, #Date
      lcall    RTC_READ
      MOV    Date_stor, DYTA

      MOV    addr, #Month
    lcall    RTC_READ
      MOV    Month_stor, DYTA

      MOV    addr, #Year
    lcall    RTC_READ
      MOV    Year_stor, DYTA
    ret
;************************************************
Print_Date:
    mov    dptr,#Date_msg
    lcall    OutStr

    mov    R0,#Year_stor
    mov    a,@R0
    lcall    pout
   
    mov    R0,#Month_stor
    mov    a,@R0
    lcall    pout

    mov    R0,#Date_stor
    mov    a,@R0
    lcall    pout
    ret
;************************************************
Print_Time:
    mov    dptr,#Time_msg
    lcall    OutStr

    mov    R0,#Hour_stor
    mov    a,@R0
    lcall    Hex2Ascii

    mov    a,#3ah
    lcall    OutChar   

    mov    R0,#Min_stor
    mov    a,@R0
    lcall    Hex2Ascii
   
    mov    a,#3ah
    lcall    OutChar

    mov    R0,#Sec_stor
    mov    a,@R0
    lcall    Hex2Ascii
    ret

Date_msg:
    db    cr,lf,'Date: ',0
Time_msg:
    db    cr,lf,'Time: ',0
;================================================
;subroutine to set time
;================================================
setime:
    mov    addr,#regb
    mov    DYTA,#set_time    ;prepare to set time
    lcall    RTC_WRITE

    mov    addr,#hour           ;set hrs
    mov    dptr,#Ent_Hrs_str
    lcall    OutStr
    lcall    GetHex
    mov    DYTA,a           ;change the value to any 0-23 as hour to set
    lcall    RTC_WRITE

    mov    addr,#min           ;set minutes
    mov    dptr,#Ent_min_str
    lcall    OutStr
    lcall    GetHex
    mov    DYTA,a           ;change  0-59 to set minutes
    lcall    RTC_WRITE

    mov    addr,#sec           ;set seconds to 00
    mov    DYTA,#00h            ;change 0- 59 to set seconds
    lcall    RTC_WRITE

;    mov    addr,#day           ;set day of the week
;    mov    DYTA,#01h    
;    lcall    RTC_WRITE

    mov    addr,#date          ;set day of month
    mov    dptr,#Ent_Day_str
    lcall    OutStr
    lcall    GetHex
    mov    DYTA,a            ;set 15h for 15th 
    lcall    RTC_WRITE

    mov    addr,#month          ;set month
    mov    dptr,#Ent_Mnth_str
    lcall    OutStr
    lcall    GetHex
    mov    DYTA,a            ;05h for month of may   
    lcall    RTC_WRITE

    mov    addr,#year          ;set year
    mov    dptr,#Ent_Yr_str
    lcall    OutStr
    lcall    GetHex
    mov    DYTA,a            ;08h for year 2008
    lcall    RTC_WRITE

    mov    addr,#rega
    mov    DYTA,#set_oscsqwe  ;set regA
    lcall    RTC_WRITE

    mov    addr,#regb
    mov    DYTA,#update_time  ;set regB for normal clock operation     
    lcall    RTC_WRITE
    ret
;--------------------------------------------------------
;subroutine to read and display 4 registers A,B,C,D.of DS1287
;=============================================================
read_reg:  
;-------------read and display reg A--------           
    mov    addr,#rega
    lcall    RTC_READ
    mov    a,DYTA
    lcall    POUT
;-------------read and display reg B--------           
    mov    addr,#regb
    lcall    RTC_READ
    mov    a,DYTA
    lcall    POUT
;-------------read and display reg C--------           
    mov    addr,#regc
    lcall    RTC_READ
    mov    a,DYTA
    lcall    POUT
;-------------read and display reg D--------           
    mov    addr,#regd
    lcall    RTC_READ
    mov    a,DYTA
    lcall    POUT
    ret
;=============================================================
$include (termfunc.inc)
END