Setting time on DS3231 using PIC16F887 problems - Page 1
Forum section: electronics / general

author: newtekuser
author_rank: Frequent Contributor
timestamp: August 27, 2023, 01:28:55 am
content: I'm having the following issues setting the time correctly on a DS3231 chip.1. if I set the hour to 12 and set the pm bit with the code below, the value for the hour is 04 when read back2. If I set the time to 11:59 and pm bit is not set, then the hour does not wrap around automatically given the 12 mode operation and instead increments to 13 as if 24 hour mode is setWhat am I doing wrong here?Code:oid ds3231_set_12_hour_mode() {// Read the current hour register valueI2C_Start();I2C_Write(0xD0);I2C_Write(0x02); // Hour register addressI2C_Repeated_Start();I2C_Write(0xD0 | 0x01); // Read addressuint8_t hourReg = I2C_Read(0);I2C_Stop();// Set the 12/24 hour mode bithourReg &= ~(1 << 6); // Clear 12/24 hour mode bit// Write the modified hour register value backI2C_Start();I2C_Write(0xD0);I2C_Write(0x02); // Hour register addressI2C_Write(hourReg);I2C_Stop();}void ds3231_set_time(uint8_t hours, uint8_t minutes, uint8_t isPM) {// Ensure hours and minutes are within valid rangesif (hours > 12) hours = 12;if (minutes > 59) minutes = 59;// Convert to 12-hour format and set the AM/PM flagif (isPM) {hours |= (1 << 5); // Set AM/PM flag}// Write new hour and minute valuesuint8_t hourReg = ((hours / 10) << 4) | (hours % 10);uint8_t minReg = ((minutes / 10) << 4) | (minutes % 10);I2C_Start();I2C_Write(0xD0);I2C_Write(0x01); // Address of the minute registerI2C_Write(minReg);I2C_Write(hourReg);I2C_Stop();}

author: Ground_Loop
author_rank: Frequent Contributor
timestamp: August 27, 2023, 02:47:19 am
content: Are you sure the registers are correct. I seem to recall seconds is 1, minutes is 2, hours is 3.

author: Peabody
author_rank: Super Contributor
timestamp: August 27, 2023, 02:55:05 am
content: Bit 6 of the hours register selects 12 or 24 hours. It should be set for 12 hours. It looks like your code clears it. Then if you are in 12-hour mode, but only then, bit 5 determines whether the current time is PM (set) or AM.Also, while it looks like you are converting the hour to BCD, I don't see where you convert the value you read back from BDC to a regular value. But I don't have time right now to study your code, so I may have missed this.Finally, when you write the hours register value, are you ORring in bits 5 and 6 before writing?Finally finally, in the Arduino world, the DS3231's I2C address is 0x68. I'm confused by the 0xD0.

author: newtekuser
author_rank: Frequent Contributor
timestamp: August 27, 2023, 03:10:16 am
content: Quote from: Peabody on August 27, 2023, 02:55:05 amMy DS3231 cannot be accessed using address 0x68, it only works with 0xD0.https://simple-circuit.com/pic18f4550-ssd1306-ds3231-rtcc/

author: newtekuser
author_rank: Frequent Contributor
timestamp: August 27, 2023, 03:20:02 am
content: Quote from: Ground_Loop on August 27, 2023, 02:47:19 amPer the DS3231 datasheet they are correct.

author: zilp
author_rank: Frequent Contributor
timestamp: August 27, 2023, 05:08:35 am
content: Quote from: newtekuser on August 27, 2023, 01:28:55 amMaybe that's the clue as to what is wrong? ;-)

author: newtekuser
author_rank: Frequent Contributor
timestamp: August 27, 2023, 05:27:42 am
content: Quote from: zilp on August 27, 2023, 05:08:35 amYes, that's what it was essentially. I did not do the bcd to dec and dec to bcd where applicable the correct way so the bit for 12 hour mode was never set. Now I'm seeing the time working correctly.The only thing to do now is to display AM PM depending on the time of day since the DS3231 doesn't do that automatically.

author: woofy
author_rank: Frequent Contributor
timestamp: August 27, 2023, 09:01:11 am
content: Quote from: Peabody on August 27, 2023, 02:55:05 amIts the same thing. 0xD0 is 0x68 shifted left 1 bit. I2C addresses are 7-bit but in the upper 7 bits of the 8 bit address byte. The lower bit is the read/write bit.Arduino uses 0x68 and takes care of the shifting and adding the read/write bit, hiding this from the user. The actual byte value the chip wants is 0xD0 to write and 0xD1 to read.