' ========================================================================= ' ' File....... DS1307.BSP ' Purpose.... Demonstrates DS1307 interfacing and display ' Author..... Parallax, Inc. (Copyright 2003 - All Rights Reserved) ' E-mail..... support@parallax.com ' Started.... 22 SEP 2003 ' Updated.... 04 APR 2004 ' ' {$STAMP BS2p} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' ' This program demonstrates the DS1307 and selective time display modes. ' -----[ Revision History ]------------------------------------------------ ' -----[ I/O Definitions ]------------------------------------------------- SDA PIN 0 ' SDA on 0; SCL on 1 Mode PIN 7 ' display mode input BtnBank VAR INB ' buttons on 4, 5, 6 ' -----[ Constants ]------------------------------------------------------- Wr1307 CON %11010000 ' write to DS1307 Rd1307 CON %11010001 ' read from DS1307 Clock12 CON 1 ' AM/PM display Clock24 CON 0 ' 24 hour display #DEFINE _P40 = 1 ' change to 0 for BS2p24 ' -----[ Variables ]------------------------------------------------------- secs VAR Byte ' DS1307 time registers mins VAR Byte hrs VAR Byte day VAR Byte ' weekday date VAR Byte ' day in month, 1 - 31 month VAR Byte year VAR Byte control VAR Byte ' SQWV I/O control buttons VAR Nib ' debounced button inputs btnHr VAR buttons.BIT2 ' advance hours btnMn VAR buttons.BIT1 ' advance minutes btnSc VAR buttons.BIT0 ' advance seconds idx VAR Nib ' loop counter addr VAR Byte ' DS1307 RAM address ioByte VAR Byte ' data to/from DS1307 oldSecs VAR Byte ' last seconds read ' -----[ EEPROM Data ]----------------------------------------------------- ClockSet DATA $FF ' $FF = not set ' -----[ Initialization ]-------------------------------------------------- Setup: READ ClockSet, ioByte ' check preset val IF (ioByte = $FF) THEN ' if $FF we should preset #IF _P40 #THEN AUXIO #ENDIF ' use aux pins on BS2p40 hrs = $06 ' 6 AM day = 1 ' Sunday I2COUT SDA, Wr1307, 0, [STR secs\8] ' initialize all RTC regs WRITE ClockSet, $00 ' clock has been preset ENDIF DEBUG CLS, "DS1307 Demo", CR, "-----------" oldSecs = $99 ' force display update ' -----[ Program Code ]---------------------------------------------------- Main: DO GOSUB Get_Time ' get current time IF (secs <> oldSecs) THEN ' update display DEBUG CRSRXY, 0, 2 #IF _P40 #THEN MAINIO #ENDIF ' mode on main io bank IF (Mode = Clock12) THEN ' 12 hour mode ioByte = hrs // 12 IF (ioByte = 0) THEN ioByte = 12 DEBUG DEC2 ioByte, ":", DEC2 mins, ":", DEC2 secs IF (hrs > 11) THEN DEBUG " PM" ELSE DEBUG " AM" ENDIF ELSE ' 24 hour mode DEBUG DEC2 hrs, ":", DEC2 mins, ":", DEC2 secs, CLREOL ENDIF oldSecs = secs ENDIF GOSUB Scan_Buttons IF (buttons > 0) THEN IF (btnHr) THEN hrs = hrs + 1 // 24 ' update hours IF (btnMn) THEN mins = mins + 1 // 60 ' update minutes IF (btnSc) THEN secs = secs + 1 // 60 ' update seconds GOSUB Set_Time oldSecs = 99 ' force display update ENDIF PAUSE 200 ' button repeat rate LOOP ' -----[ Subroutines ]----------------------------------------------------- Scan_Buttons: #IF _P40 #THEN MAINIO #ENDIF ' buttons on main io bank buttons = %0111 ' assume pressed FOR idx = 1 TO 10 buttons = buttons & ~BtnBank ' inputs are active-low PAUSE 2 NEXT RETURN Set_Time: secs = (secs / 10 << 4) + (secs // 10) ' decimal to BCD mins = (mins / 10 << 4) + (mins // 10) hrs = (hrs / 10 << 4) + (hrs // 10) #IF _P40 #THEN AUXIO #ENDIF ' use aux pins on BS2p40 I2COUT SDA, Wr1307, 0, [secs, mins, hrs] ' update time registers RETURN Get_Time: #IF _P40 #THEN AUXIO #ENDIF ' use aux pins on BS2p40 I2CIN SDA, Rd1307, 0, [secs, mins, hrs] ' read time registers secs = secs.NIB1 * 10 + secs.NIB0 ' BCD to decimal mins = mins.NIB1 * 10 + mins.NIB0 hrs = hrs.NIB1 * 10 + hrs.NIB0 RETURN Wr_Reg: #IF _P40 #THEN AUXIO #ENDIF ' use aux pins on BS2p40 I2COUT SDA, Wr1307, addr, [ioByte] ' write iobyte to addr RETURN Rd_Reg: #IF _P40 #THEN AUXIO #ENDIF ' use aux pins on BS2p40 I2CIN SDA, Rd1307, addr, [ioByte] ' read iobyte from addr RETURN