Below is a little test routine that I wrote for someone having problems with the DS1302 real time clock chip I specified for another project. He has an 08M on hand, so we thought if he could get the DS1302 running on the 08M, independently of the other processor, it would tell us where to look for the ultimate cause of his problem.
Since I didn't find any examples of a Picaxe driving a DS1302 chip the last time I searched the forums, I thought I'd publish the diagnostic here so anyone looking for info on this chip might find an example of how one is used.
(The DS1302, by the way, is similar internally to the DS1307. It uses a bidirectional synchronous serial interface though, rather than the 1307's I2C interface, and handles the internal registers a bit differently than does the DS1307. It also has a built-in trickle charger that's ideal for clock backup using a supercap, which is why I selected it in the first place.)
This routine implements a bit-banged DS1302 interface. Note that I haven't optimized the code for the 08M. It's a rough translation of the algorithm I used in my C routine. Hopefully, if there is design flaw in my C routine, it will be reflected in the Picaxe code. But I believe it serves as a good illustration.
I've tested this on the breadboard, and it works just fine.
I hope that, in the future, someone might find this useful.
Tom
Since I didn't find any examples of a Picaxe driving a DS1302 chip the last time I searched the forums, I thought I'd publish the diagnostic here so anyone looking for info on this chip might find an example of how one is used.
(The DS1302, by the way, is similar internally to the DS1307. It uses a bidirectional synchronous serial interface though, rather than the 1307's I2C interface, and handles the internal registers a bit differently than does the DS1307. It also has a built-in trickle charger that's ideal for clock backup using a supercap, which is why I selected it in the first place.)
This routine implements a bit-banged DS1302 interface. Note that I haven't optimized the code for the 08M. It's a rough translation of the algorithm I used in my C routine. Hopefully, if there is design flaw in my C routine, it will be reflected in the Picaxe code. But I believe it serves as a good illustration.
I've tested this on the breadboard, and it works just fine.
I hope that, in the future, someone might find this useful.
Tom
Code:
#rem
DS1302Test_08M.bas
Test routine for DS1302 for Picaxe 08M. tjl Oct 24, 2007
This program displays the time on the Picaxe terminal each
second. (Set your Program Editor options to open the terminal
window automatically after program download.)
Time is maintained and set in the 24-hour format.
Time is preset by changing reg values in the appropriate assignment
section at the top of Main:
This is a diagnostic, and a rough translation of the code and
algorithms used in a C program. It has not been optimized
for the Picaxe.
This program uses 253 bytes of program memory out of the 256 available.
Connect DS1302 as follows:
leg 1: +5 v
leg 2: crystal
leg 3: crystal
leg 4: ground
leg 5: 08M leg 5
leg 6: 08M leg 6
leg 7: 08M leg 3
leg 8: open or supercap to ground
#endrem
; DS1302 Opcodes
symbol WriteCtrl = %10001110
symbol ReadSecs = %10000001
symbol WriteSecs = %10000000
symbol ReadMins = %10000011
symbol WriteMins = %10000010
symbol ReadHrs = %10000101
symbol WriteHrs = %10000100
symbol WriteTrickle = %10010000
symbol TrickleSet = %10100101
; DS1302 Connections
symbol CLK = 4 ' leg 3 to DS1302 leg 7
symbol IO = 1 ' leg 6 to DS1302 leg 6
symbol RST = 2 ' leg 5 to DS1302 leg 5
; Registers
symbol Hours = b0
symbol Mins = b1
symbol Secs = b2
symbol PrevSecs = b3
symbol Command = b4
symbol Data1302 = b5
symbol ShiftData = b6
Main:
; Preset time here using BCD format.
; As shown, this presets the time to 12:34:56
Hours = $12
Mins = $34
Secs = $56
PrevSecs = 0
low CLK
; Init 1302
Command = WriteCtrl ' clear write protect
Data1302 = 0
gosub Send1302Cmd
Command = WriteTrickle ' turn on the supercap trickle charger
Data1302 = TrickleSet
gosub Send1302Cmd
Hours = Hours & %00111111 ' set 24-hour format, set hours
Command = WriteHrs
Data1302 = Hours
gosub Send1302Cmd
Command = WriteMins ' set minutes
Data1302 = Mins
gosub Send1302Cmd
Secs = Secs & %01111111 ' set CH bit to zero and set secs
Command = WriteSecs
Data1302 = Secs
gosub Send1302Cmd
do ' wait for Secs to change
Command = ReadSecs
gosub Get1302Data
if Data1302 <> PrevSecs then ' when secs change, get and show time.
Secs = Data1302
PrevSecs = Secs
gosub GetTime
endif
loop
end
Send1302Cmd:
' Sends Command, then sends Data1302
dirs = %00010110
high RST
ShiftData = Command
gosub Shiftout
ShiftData = Data1302
gosub Shiftout
low RST
return
Get1302Data:
' First sends Command, then reads 1302 result to Data1302
dirs = %00010110
high RST
ShiftData = Command
gosub Shiftout
dirs = %00010100
gosub Shiftin
low RST
return
Shiftout:
; Shift data to 1302, LSB first
for b13 = 1 to 8
b12 = ShiftData % 2
if b12 = 1 then
high IO
else
low IO
endif
pulsout CLK,1 ' 10 uSec pulse on CLK
ShiftDAta = ShiftData / 2
next
return
Shiftin:
; Shifts data into Data1302 LSB first
; This call always follows a shiftout op, so the first bit of
; the response is present on the IO pin at call. It only takes
; seven clock pulses to shift in the rest of the data byte
' note that this won't read the most significat bit. but when
' reading the DS1302, it never has to.
for b13 = 1 to 7
b12 = pin1 * 128
Data1302 = Data1302 + b12
Data1302 = Data1302 / 2
pulsout CLK,1 ' 10 uSec pulse on CLK strobes in next data bit
next
return
GetTime:
' Get Hours, Mins, Secs, convert to ASCII, send to Picaxe terminal
Command = ReadHrs
gosub Get1302Data
Hours = Data1302 & %00111111
bcdtoascii Hours,b12,b13
sertxd(b12,b13,":")
Command = ReadMins
gosub Get1302Data
bcdtoascii Data1302,b12,b13
sertxd(b12,b13,":")
Command = ReadSecs
gosub Get1302Data
bcdtoascii Data1302,b12,b13
sertxd(b12,b13,13,10)
return
Last edited: