;************************************************** ; clock app using rtc 8583 ;************************************************** cpu "8051.tbl" ; internal ram bit-addr locations erb: equ 070h ; ack error flag srf: equ 071h ; stop read flag sda: equ 0b0h ; i2c data line (p3.0) scl: equ 0b1h ; i2c clock line (p3.1) ad0: equ 0b2h ; latch address line 0 ad1: equ 0b3h ; latch address line 1 sw0: equ 0b4h ; input switch 0 sw1: equ 0b5h ; input switch 1 wrs: equ 0b7h ; write segment latch ; internal ram byte locations tmp: equ 060h ; temporary storage tgf: equ 061h ; sec toggle byte (subb!) msk: equ 062h ; port mask for colon blink tm0: equ 070h ; control byte tm1: equ 071h ; 1/100 byte tm2: equ 072h ; second byte tm3: equ 073h ; minute byte tm4: equ 074h ; hour byte ; alias for system reg/port pt1: equ 090h ; port 1 - segment data rgb: equ 0f0h ; register b org 00h ljmp start ; skip interrupt vectors area ; org 03h ; override with segment table + nulls!! table: dfb 08h,5bh,22h,12h,51h,14h,04h,5ah ; org 0bh dfb 00h,10h,00h,00h,00h,00h,00h,00h ; org 13h dfb 00h,00h,00h,00h,00h,00h,00h,00h ; org 1bh dfb 00h,00h,00h,00h,00h,00h,00h,00h ; org 23h dfb 00h,00h,00h,00h,00h,00h,00h,00h ; org 2bh dfb 00h,00h,00h,00h,00h,00h,00h,00h ; org 33h dfb 00h,00h,00h,00h,00h,00h,00h,00h ;************************************************** ; main code ;************************************************** ; org 3bh start: setb ad0 ; set default latch address 11 clr wrs ; clear write signal clr srf ; clear stop read flag mov tgf,#00h ; toggle byte is zero (init) mov msk,#00h ; switch on by default - orl mov dptr,#table ; init segment display table ; local default setting mov tm0,#00h ; mode ext osc,nomask,noalm mov tm1,#00h ; 1/100 seconds bcd mov tm2,#50h ; seconds bcd mov tm3,#58h ; minutes bcd mov tm4,#92h ; 12h,am,12 hour bcd ; init rtc 8583 setting & value irtc: call i2cst mov a,#0a0h ; slave address (a0=0) write call i2cout jb erb,irtc ; check acknowledge mov a,#00h ; word address (control reg) call i2cout mov a,tm0 ; mode ext osc,nomask,noalm call i2cout mov a,tm1 ; 1/100 seconds bcd call i2cout mov a,tm2 ; seconds bcd call i2cout mov a,tm3 ; minutes bcd call i2cout mov a,tm4 ; 12h,am,12 hour bcd call i2cout call i2csp ; main routine main: call i2cst mov a,#0a0h ; slave address (a0=0) write call i2cout mov a,#03h ; word address (03-minute) call i2cout call i2cst ; resend for read mov a,#0a1h ;slave address (a0=0) read call i2cout ; start read call i2cin mov tm3,a ; minute byte setb srf ; last byte call i2cin mov tm4,a ; hour byte call i2csp ; now we update! disp: setb ad1 ; set latch address 11 mov a,tm3 anl a,#0fh movc a,@a+dptr orl a,msk mov pt1,a setb wrs clr wrs clr ad0 ; set latch address 10 mov a,tm3 swap a anl a,#0fh movc a,@a+dptr orl a,msk mov pt1,a setb wrs clr wrs clr ad1 ; set latch address 00 mov a,tm4 swap a anl a,#03h ; for hour take 2-bits only movc a,@a+dptr orl a,msk mov pt1,a setb wrs clr wrs setb ad0 ; set latch address 01 mov a,tm4 anl a,#0fh movc a,@a+dptr orl a,msk mov pt1,a setb wrs clr wrs ; check switches chkb0: jb sw0,chkb1 jnb sw0,$ mov a,tm3 add a,#01h da a cjne a,#60h,savem mov a,#00h savem: mov tm3,a jmp next1 chkb1: jb sw1,chktm jnb sw1,$ inch: mov a,tm4 anl a,#3fh add a,#01h da a cjne a,#13h,saveh ; only for 12h format! mov a,#01h saveh: mov tmp,a mov a,tm4 anl a,#0c0h orl a,tmp mov tm4,a ; write to rtc if needed next1: call i2cst mov a,#0a0h ; slave address (a0=0) write call i2cout mov a,#03h ; word address (03-minute) call i2cout mov a,tm3 ; minutes bcd call i2cout mov a,tm4 ; hour bcd call i2cout call i2csp jmp main ; monitor tf flag chktm: call i2cst mov a,#0a0h ; slave address (a0=0) write call i2cout mov a,#00h ; word address (00) call i2cout call i2cst ; resend for read mov a,#0a1h ;slave address (a0=0) read call i2cout ; start read setb srf ; last byte call i2cin anl a,#01h mov tm0,a ; control byte - get tf (lsb) only! call i2csp ; now we check clr c subb a,tgf ; look for transition! jz chkb0 mov tgf,tm0 jnc col0 mov msk,#00h ; 1->0 transition! jmp main col0: mov msk,#80h ; 0->1 transition! jmp disp ;************************************************** ; subroutines ;************************************************** ; routine i2c to write out start marker i2cst: setb scl setb sda nop ; start condition setup time > 4.7 us nop ; for 11.0592MHz xtal, 1 mc = 1.085us nop ; 1 nop = 1 mach cycle nop clr sda nop ; start condition hold time > 4.0 us nop nop clr scl ret ; routine i2c to write 1 byte out - scl already low i2cout: mov rgb,#08h i2cl1: rlc a jnc i2co0 setb sda sjmp i2co1 i2co0: clr sda i2co1: setb scl nop ; scl high time > 4.0 us (low time > 4.7 us) nop nop clr scl djnz rgb,i2cl1 setb sda nop setb scl clr erb jnb sda,i2cef ; check acknowledge bit setb erb i2cef: clr scl ret ; routine i2c to write out stop marker i2csp: clr sda nop setb scl nop ; stop condition setup time > 4.0 us nop nop setb sda ret ; routine i2c to read 1 byte in i2cin: mov rgb,#08h setb sda ; need this to disable int pulldwn source? i2cl2: clr scl nop ; scl low time > 4.7 us (high time > 4.0 us) nop nop nop setb scl clr c jnb sda,i2ci0 cpl c i2ci0: rlc a djnz rgb,i2cl2 clr scl jb srf,i2ci1 ; scl low to vata valid time < 3.4us?? clr sda ; send acknowledge bit if not last! i2ci1: clr srf ; reset stop read flag nop setb scl nop nop nop clr scl ret ;************************************************** end ;**************************************************