DS1302 -- 08M Test Routine

Tom2000

Senior Member
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




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:

Michael 2727

Senior Member
The Code Snippets section of the forum may be a good
place to put this type of post.
I don't have any DS clock chips but there are plenty
of people who do, thanks for taking the time, no pun intended :p
 

Tom2000

Senior Member
Thanks, Michael.

Would one of the moderators be so kind as to move this thread? Thanks.

And, Michael, I thought it was a great pun. Even at this hour of the morning! :)

Tom
 
Top