un programa que prueba que el DS3231 funciona bien en una FRDMKL25Z
Revision 2:4e6e761c60f2, committed 2014-11-20
- Comitter:
- j3
- Date:
- Thu Nov 20 00:03:27 2014 +0000
- Parent:
- 1:c814af60fdbf
- Child:
- 3:312589d8185c
- Commit message:
- initial implementation of member functions
Changed in this revision
ds3231.cpp | Show annotated file Show diff for this revision Revisions of this file |
ds3231.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/ds3231.cpp Wed Nov 19 04:16:33 2014 +0000 +++ b/ds3231.cpp Thu Nov 20 00:03:27 2014 +0000 @@ -76,6 +76,8 @@ /**********************************************************//** * Sets the time on DS3231 +* Struct data is in integrer format, not BCD. Fx will convert +* to BCD for you. * * On Entry: * @param[in] time - struct cotaining time data; @@ -99,8 +101,42 @@ **************************************************************/ uint16_t Ds3231::set_time(ds3231_time_t time) { + uint8_t data[] = {0,0,0,0}; + uint8_t data_length = 0; + uint8_t max_hour = 24; - return 0; + data[data_length++] = SECONDS; + data[data_length++] = uchar_2_bcd(time.seconds); + data[data_length++] = uchar_2_bcd(time.minutes); + + //format Hours register + data[data_length] = uchar_2_bcd(time.hours); + if(time.mode) + { + max_hour = max_hour/2; + + data[data_length] |= MODE; + if(time.am_pm) + { + data[data_length] |= AM_PM; + } + + } + else + { + max_hour = max_hour - 1; + } + data_length++; + + //Test for good data. + if((time.seconds > 59) || (time.minutes > 59) || (time.hours > max_hour)) + { + return(1); + } + else + { + return(write(w_adrs,(const char*) data, data_length)); + } } @@ -130,8 +166,17 @@ **************************************************************/ uint16_t Ds3231::set_calendar(ds3231_calendar_t calendar) { + uint8_t data[] = {0,0,0,0,0}; + uint8_t data_length = 0; + + data[data_length++] = DAY; + data[data_length++] = uchar_2_bcd(calendar.day); + data[data_length++] = uchar_2_bcd(calendar.date); + data[data_length++] = uchar_2_bcd(calendar.month); + data[data_length++] = uchar_2_bcd(calendar.year); - return 0; + //users responsibility to make sure calendar is logical + return(write(w_adrs,(const char*) data, data_length)); } @@ -164,8 +209,128 @@ **************************************************************/ uint16_t Ds3231::set_alarm(ds3231_alrm_t alarm, bool one_r_two) { - - return 0; + uint8_t data[] = {0,0,0,0,0}; + uint8_t data_length = 0; + uint8_t max_hour = 24; + uint8_t mask_var = 0; + + //setting alarm 1 or 2? + if(one_r_two) + { + data[data_length++] = ALRM1_SECONDS; + + //config seconds register + if(alarm.am1) + { + mask_var |= ALRM_MASK; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.seconds)); + mask_var = 0; + + //config minutes register + if(alarm.am2) + { + mask_var |= ALRM_MASK; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes)); + mask_var = 0; + + //config hours register + if(alarm.am3) + { + mask_var |= ALRM_MASK; + } + if(alarm.mode) + { + max_hour = max_hour/2; + mask_var |= MODE; + if(alarm.am_pm) + { + mask_var |= AM_PM; + } + } + else + { + max_hour = max_hour - 1; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours)); + mask_var = 0; + + //config day/date register + if(alarm.am4) + { + mask_var |= ALRM_MASK; + } + if(alarm.dy_dt) + { + mask_var |= DY_DT; + data[data_length++] = (mask_var | uchar_2_bcd(alarm.day)); + } + else + { + data[data_length++] = (mask_var | uchar_2_bcd(alarm.date)); + } + mask_var = 0; + } + else + { + data[data_length++] = ALRM2_MINUTES; + + //config minutes register + if(alarm.am2) + { + mask_var |= ALRM_MASK; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes)); + mask_var = 0; + + //config hours register + if(alarm.am3) + { + mask_var |= ALRM_MASK; + } + if(alarm.mode) + { + max_hour = max_hour/2; + mask_var |= MODE; + if(alarm.am_pm) + { + mask_var |= AM_PM; + } + } + else + { + max_hour = max_hour - 1; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours)); + mask_var = 0; + + //config day/date register + if(alarm.am4) + { + mask_var |= ALRM_MASK; + } + if(alarm.dy_dt) + { + mask_var |= DY_DT; + data[data_length++] = (mask_var | uchar_2_bcd(alarm.day)); + } + else + { + data[data_length++] = (mask_var | uchar_2_bcd(alarm.date)); + } + mask_var = 0; + } + + //Test for good data. + if((alarm.seconds > 59) || (alarm.minutes > 59) || (alarm.hours > max_hour) || (alarm.day > 7) || (alarm.date > 31)) + { + return(1); + } + else + { + return(write(w_adrs,(const char*) data, data_length)); + } } @@ -194,8 +359,15 @@ **************************************************************/ uint16_t Ds3231::set_cntl_stat_reg(ds3231_cntl_stat_t data) { + uint8_t local_data[] = {0,0,0}; + uint8_t data_length = 0; + + local_data[data_length++] = CONTROL; + local_data[data_length++] = data.control; + local_data[data_length++] = data.status; - return 0; + //users responsibility to make sure data is logical + return(write(w_adrs,(const char*) local_data, data_length)); } @@ -203,11 +375,12 @@ * Gets the time on DS3231 * * On Entry: -* @param[in] time - struct for storing time data; -* seconds, minutes and hours +* @param[in] time - pointer to struct for storing time +* data; seconds, minutes and hours * * On Exit: -* @param[out] time - contains current rtc time data +* @param[out] time - contains current integrer rtc time +* data * @return return value = 0 on success, non-0 on failure * * Example: @@ -223,10 +396,24 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_time(ds3231_time_t time) +uint16_t Ds3231::get_time(ds3231_time_t* time) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[3]; + + data[0] = SECONDS; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 3); + + time->seconds = bcd_2_uchar(data[0]); + time->minutes = bcd_2_uchar(data[1]); + time->hours = bcd_2_uchar((data[2]&0x1F)); + } + + return(rtn_val); } @@ -234,11 +421,13 @@ * Gets the calendar on DS3231 * * On Entry: -* @param[in] calendar - struct for storing calendar data; +* @param[in] calendar - pointer to struct for storing +* calendar data; * day, date, month, year * * On Exit: -* @param[out] calendar - contains current rtc calendar +* @param[out] calendar - contains current integer rtc +* calendar data * @return return value = 0 on success, non-0 on failure * * Example: @@ -255,10 +444,25 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_calendar(ds3231_calendar_t calendar) +uint16_t Ds3231::get_calendar(ds3231_calendar_t* calendar) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[4]; + + data[0] = DAY; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 4); + + calendar->day = bcd_2_uchar(data[0]); + calendar->date = bcd_2_uchar(data[1]); + calendar->month = bcd_2_uchar((data[2]&0x1F)); + calendar->year = bcd_2_uchar(data[3]); + } + + return(rtn_val); } @@ -266,14 +470,16 @@ * Get either Alarm1 or Alarm2 of DS3231 * * On Entry: -* @param[in] alarm - struct for storing alarm data +* @param[in] alarm - pointer to struct for storing alarm +* data; * seconds, minutes, hours, day, date * seconds used on Alarm1 only +* * @param[in] one_r_two - TRUE for Alarm1 and FALSE for * Alarm2 * * On Exit: -* @param[out] alarm - contains alarm register data +* @param[out] alarm - contains integer alarm data * @return return value = 0 on success, non-0 on failure * * Example: @@ -290,10 +496,58 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_alarm(ds3231_alrm_t alarm, bool one_r_two) +uint16_t Ds3231::get_alarm(ds3231_alrm_t* alarm, bool one_r_two) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[4]; + + if(one_r_two) + { + data[0] = ALRM1_SECONDS; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 4); + + alarm->seconds = bcd_2_uchar(data[0]&0x7F); + alarm->minutes = bcd_2_uchar(data[1]&0x7F); + alarm->hours = bcd_2_uchar(data[2]&0x1F); + + if(data[3] & DY_DT) + { + alarm->day = bcd_2_uchar(data[3]&0x0F); + } + else + { + alarm->date = bcd_2_uchar(data[3]&0x3F); + } + } + } + else + { + data[0] = ALRM2_MINUTES; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 4); + + alarm->minutes = bcd_2_uchar(data[0]&0x7F); + alarm->hours = bcd_2_uchar(data[1]&0x1F); + + if(data[3] & DY_DT) + { + alarm->day = bcd_2_uchar(data[2]&0x0F); + } + else + { + alarm->date = bcd_2_uchar(data[2]&0x3F); + } + } + } + + return(rtn_val); } @@ -301,8 +555,8 @@ * Get control and status registers of DS3231 * * On Entry: -* @param[in] data - Struct for storing control and status -* register data +* @param[in] data - pointer to struct for storing control +* nd status register data * * On Exit: * @param[out] data - contains control and status registers @@ -322,10 +576,23 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_cntl_stat_reg(ds3231_cntl_stat_t data) +uint16_t Ds3231::get_cntl_stat_reg(ds3231_cntl_stat_t* data) { - - return 0; + uint16_t rtn_val = 1; + uint8_t local_data[2]; + + local_data[0] = CONTROL; + rtn_val = write(w_adrs, (const char*) local_data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) local_data, 2); + + data->control = local_data[0]; + data->status = local_data[1]; + } + + return(rtn_val); } @@ -333,11 +600,9 @@ * Get temperature data of DS3231 * * On Entry: -* @param[in] temp - Integer for storing temperature data * * On Exit: -* @param[out] temp - contains temperature data -* @return return value = 0 on success, non-0 on failure +* @return return value = raw temperature data * * Example: * @code @@ -345,16 +610,79 @@ * //instantiate rtc object * Ds3231 rtc(D14, D15); * -* //do not use 0xAA, see datasheet for appropriate data * uint16_t temp; * -* rtn_val = rtc.get_temperature(temp); +* temp = rtc.get_temperature(); * * @endcode **************************************************************/ -uint16_t Ds3231::get_temperature(uint16_t temp) +uint16_t Ds3231::get_temperature(void) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[2]; + + data[0] = MSB_TEMP; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + read(r_adrs,(char *) data, 2); + + rtn_val = data[0] << 8; + rtn_val |= data[1]; + } + + return(rtn_val); } + +/**********************************************************//** +* Private mmber fx, converts unsigned char to BCD +* +* On Entry: +* @param[in] data - 0-255 +* +* On Exit: +* @return bcd_result = BCD representation of data +* +**************************************************************/ +uint16_t Ds3231::uchar_2_bcd(uint8_t data) +{ + uint16_t bcd_result = 0; + + //Get hundreds + bcd_result |= ((data/100) << 8); + data = (data - (data/100)*100); + + //Get tens + bcd_result |= ((data/10) << 4); + data = (data - (data/10)*10); + + //Get ones + bcd_result |= data; + + return(bcd_result); +} + + +/**********************************************************//** +* Private mmber fx, converts BCD to a uint8_t +* +* On Entry: +* @param[in] bcd - 0-99 +* +* On Exit: +* @return rtn_val = integer rep. of BCD +* +**************************************************************/ +uint8_t Ds3231::bcd_2_uchar(uint8_t bcd) +{ + uint8_t rtn_val = 0; + + rtn_val += ((bcd&0xf0)>>4)*10; + rtn_val += (bcd&0x000f); + + return rtn_val; +} + +
--- a/ds3231.h Wed Nov 19 04:16:33 2014 +0000 +++ b/ds3231.h Thu Nov 20 00:03:27 2014 +0000 @@ -57,9 +57,10 @@ #define I2C_WRITE 0 #define I2C_READ 1 -#define AM_PM (1 << 5) -#define TIME_FORMAT (1 << 6) -#define DY_DT (1 << 6) +#define AM_PM (1 << 5) +#define MODE (1 << 6) +#define DY_DT (1 << 6) +#define ALRM_MASK (1 << 7) //control register bit masks #define A1IE (1 << 0) @@ -69,7 +70,7 @@ #define RS2 (1 << 4) #define CONV (1 << 5) #define BBSQW (1 << 6) -#define EOSC (1 << 7) +#define EOSC (1 << 7) //status register bit masks #define A1F (1 << 0) @@ -108,6 +109,8 @@ uint8_t seconds; uint8_t minutes; uint8_t hours; + bool am_pm; //TRUE for PM, same logic as datasheet + bool mode; //TRUE for 12 hour, same logic as datasheet }ds3231_time_t; @@ -127,6 +130,13 @@ uint8_t hours; uint8_t day; uint8_t date; + bool am1; //not used for alarm 2 + bool am2; + bool am3; + bool am4; + bool am_pm; //TRUE for PM, same logic as datasheet + bool mode; //TRUE for 12 hour, same logic as datasheet + bool dy_dt; //TRUE for Day, same logic as datasheet }ds3231_alrm_t; @@ -144,6 +154,31 @@ { uint8_t w_adrs, r_adrs; + /**********************************************************//** + * Private mmber fx, converts unsigned char to BCD + * + * On Entry: + * @param[in] data - 0-255 + * + * On Exit: + * @return bcd_result = BCD representation of data + * + **************************************************************/ + uint16_t uchar_2_bcd(uint8_t data); + + + /**********************************************************//** + * Private mmber fx, converts BCD to a uint8_t + * + * On Entry: + * @param[in] bcd - 0-99 + * + * On Exit: + * @return rtn_val = integer rep. of BCD + * + **************************************************************/ + uint8_t bcd_2_uchar(uint8_t bcd); + public: /**********************************************************//** * Constructor for Ds3231 Class @@ -168,6 +203,8 @@ /**********************************************************//** * Sets the time on DS3231 + * Struct data is in integrer format, not BCD. Fx will convert + * to BCD for you. * * On Entry: * @param[in] time - struct cotaining time data; @@ -194,6 +231,8 @@ /**********************************************************//** * Sets the calendar on DS3231 + * Struct data is in integrer format, not BCD. Fx will convert + * to BCD for you. * * On Entry: * @param[in] calendar - struct cotaining calendar data; @@ -221,6 +260,8 @@ /**********************************************************//** * Set either Alarm1 or Alarm2 of DS3231 + * Struct data is in integrer format, not BCD. Fx will convert + * to BCD for you. * * On Entry: * @param[in] alarm - struct cotaining alarm data @@ -279,11 +320,12 @@ * Gets the time on DS3231 * * On Entry: - * @param[in] time - struct for storing time data; - * seconds, minutes and hours + * @param[in] time - pointer to struct for storing time + * data; seconds, minutes and hours * * On Exit: - * @param[out] time - contains current rtc time data + * @param[out] time - contains current integrer rtc time + * data * @return return value = 0 on success, non-0 on failure * * Example: @@ -299,18 +341,20 @@ * * @endcode **************************************************************/ - uint16_t get_time(ds3231_time_t time); + uint16_t get_time(ds3231_time_t* time); /**********************************************************//** * Gets the calendar on DS3231 * * On Entry: - * @param[in] calendar - struct for storing calendar data; + * @param[in] calendar - pointer to struct for storing + * calendar data; * day, date, month, year * * On Exit: - * @param[out] calendar - contains current rtc calendar + * @param[out] calendar - contains current integer rtc + * calendar data * @return return value = 0 on success, non-0 on failure * * Example: @@ -327,21 +371,23 @@ * * @endcode **************************************************************/ - uint16_t get_calendar(ds3231_calendar_t calendar); + uint16_t get_calendar(ds3231_calendar_t* calendar); /**********************************************************//** * Get either Alarm1 or Alarm2 of DS3231 * * On Entry: - * @param[in] alarm - struct for storing alarm data + * @param[in] alarm - pointer to struct for storing alarm + * data; * seconds, minutes, hours, day, date * seconds used on Alarm1 only + * * @param[in] one_r_two - TRUE for Alarm1 and FALSE for * Alarm2 * * On Exit: - * @param[out] alarm - contains alarm register data + * @param[out] alarm - contains integer alarm data * @return return value = 0 on success, non-0 on failure * * Example: @@ -358,15 +404,15 @@ * * @endcode **************************************************************/ - uint16_t get_alarm(ds3231_alrm_t alarm, bool one_r_two); + uint16_t get_alarm(ds3231_alrm_t* alarm, bool one_r_two); /**********************************************************//** * Get control and status registers of DS3231 * * On Entry: - * @param[in] data - Struct for storing control and status - * register data + * @param[in] data - pointer to struct for storing control + * nd status register data * * On Exit: * @param[out] data - contains control and status registers @@ -386,18 +432,16 @@ * * @endcode **************************************************************/ - uint16_t get_cntl_stat_reg(ds3231_cntl_stat_t data); + uint16_t get_cntl_stat_reg(ds3231_cntl_stat_t* data); /**********************************************************//** * Get temperature data of DS3231 * * On Entry: - * @param[in] temp - Integer for storing temperature data * * On Exit: - * @param[out] temp - contains temperature data - * @return return value = 0 on success, non-0 on failure + * @return return value = raw temperature data * * Example: * @code @@ -405,14 +449,13 @@ * //instantiate rtc object * Ds3231 rtc(D14, D15); * - * //do not use 0xAA, see datasheet for appropriate data * uint16_t temp; * - * rtn_val = rtc.get_temperature(temp); + * temp = rtc.get_temperature(); * * @endcode **************************************************************/ - uint16_t get_temperature(uint16_t temp); + uint16_t get_temperature(void); }; #endif /* DS3231_H*/