Weird Issue with DS1306 Realtime Clock not wrapping the hours at midnight - Page 1
Forum section: electronics / projects

author: timbos
author_rank: Contributor
timestamp: March 24, 2013, 03:41:25 pm
content: I've got a little DS1306 RTC chip with Alarm that I'm using to wake up a PIC microcontroller at specific times through the day.I've just done an overnight test with it, and it seems that the hour counter doesn't wrap to 00 at midnight, but keeps counting up. I noticed this when my LCD reported that it was 25 O'clock when I came to my bench this morning. Now, the datasheet implies that it can only have values from 00-23 so my first thought was to check the BCD to Decimal convertor that I wrote, but that seems OK.When I run the application through the debugger, it looks like the BCD coded data returned over SPI is indeed 24, when it should be 00. I've scoured the datasheet for gotchas and can't see anything -- does anyone know what I'm missing?

author: timbos
author_rank: Contributor
timestamp: March 25, 2013, 08:52:24 am
content: Overnight I wondered if there was an issue because I wasn't setting the date into the DS1306. Having just tried that, it still wraps from 23:59:59 to 24:00:00 etc.

author: David_AVD
author_rank: Super Contributor
timestamp: March 25, 2013, 09:14:34 am
content: Sounds like you're not decoding the hour register correctly.

author: amyk
author_rank: Super Contributor
timestamp: March 25, 2013, 10:00:24 am
content: Have you set the date correctly, using BCD format?It's also not out of the question that you could have a defective chip. What happens after 25:00:00? Does the date eventually go over, or keep going until 99:59:59?

author: timbos
author_rank: Contributor
timestamp: March 25, 2013, 06:39:34 pm
content: When I debugged it, I looked at the raw BCD data that comes back into a buffer on my PIC. It matches the number that's decoded i.e. 24:00:00 (actually, the RTC returns 0x64, 0x00, 0x00 for that time since bit 6 of the hour variable is used to signify 24h mode).@amyk: I've not had the patience to let it get as high as 99:59, but it certainly has gone as high as 27 or 28 before I started messing with it to try and work out what was happening. I set the date to 1/1/1 (or rather 0x01, 0x01, 0x01).

author: C
author_rank: Super Contributor
timestamp: March 25, 2013, 07:17:40 pm
content: From Data sheetQuoteQuoteQuestion could you be writing a 1 to some of the 0 bits?I note that this ram & clock and that you can read & write a block of bytes.I would create a block write function and a block read function to move data between pic memory and the DS1306 ram, When this is working, change the address and length to the clock block and send a prebuilt block of data and then read block back. For testing I would end up with 4 blocks in pic memory. I would not write or read the RESERVED area. Note a small delay may be needed between writes and reads.C

author: timbos
author_rank: Contributor
timestamp: March 25, 2013, 10:36:53 pm
content: Quote from: C on March 25, 2013, 07:17:40 pmI don't think so.I'm able to read and write to RAM without an issue, and I get back the data that I expect. Here's the code that I'm using to debug (I stripped out everything that doesn't relate to this issue): MCC18, running in MPLABX.If I set a breakpoint on the last Delay1KTCY(10), the first time it hits it, I see the time read back as it was set. Next time round it's advanced a few seconds and the hours have rolled over to 13 (in this particular incarnation, it's in 12h format rather than 24h just in case I was doing something silly).Code:#include <p18f2550.h>#include <delays.h>#include <spi.h>#include <stdio.h>#include <string.h>#pragma config FOSC = INTOSC_HS //internal oscillator#pragma config WDT = OFF //no watchdog#pragma config VREGEN = OFF //disable USB regulator#pragma config LPT1OSC = ON //low power timer 1#pragma config PLLDIV = 1#pragma config BOR = OFF#pragma config PBADEN = OFF#pragma config LVP = OFF //Single supply ICSP disabled//Pins Outputs#define _RTCSelect LATAbits.LATA2void main(void){char data;TRISA=0;TRISB=0xfc; //PortB is an input apart from SPI outputs.//First write the the Control register to set up the RTCDelay10KTCYx(2);_RTCSelect = 1;OpenSPI(SLV_SSOFF & SPI_FOSC_4, MODE_01, SMPEND);Delay1KTCYx(1);WriteSPI(0x8f); //Select Control Register on DS1306 RTCWriteSPI(0x00); //make sure it's writeable (bit 6=0), disable alarms and interruptsCloseSPI();_RTCSelect = 0;Delay1KTCYx(10);//Write some time data to the RTCOpenSPI(SLV_SSOFF & SPI_FOSC_4, MODE_01, SMPEND);_RTCSelect = 1;Delay1KTCYx(1);WriteSPI(0x80); //Select time write registersWriteSPI(0x55);//sWriteSPI(0x59);//mWriteSPI(0x31);//h 11pm (set bit 5 high for PM)WriteSPI(0x05);//dayWriteSPI(0x10);//dateWriteSPI(0x08);//mWriteSPI(0x55);//y_RTCSelect = 0;CloseSPI();Delay1KTCYx(10);while(1){OpenSPI(SLV_SSOFF & SPI_FOSC_4, MODE_01, SMPEND);_RTCSelect = 1;Delay1KTCYx(1);WriteSPI(0x00); //Select Read from time registers on DS1306 RTCgetsSPI(data,7); //get 7 bits of data_RTCSelect = 0;CloseSPI();Delay1KTCYx(10); //<----- Breakpoint set here to examine value of data}}

author: David_AVD
author_rank: Super Contributor
timestamp: March 25, 2013, 11:15:42 pm
content: Where's the code that decodes the time after the read?

author: Len
author_rank: Frequent Contributor
timestamp: March 26, 2013, 02:43:59 am
content: Quote from: timbos on March 25, 2013, 06:39:34 pmIf the hours register is 0x64, that's 4 PM. Bit 6 is 1 which indicates 12-hour mode, bit 5 is 1 which means PM.

author: C
author_rank: Super Contributor
timestamp: March 26, 2013, 02:48:57 am
content: compare your data vs table

author: timbos
author_rank: Contributor
timestamp: March 26, 2013, 08:53:16 am
content: Quote from: David_AVD on March 25, 2013, 11:15:42 pmI left it out of this example because I was using the debugger to examine the raw data as it came back from the RTC.FWIW, I used a BCD to Decimal routine that looks like this:Code:int BCDtoDec(unsigned char bcdByte){return (((bcdByte & 0xF0) >> 4)*10) + (bcdByte & 0x0F);}Quote from: Len on March 26, 2013, 02:43:59 amWE HAVE A WINNER! That's the mistake I made: misreading the datasheet that bit 6 is high for 24h mode. It's not. Bit 6 is low for 24h mode, so I was misreading my data.Thanks everyone!

author: David_AVD
author_rank: Super Contributor
timestamp: March 26, 2013, 08:54:57 am
content: LOL - didn't I say that ages ago?Quote

author: timbos
author_rank: Contributor
timestamp: March 26, 2013, 09:13:28 am
content: You did. I checked what I was doing when you wrote that, but still had the wrong schema in my head so didn't see my mistake.