Author Topic: Setting time on DS3231 using PIC16F887 problems  (Read 948 times)

0 Members and 1 Guest are viewing this topic.

Offline newtekuserTopic starter

  • Frequent Contributor
  • **
  • Posts: 356
  • Country: us
Setting time on DS3231 using PIC16F887 problems
« on: August 27, 2023, 01:28:55 am »
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 back
2. 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 set

What am I doing wrong here?

Code: [Select]
oid ds3231_set_12_hour_mode() {
    // Read the current hour register value
    I2C_Start();
    I2C_Write(0xD0);
    I2C_Write(0x02); // Hour register address
    I2C_Repeated_Start();
    I2C_Write(0xD0 | 0x01); // Read address
    uint8_t hourReg = I2C_Read(0);
    I2C_Stop();
   
    // Set the 12/24 hour mode bit
    hourReg &= ~(1 << 6); // Clear 12/24 hour mode bit
   
    // Write the modified hour register value back
    I2C_Start();
    I2C_Write(0xD0);
    I2C_Write(0x02); // Hour register address
    I2C_Write(hourReg);
    I2C_Stop();
}

void ds3231_set_time(uint8_t hours, uint8_t minutes, uint8_t isPM) {
    // Ensure hours and minutes are within valid ranges
    if (hours > 12) hours = 12;
    if (minutes > 59) minutes = 59;

    // Convert to 12-hour format and set the AM/PM flag
    if (isPM) {
        hours |= (1 << 5); // Set AM/PM flag
    }

    // Write new hour and minute values
    uint8_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 register
    I2C_Write(minReg);
    I2C_Write(hourReg);
    I2C_Stop();
}
 

Online Ground_Loop

  • Frequent Contributor
  • **
  • Posts: 645
  • Country: us
Re: Setting time on DS3231 using PIC16F887 problems
« Reply #1 on: August 27, 2023, 02:47:19 am »
Are you sure the registers are correct. I seem to recall seconds is 1, minutes is 2, hours is 3.
« Last Edit: August 27, 2023, 02:51:40 am by Ground_Loop »
There's no point getting old if you don't have stories.
 

Offline Peabody

  • Super Contributor
  • ***
  • Posts: 2008
  • Country: us
Re: Setting time on DS3231 using PIC16F887 problems
« Reply #2 on: August 27, 2023, 02:55:05 am »
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.
 

Offline newtekuserTopic starter

  • Frequent Contributor
  • **
  • Posts: 356
  • Country: us
Re: Setting time on DS3231 using PIC16F887 problems
« Reply #3 on: August 27, 2023, 03:10:16 am »
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.

My DS3231 cannot be accessed using address 0x68, it only works with 0xD0. https://simple-circuit.com/pic18f4550-ssd1306-ds3231-rtcc/
 

Offline newtekuserTopic starter

  • Frequent Contributor
  • **
  • Posts: 356
  • Country: us
Re: Setting time on DS3231 using PIC16F887 problems
« Reply #4 on: August 27, 2023, 03:20:02 am »
Are you sure the registers are correct. I seem to recall seconds is 1, minutes is 2, hours is 3.

Per the DS3231 datasheet they are correct.

 

Offline zilp

  • Regular Contributor
  • *
  • Posts: 206
  • Country: de
Re: Setting time on DS3231 using PIC16F887 problems
« Reply #5 on: August 27, 2023, 05:08:35 am »
as if 24 hour mode is set

Maybe that's the clue as to what is wrong? ;-)
 

Offline newtekuserTopic starter

  • Frequent Contributor
  • **
  • Posts: 356
  • Country: us
Re: Setting time on DS3231 using PIC16F887 problems
« Reply #6 on: August 27, 2023, 05:27:42 am »
as if 24 hour mode is set

Maybe that's the clue as to what is wrong? ;-)

Yes, 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.
 

Online woofy

  • Frequent Contributor
  • **
  • Posts: 335
  • Country: gb
    • Woofys Place
Re: Setting time on DS3231 using PIC16F887 problems
« Reply #7 on: August 27, 2023, 09:01:11 am »
...
Finally finally, in the Arduino world, the DS3231's I2C address is 0x68.  I'm confused by the 0xD0.

Its 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.
 
The following users thanked this post: newtekuser


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf