Page Sponsored by 
Back to Victorian University Electronics Intranet Home Page Mirror.
RTC alarm clock project.

Using a Dallas DS1302 real time clock chip and an 89C2051 to make an alarm clock.

Circuit showing connections from the 2051 to the DS1302. The 3.6V nicad battery is trickle charged during normal operation and keeps the rtc going if the main power fails. When the main power is reconnected the time and the alarm time should still be stored in the rtc. So far I have disconnected the main power for 24 hours and the voltage from the 3.6V backup battery dropped from 3.96V to 3.94V. Obviously the battery should keep the rtc going for quite a long time.

Photo showing the prototype clock using a DT104 board for the 2051 and DS1302, a DT004 mother board and a LCD mounted on a prototype board. The buzzer for the alarm and the rtc backup battery can also be seen. The backup battery is an old computer cmos nicad battery. The buzzer is connected to port p3.5
 


Photos showing DT104 board with DS1302 and 32Khz xtal mounted. Battery shown is the rtc backup battery. The MAX232 chip is needed for setting the alarm and the time.

Photo showing connections to the DS1302.

Sample alarm clock program.

;sample alarm clock program for 2051 & ds1302 rtc chip
;ds1302 sclk connects to p3.2
;ds1302 i/o  connects to p3.3
;ds1302 rst  connects to p3.4
;
;the 2051 wait for approx a second at boot up for a serial i/p
;if an i/p is received then a setup menu is displayed
;hours and minutes can be set in 12 hour mode
;serial comms at 9600 baud using a 11.059Mhz xtal
;the alarm hours and min are stored in the rtc ram 
;the alarm stays on for one minute
;
;written by Peter Averill 7-6-1999 
;
;version 2
;updated 10-6-199
;how includes trickle charge of a computer cmos nicad battery for
;battery backup of the rtc
;a piezo buzzer is how connected to port p3.5 for the alarm
; 

$mod2051                

CR              equ     0dh             ; carriage return
LF              equ     0ah             ; line feed

BAUD_9600       equ     0fdh            ; 9600 baud

;rtc equates

sclk            equ     p3.2
io              equ     p3.3
rst             equ     p3.4 

buzzer          equ     p3.5

write_sec       equ     080h
read_sec        equ     081h
write_min       equ     082h
read_min        equ     083h
write_hr        equ     084h
read_hr         equ     085h
control         equ     08eh
trickle         equ     090h
a_h_w           equ     0c0h            ;alarm hours write
a_h_r           equ     0c1h            ;alarm hours read
a_m_w           equ     0c2h            ;alarm minutes write
a_m_r           equ     0c3h            ;alarm minutes read

count           equ     r0      
rtc_reg         equ     r1

;lcd equates

rs              equ     p1.2
en              equ     p1.3
db4             equ     p1.4
db5             equ     p1.5
db6             equ     p1.6
db7             equ     p1.7


datcom          bit     0

                DSEG AT 0020H
                org     0021h           ;leave room for datcom bit
hour:           ds      1
minute:         ds      1

                ORG     0030H           ; stack origin
stack:          DS      20H             ; stack depth


                CSEG

                ORG     0000H           ; power on/reset vector
                jmp     cold_start

                ORG     0003H           ; external interrupt 0 vector
                reti                    ; undefined

                ORG     000BH           ; timer 0 overflow vector
                reti

                ORG     0013H           ; external interrupt 1 vector
                reti                    ; undefined

                ORG     001BH           ; timer 1 overflow vector
                reti                    ; undefined

                ORG     0023H           ; serial I/O interrupt vector
                reti
                

                ORG     40H             ; begin constant data space


menu:           db      cr,lf,lf,lf
                db      'Alarm clock program for 2051 & DS1302',LF,CR
                db      '_____________________________________',LF,CR
                db      'Written by Peter Averill',LF,LF,LF,CR
                db      'Press:-',LF,CR
                db      '        h to set hours enter 00-12',cr,lf
                db      '        m to set minutes enter 00-59',cr,lf
                db      '        a to set the alarm',cr,lf
                db      '        r to run clock',CR,LF,LF,LF,0

menu2:          db      '   press "a" for am or "p" for pm ',0
menu3:          db      cr,lf,'Enter alarm hours 00-12',cr,lf,0
menu4:          db      cr,lf,'Enter alarm minutes 00-59',cr,lf,0

setup:          DB      033h,032h,028h,00ch
                db      002h,001h,0ffh

mess:           db      'The time is',0ffh



                USING   0               ; register bank zero
cold_start:
                mov     sp, #(stack-1)  ; initialize stack pointer
                call    initialize      ; initialize controller registers

                setb    TI
                setb    ES

                setb    buzzer          ;turn buzzer off

                mov     a,#0ffh
                call    delay_ms
                call    delay_mS
                call    delay_ms

top:            jnb     ri,m1
                clr     es
                mov     a,sbuf
                clr     ri
                call    set_clk
                setb    es

m1:
                clr     datcom          ;send commands
                mov     dptr, #setup    ;lcd setup string
                call    send_string
                setb    datcom          ;send data
                mov     dptr, #mess
                call    send_string
                

m2:             
                mov     a,#0c0h         ;selects second line
                clr     datcom          ;send command
                call    send_char
                setb    datcom

                mov     rtc_reg,#read_hr
                call    read_rtc
                mov     hour,a
                mov     c,acc.5
                mov     f0,c
                anl     a,#01fh
                call    disp_bcd                
                mov     a,#':'
                call    send_char

                mov     rtc_reg,#read_min
                call    read_rtc
                mov     minute,a
                call    disp_bcd
                mov     a,#':'
                call    send_char

                mov     rtc_reg,#read_sec
                call    read_rtc
                call    disp_bcd

                mov     a,#' '
                call    send_char
                jb      f0,m3
                mov     a,#'A'
                call    send_char
                jmp     m4
m3:             mov     a,#'P'
                call    send_char
m4:             mov     a,#'M'
                call    send_char

                mov     rtc_reg,#a_h_r
                call    read_rtc
                cjne    a,hour,m5       ;check if alarm hour is equal
                mov     rtc_reg,#a_m_r
                call    read_rtc
;               call    disp_bcd        ;diagnostic code for displaying alarm min 
                cjne    a,minute,m5     ;check if alarm minute is equal
                clr     buzzer          ;turn on buzzer 
                jmp     m6
m5:
                setb    buzzer          ;turn buzzer off
m6:
                jmp     m2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_clk:
                clr     a                       ;car write protect
                mov     rtc_reg,#control
                call    write_rtc

su1:            mov     dptr, #menu
                call    serial_string
                call    getch
                call    serial_char

su2:            cjne    a,#'h',su3
                call    hour_set
su3:            cjne    a,#'m',su4
                call    min_set
su4:            cjne    a,#'a',su5
                call    alarm_set
su5:
                cjne    a,#'r',su1

                mov     a,#10100111b    ;one diode & 8K resistor
                mov     rtc_reg,#trickle
                call    write_rtc       ;turn on trickle charging

                clr     a               ;write zero to the sec
                mov     rtc_reg,#write_sec
                call    write_rtc       ;starts rtc


                mov     a,#80h          ;set write protect
                mov     rtc_reg,#control
                call    write_rtc

                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
hour_set:
                push    acc
                mov     a,#cr
                call    serial_char
                mov     a,#lf
                call    serial_char
                call    get_hr
                mov     rtc_reg,#write_hr
                call    write_rtc
                pop     acc

                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_hr:
                call    get_num
                add     a,#80h          ;select 12 hour mode
                push    acc

                mov     dptr, #menu2
                call    serial_string
                call    getch
gh1:            cjne    a,#'a',gh2
                clr     f0
                jmp     gh3
gh2:            cjne    a,#'p',gh1
                setb    f0
gh3:            call    serial_char
                pop     acc
                jnb     f0,gh4
                add     a,#20h          ;add in pm bit
gh4:
                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
min_set:
                push    acc
                mov     a,#cr
                call    serial_char
                mov     a,#lf
                call    serial_char
                call    get_num
                mov     rtc_reg,#write_min
                call    write_rtc
                pop     acc

                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alarm_set:
                push    acc
                mov     dptr,#menu3
                call    serial_string
                call    get_hr
                mov     rtc_reg,#a_h_w
                call    write_rtc
                mov     dptr,#menu4
                call    serial_string
                call    get_num
                mov     rtc_reg,#a_m_w
                call    write_rtc
                pop     acc

                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_num:
                call    getch
                call    serial_char
                clr     cy
                subb    a,#30h
                rl      a
                rl      a
                rl      a
                rl      a               
                mov     count,a         ;secound use of reg count
get2d:          call    getch
                call    serial_char
                subb    a,#30h
                add     a,count

                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
