CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Basic DS3231 driver

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
temtronic



Joined: 01 Jul 2010
Posts: 8220
Location: Greensville,Ontario

View user's profile Send private message

Basic DS3231 driver
PostPosted: Tue Apr 13, 2021 4:49 am     Reply with quote

Below is a basic driver for the DS3231 RTC chip, essentially modiifed DS1307 code, so not all features, but it does set/get time info.
Code:

////////////////////////////////////////////////////////////////////////////////
/// jay_rtc3231 from jay_DS1307.C ///
/// Driver for Real Time Clock ///
// ds3231_init() - Enable oscillator without clearing the seconds register -///
// enable square wave output at 1Hz
// ds3231_set_date_time(year,mth,day,dow,hrs,min,sec) Set the date/time ///
// ds3231_get_date_time(year,mth,day,dow,hrs,min,sec) Get the date/time
// ds3231_get_date(year,mth,day,dow) Get the date ///
//
// ds3231_get_time(hrs,min,sec) Get the time ///

//setup RTC pins
#ifndef   RTC_SDA
#define RTC_SDA PIN_B1
#define RTC_SCL PIN_B2
#endif

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds3231_init(void)
{
BYTE seconds = 0;

i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_start();
i2c_write(0xD1); // RD from RTC
seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
i2c_stop();
seconds &= 0x7F;

delay_us(3);

i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x0E); // point to Control Register
i2c_write(0b01000000); // Enable squarewave output pin
i2c_stop();

}
void ds3231_set_date_time(BYTE rtcyer, BYTE rtcmth, BYTE rtcday, BYTE rtcdow, BYTE rtchrs, BYTE rtcmin, BYTE rtcsec)
{
rtcsec &= 0x7F;
rtchrs &= 0x3F;

i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_write(bin2bcd(rtcsec)); // REG 0
i2c_write(bin2bcd(rtcmin)); // REG 1
i2c_write(bin2bcd(rtchrs)); // REG 2
i2c_write(bin2bcd(rtcdow)); // REG 3
i2c_write(bin2bcd(rtcday)); // REG 4
i2c_write(bin2bcd(rtcmth)); // REG 5
i2c_write(bin2bcd(rtcyer)); // REG 6
i2c_stop();
}

void ds3231_get_time(BYTE &rtchrs, BYTE &rtcmin, BYTE &rtcsec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
rtcsec = bcd2bin(i2c_read() & 0x7f);
rtcmin = bcd2bin(i2c_read() & 0x7f);
rtchrs = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
}

void ds3231_get_date(BYTE &rtcyer, BYTE &rtcmth, BYTE &rtcday, BYTE &rtcdow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03); // Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
rtcdow = bcd2bin(i2c_read() & 0x7f); // REG 3
rtcday = bcd2bin(i2c_read() & 0x3f); // REG 4
rtcmth = bcd2bin(i2c_read() & 0x1f); // REG 5
rtcyer = bcd2bin(i2c_read(0)); // REG 6
i2c_stop();
}

void ds3231_get_date_time(BYTE &rtcyer, BYTE &rtcmth, BYTE &rtcday, BYTE &rtcdow, BYTE &rtchrs, BYTE &rtcmin, BYTE &rtcsec)
{
i2c_start();
i2c_write(0xD0);               // WRITE cmd
i2c_write(0x00);               // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);                // READ cmd
rtcsec = bcd2bin(i2c_read() & 0x7f);   // REG 0
rtcmin = bcd2bin(i2c_read() & 0x7f);   // REG 1
rtchrs = bcd2bin(i2c_read() & 0x3f);   // REG 2
rtcdow = bcd2bin(i2c_read() & 0x7f);   // REG 3
rtcday = bcd2bin(i2c_read() & 0x3f);   // REG 4
rtcmth = bcd2bin(i2c_read() & 0x1f);   // REG 5
rtcyer = bcd2bin(i2c_read(0));         // REG 6
i2c_stop();
}

BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;

temp = binary_value;
retval = 0;

while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}

return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;

temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;

// Now return: (Tens * 8) + (Tens * 2) + Ones

return(temp + (temp >> 2) + (bcd_value & 0x0f));
}

//read DS3231 temerature sensor
void ds3231_get_temp(BYTE &rtctms, BYTE &rtctls)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x11); // Start at temperature MSB
i2c_start();
i2c_write(0xD1);
rtctms = i2c_read();
rtctls = i2c_read(0);
i2c_stop();
}

// returns chip temperature
// Temperature is stored in hundredths C (output value of "3125" equals 31.25 °C).
unsigned int16 Get_RTC_Temperature()
{
  char t_msb, t_lsb;
  unsigned int16 c_temp;
   I2C_START();
  I2C_WRITE(0xd0);
  I2C_WRITE(0x11);
  I2C_START();
  I2C_WRITE(0xd1);
  t_msb = I2C_READ(1);
  t_lsb = I2C_READ(0);
  I2C_STOP();

  c_temp = (unsigned int16)t_msb << 2 | t_lsb >> 6;

  if(t_msb & 0x80)
    c_temp |= 0xFC00;

  return c_temp * 25;
}

void ds3231_set_RAM(BYTE &rtcrm7,BYTE &rtcrm8,BYTE &rtcrm9,BYTE &rtcrmA,BYTE &rtcrmB,BYTE &rtcrmC,BYTE &rtcrmD)
{
i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x07); // Start at REG 7 'alarm data'
i2c_write(rtcrm7); // REG 7
i2c_write(rtcrm8); // REG 8
i2c_write(rtcrm9); // REG 9
i2c_write(rtcrmA); // REG A
i2c_write(rtcrmB); // REG B
i2c_write(rtcrmC); // REG C
i2c_write(rtcrmD); // REG D
i2c_stop();
}

void ds3231_get_RAM(BYTE &rtcrm7,BYTE &rtcrm8,BYTE &rtcrm9,BYTE &rtcrmA,BYTE &rtcrmB,BYTE &rtcrmC,BYTE &rtcrmD)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x07); // Start at REG 7 - 'alarm data'
i2c_start();
i2c_write(0xD1);
rtcrm7 = i2c_read(); // read all 7 bytes of RTC RAM
rtcrm8 = i2c_read(); // aka  alarm bits
rtcrm9 = i2c_read(); // and bytes
rtcrmA = i2c_read();
rtcrmB = i2c_read();
rtcrmC = i2c_read();
rtcrmD = i2c_read(0);
i2c_stop();
}

robleso7473



Joined: 25 Mar 2009
Posts: 9

View user's profile Send private message

Thanks for posting code
PostPosted: Tue May 25, 2021 1:54 pm     Reply with quote

Thanks Temtronic, saved me some time implementing this.
Big O
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group