DS3231 RTC Enhancements

Discussion in 'Embedded Systems and Microcontrollers' started by jpanhalt, May 11, 2016.

  1. jpanhalt

    Thread Starter AAC Fanatic!

    Jan 18, 2008
    5,699
    907
    I have added a button to increase the minutes or seconds of a DS3231 module by 1 (one) each time it is pushed:
    Code (ASM):
    1.  
    2. Increment
    3.      movlw     7  
    4.      addwf     min_sec,w      ;test if low nibble =9
    5.      btfsc     STATUS,1       ;test DC
    6.      goto      Done        
    7.      incf      min_sec,w
    8. Done
    9.      nop                      ;this will be a call with value in w to "WriteOneByte"
    10.  
    Note: "min_sec" is the current read of the appropriate register in the RTC.

    There is no check for reaching "60." Of course, it is no big strain to add that test. Does anyone know what happens if you try to write a "60" in BCD to the minutes or seconds registers?

    Just FWI, since some of you may not have played with these devices in awhile: BCD "59" = b'01011001'
    and BCD "60" = b'01100000'

    I thought I would ask before just trying it.

    Regards, John
     
    Last edited: May 11, 2016
  2. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    @jpanhalt Looks OK. Don't forget to save your result in min_sec.

    You can also save a jump and a Tcyc or two by:
    Code (Microchip Assembler):
    1.  
    2.   incf min_sec,F   ; bump time
    3.   movlw 06h     ; add 6 to LSnibble to see if its >= Ah
    4.   addwf min_sec,W
    5.   btfsc STATUS,DC   ; if digit carry it rolled 9-> 0 and is adjusted
    6.   movwf min_sec   ; save incremented/adjusted result - it may be out of range
    7.  
    8.   addlw 0A0h     ; test for wrap around by adding complement of 60h
    9.   btfsc STATUS,C   ; C if copy of incremented/adjusted BCD value was >=60h
    10.   clrf min_sec   ; 60h->00h ; min_sec needs wrapping 60h -> 00h
    11.   movf min_sec,W   ; min_sec is incremented, adjusted and wrapped. Get result to W
    12.  
    You can also do to the test for 59h before the increment but that probably means a jump. Lots of ways to do it.

    Have fun!
    EDIT: @jpanhalt tested and corrected code - sheesh..
     
    Last edited: May 11, 2016
    jpanhalt likes this.
  3. jpanhalt

    Thread Starter AAC Fanatic!

    Jan 18, 2008
    5,699
    907
    Thank you for the code. I will play with it tomorrow. It would be nice to save that jump.

    I will try not to forget where the answer is. ;) I often call with it in W, but I am not certain I will do that in this instance. If someone doesn't speak up about what happens when values that are not possible are written, I will just try it.

    John
     
  4. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    W is great for passing parameters. I make it a habit to maintain values in RAM and use W for rank temporary stuff. Otherwise, I forget to save things..
    As far as writing out of range values, if it is specified in the datasheet what happens when you do, you might be OK. If it isn't, don't do it. Unspecified things have a way of changing without notice and can work differently even from legitimate 2ed source manufacturers. You don't have control over that but you do have control over writing valid values so I'd recommend you stay within the lines.

    Best regards,
    John

    PS I tweaked the code to save a byte.
     
    jpanhalt likes this.
  5. jpanhalt

    Thread Starter AAC Fanatic!

    Jan 18, 2008
    5,699
    907
    The datasheet is silent on that subject. As was Google, best I could tell. I would be extremely surprised if the seconds rolled over. My guess is it is either ignored, i.e, 60 might be read as 20, read as zero, doesn't read at all, or is read as hash. I favor the latter two. I have 3 of these modules and if I brick one, it is no great loss. Besides, that will give me a chance to test my un-bricking routine.

    I am actually more interested in getting experience with the I2C interface and have a list of questions regarding error handling which I plan to post when they are more refined. Since getting some minor glitches fixed in January, I have yet to get an error (1 master, 1 slave), but what worries me is the somewhat vague discussion of error handling in the Microchip notes. Today was not my day -- a rare "migraine." I even cancelled a trip into Cleveland. Will be much better tomorrow.

    Thanks for the tweak.

    John
     
  6. NorthGuy

    Active Member

    Jun 28, 2014
    605
    121
    Something of that sort:

    Code (Microchip Assembler):
    1. movlw 0xA7       ; we want to set DC if there's a carry and/or C if it's 0x59
    2. addwf min_sec,f
    3. movlw 0xA6       ; we're going to subtract this back if there's no carries
    4. btfsc STATUS,1   ; but if there was DC carry, we only need to subtract back 0xA0
    5. movlw 0xA0
    6. btfss STATUS,0   ; and if we had 0x59, there's no need to subtract - zero is already there
    7. subwf min_sec,f
     
    jpanhalt and JohnInTX like this.
  7. jpanhalt

    Thread Starter AAC Fanatic!

    Jan 18, 2008
    5,699
    907
    This old chemist just had to do the experiment: What happens when you write a BCD >59 to minutes or seconds?
    1) Both registers seems to behave the same wary. Testing the seconds (register 0x00) doesn't take as long as testing minutes. I did not fully test the minutes register.
    2) When written with bcd 60 (or any of several numbers >60), that value is displayed and counts up "normally" (i.e., the low nibble counts and high nibble increments ) until "79" is displayed. At that point, the display changes to 40 and continues to work normally thereafter. Thus, looking only at the high nibble:
    Code (Text):
    1.  
    2. 0110
    3. 0111
    4. x100
    5.  
    Interesting that x111 doesn't roll over to x000 but rather goes to x100.
    Testing the low nibble of the seconds register with 0x5A gave in sequence:
    Code (Text):
    1.  
    2. 01011010   (displayed as 5A)
    3. 01011011   (displayed as 5B)
    4. 00000100   (displayed as 04) and minutes increment
    5.  
    Thank you both for the code advice. I will avoid writing 60.

    John

    Edit: Of course, my print algorithm may affect what is displayed.
     
    Last edited: May 12, 2016
    JohnInTX likes this.
  8. jpanhalt

    Thread Starter AAC Fanatic!

    Jan 18, 2008
    5,699
    907
    Just in case someone in the future finds this thread, I followed NorthGuy's lead and rewrote my code for decrement of the packed BCD registers.
    Code (Microchip Assembler):
    1.  
    2. Decrement                     ;decrement minute or second packed BCD registers
    3.      movlw     -1
    4.      addwf     min_sec,f
    5.      btfss     STATUS,0       ;Carry clear on borrow
    6.      goto      err            ;err routine simply ignores decrement request
    7.      movlw     6              
    8.      btfss     STATUS,1       ;DC clear on borrow, result goes back to original subtraction
    9.      subwf     min_sec,f      ;BCD correction for carrying 15 to low nibble
    10.      nop
    11.  
    Thanks again for the help.

    John
     
Loading...