disp_bcd:
                push    acc
                push    acc
                rr      a
                rr      a
                rr      a
                rr      a
                anl     a,#0fh
                add     a,#30h
                call    send_char
                pop     acc
                anl     a,#0fh
                add     a,#30h
                call    send_char
                pop     acc
                ret             

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                     
;writes the contents of a to the rtc register in rtc_reg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
write_rtc:
                setb    rst 
                push    acc
                mov     a,rtc_reg
                call    twr
                pop     acc
                call    twr 
                clr     rst     
                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;returns the content of the rtc register in rtc_reg to the acc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_rtc:               
                setb    rst 
                mov     a,rtc_reg
                call    twr
                call    trd 
                clr     rst     
                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;rtc write writes the 8bit value in acc to the rtc
;used for command writes and data writes after a command 
;write
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
twr:    
                mov     count,#8 
twr1:   
                rrc     A 
                mov     io,C 
                nop                     ;data to clock wait
                setb    sclk
                nop 
                clr     sclk            ;falling edge of clock
                djnz    count,twr1
                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;rtc read returns 8bit result in the acc
;read can only be used after a command write
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
trd:    
                setb    io
                mov     count,#8
trd1:   
                nop                     ;wait before reading
                mov     c,io
                rrc     a 
                setb    sclk
                nop
                clr     sclk            ;failing edge of clock
                djnz    count,trd1

                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
send_string:

        ; Transmit string pointed to by DPTR.
        ; String may be of any length, but must be 0ffh terminated.

                push    acc
                push    dpl
                push    dph
ss1:
                clr     a
                movc    a, @a+dptr      ; get character
                inc     a
                jz      ss2             ; check for terminator
                dec     a

                call    send_char       ; send character

                inc     dptr            ; point to next character
                jmp     ss1
ss2:
                pop     dph
                pop     dpl
                pop     acc
                ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
send_char:      mov     c,datcom
                mov     rs,c
                clr     en
                mov     c,acc.4
                mov     db4,c
                mov     c,acc.5
                mov     db5,c
                mov     c,acc.6
                mov     db6,c
                mov     c,acc.7
                mov     db7,c
                setb    en
                clr     en
                push    acc
                mov     a,#4h
                call    delay_ms
                pop     acc
                mov     c,acc.0
                mov     db4,c
                mov     c,acc.1
                mov     db5,c
                mov     c,acc.2
                mov     db6,c
                mov     c,acc.3
                mov     db7,c
                setb    en
                clr     en
                mov     a,#4h
                call    delay_ms

                ret     

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
getch:
                setb    es              ;enable reception
                jnb     ri,$            ;wait for key press
                clr     es
                mov     a,sbuf
                clr     ri
                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
serial_string:

        ; Transmit string pointed to by DPTR.
        ; String may be of any length, but must be null-terminated.

                push    acc
                push    dpl
                push    dph
s_s1:
                clr     a
                movc    a, @a+dptr      ; get character
                jz      s_s2             ; check for terminator

                call    serial_char       ; send character

                inc     dptr            ; point to next character
                jmp     s_s1
s_s2:
                pop     dph
                pop     dpl
                pop     acc
                ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
serial_char:

        ; Wait for transmitter to clear, add even parity bit to character
        ; in accumulator and transmit it. Does not wait for transmitter
        ; to clear before returning.

                jnb     TI, $           ; wait here for transmitter to clear
                clr     TI              ; clear transmit flag
                push    acc             ; save char
                mov     SBUF, a         ; load character into transmitter
                pop     acc             ; restore char
                ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

initialize:

        ; Initialize controller registers.

                mov     PCON, #0        ; initialize power control register
                mov     IE, #0          ; deactivate all interrupts


                mov     SCON, #01000000b        ; serial port mode one
                mov     TMOD, #00100001b        ; timer one 8-bit auto-reload,
                                          &nb;     ; timer zero 16-bit
                mov     TH1, #BAUD_9600         ; timer one reload value
                mov     TCON, #01000000b        ; start timer one & zero
                setb    REN                     ;enable rx int
                setb    EA                      ;global int able

                ret
                 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay_ms:

        ; Delay for one mS times the value in the accumulator.

                push    acc
                push    b

                mov     b, #0
dd:
                djnz    b, $            ; 500 uS @ 12 MHz
                djnz    b, $            ; 500 uS @ 12 MHz
                djnz    acc, dd

                pop     b
                pop     acc
                ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                end
Written by Peter Averill
Victoria Universtiy TAFE
Electronics Technology Department
13 June 1999

Copying these pages:
 
Back to Victorian University Electronics Intranet Home Page Mirror.
DonTronics Links:
Home Products Prices Directory Order Contact New Books Files Links FAQ