DS3231
DS3231.h@16:610f7091e0ac, 2021-05-08 (annotated)
- Committer:
- lukas_formanek
- Date:
- Sat May 08 16:13:55 2021 +0000
- Revision:
- 16:610f7091e0ac
- Parent:
- 15:bf11392ccaea
LoRa_Access_Point
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lukas_formanek | 15:bf11392ccaea | 1 | /** mbded library for driving the PMAXIM DS3231 Real Time Clock |
lukas_formanek | 15:bf11392ccaea | 2 | * datasheet link : http://datasheets.maximintegrated.com/en/ds/DS3231.pdf |
lukas_formanek | 15:bf11392ccaea | 3 | * breakout : MACETECH ChronoDot V2.1 High Precision RTC |
lukas_formanek | 15:bf11392ccaea | 4 | * remi cormier 2012 |
lukas_formanek | 15:bf11392ccaea | 5 | * WARNING : sda and sdl should be pulled up with 2.2k resistor |
lukas_formanek | 15:bf11392ccaea | 6 | */ |
lukas_formanek | 15:bf11392ccaea | 7 | |
lukas_formanek | 15:bf11392ccaea | 8 | /** Example code |
lukas_formanek | 15:bf11392ccaea | 9 | * @code |
lukas_formanek | 15:bf11392ccaea | 10 | // DS3231 Library test program |
lukas_formanek | 15:bf11392ccaea | 11 | // remi cormier 2012 |
lukas_formanek | 15:bf11392ccaea | 12 | |
lukas_formanek | 15:bf11392ccaea | 13 | #include "mbed.h" |
lukas_formanek | 15:bf11392ccaea | 14 | #include "DS3231.h" |
lukas_formanek | 15:bf11392ccaea | 15 | |
lukas_formanek | 15:bf11392ccaea | 16 | Serial pc(USBTX, USBRX); |
lukas_formanek | 15:bf11392ccaea | 17 | |
lukas_formanek | 15:bf11392ccaea | 18 | int hour; |
lukas_formanek | 15:bf11392ccaea | 19 | int minute; |
lukas_formanek | 15:bf11392ccaea | 20 | int second; |
lukas_formanek | 15:bf11392ccaea | 21 | |
lukas_formanek | 15:bf11392ccaea | 22 | int dayOfWeek; |
lukas_formanek | 15:bf11392ccaea | 23 | int date; |
lukas_formanek | 15:bf11392ccaea | 24 | int month; |
lukas_formanek | 15:bf11392ccaea | 25 | int year; |
lukas_formanek | 15:bf11392ccaea | 26 | |
lukas_formanek | 15:bf11392ccaea | 27 | DS3231 RTC(p28,p27); |
lukas_formanek | 15:bf11392ccaea | 28 | |
lukas_formanek | 15:bf11392ccaea | 29 | |
lukas_formanek | 15:bf11392ccaea | 30 | int main() |
lukas_formanek | 15:bf11392ccaea | 31 | {printf("\r\n\nDS3231 Library test program\r\nremi cormier 2012\r\n\n"); |
lukas_formanek | 15:bf11392ccaea | 32 | |
lukas_formanek | 15:bf11392ccaea | 33 | RTC.setI2Cfrequency(400000); |
lukas_formanek | 15:bf11392ccaea | 34 | |
lukas_formanek | 15:bf11392ccaea | 35 | //RTC.writeRegister(DS3231_Aging_Offset,0); // uncomment to set Aging Offset 1LSB = approx. 0.1 ppm according from datasheet = 0.05 ppm @ 21 °C from my measurments |
lukas_formanek | 15:bf11392ccaea | 36 | |
lukas_formanek | 15:bf11392ccaea | 37 | RTC.convertTemperature(); |
lukas_formanek | 15:bf11392ccaea | 38 | |
lukas_formanek | 15:bf11392ccaea | 39 | int reg=RTC.readRegister(DS3231_Aging_Offset); |
lukas_formanek | 15:bf11392ccaea | 40 | if (reg>127) |
lukas_formanek | 15:bf11392ccaea | 41 | {reg=reg-256;} |
lukas_formanek | 15:bf11392ccaea | 42 | pc.printf("Aging offset : %i\r\n",reg); |
lukas_formanek | 15:bf11392ccaea | 43 | |
lukas_formanek | 15:bf11392ccaea | 44 | pc.printf("OSF flag : %i",RTC.OSF()); |
lukas_formanek | 15:bf11392ccaea | 45 | pc.printf("\r\n"); |
lukas_formanek | 15:bf11392ccaea | 46 | |
lukas_formanek | 15:bf11392ccaea | 47 | RTC.readDate(&date,&month,&year); |
lukas_formanek | 15:bf11392ccaea | 48 | pc.printf("date : %02i-%02i-%02i",date,month,year); |
lukas_formanek | 15:bf11392ccaea | 49 | pc.printf("\r\n"); |
lukas_formanek | 15:bf11392ccaea | 50 | |
lukas_formanek | 15:bf11392ccaea | 51 | //RTC.setTime(19,48,45); // uncomment to set time |
lukas_formanek | 15:bf11392ccaea | 52 | |
lukas_formanek | 15:bf11392ccaea | 53 | RTC.readTime(&hour,&minute,&second); |
lukas_formanek | 15:bf11392ccaea | 54 | pc.printf("time : %02i:%02i:%02i",hour,minute,second); |
lukas_formanek | 15:bf11392ccaea | 55 | pc.printf("\r\n"); |
lukas_formanek | 15:bf11392ccaea | 56 | |
lukas_formanek | 15:bf11392ccaea | 57 | //RTC.setDate(6,22,12,2012); // uncomment to set date |
lukas_formanek | 15:bf11392ccaea | 58 | |
lukas_formanek | 15:bf11392ccaea | 59 | RTC.readDateTime(&dayOfWeek,&date,&month,&year,&hour,&minute,&second); |
lukas_formanek | 15:bf11392ccaea | 60 | pc.printf("date time : %i / %02i-%02i-%02i %02i:%02i:%02i",dayOfWeek,date,month,year,hour,minute,second); |
lukas_formanek | 15:bf11392ccaea | 61 | pc.printf("\r\n"); |
lukas_formanek | 15:bf11392ccaea | 62 | |
lukas_formanek | 15:bf11392ccaea | 63 | pc.printf("temperature :%6.2f",RTC.readTemp()); |
lukas_formanek | 15:bf11392ccaea | 64 | pc.printf("\r\n"); |
lukas_formanek | 15:bf11392ccaea | 65 | } |
lukas_formanek | 15:bf11392ccaea | 66 | * @endcode |
lukas_formanek | 15:bf11392ccaea | 67 | */ |
lukas_formanek | 15:bf11392ccaea | 68 | |
lukas_formanek | 15:bf11392ccaea | 69 | |
lukas_formanek | 15:bf11392ccaea | 70 | #include "mbed.h" |
lukas_formanek | 15:bf11392ccaea | 71 | |
lukas_formanek | 15:bf11392ccaea | 72 | #ifndef MBED_DS3231_H |
lukas_formanek | 15:bf11392ccaea | 73 | #define MBED_DS3231_H |
lukas_formanek | 15:bf11392ccaea | 74 | |
lukas_formanek | 16:610f7091e0ac | 75 | #define DS3231_I2C_ADRS 0x68 |
lukas_formanek | 16:610f7091e0ac | 76 | #define I2C_WRITE 0 |
lukas_formanek | 16:610f7091e0ac | 77 | #define I2C_READ 1 |
lukas_formanek | 16:610f7091e0ac | 78 | |
lukas_formanek | 15:bf11392ccaea | 79 | //DS3231 8 bit adress |
lukas_formanek | 15:bf11392ccaea | 80 | #define DS3231_Address 0xD0 |
lukas_formanek | 16:610f7091e0ac | 81 | //#define DS3231_Address 0x68 |
lukas_formanek | 15:bf11392ccaea | 82 | |
lukas_formanek | 15:bf11392ccaea | 83 | //DS3231 registers |
lukas_formanek | 15:bf11392ccaea | 84 | #define DS3231_Seconds 0x00 |
lukas_formanek | 15:bf11392ccaea | 85 | #define DS3231_Minutes 0x01 |
lukas_formanek | 15:bf11392ccaea | 86 | #define DS3231_Hours 0x02 |
lukas_formanek | 15:bf11392ccaea | 87 | // DS3231 Hours bits |
lukas_formanek | 15:bf11392ccaea | 88 | #define DS3231_bit_AM_PM 0x20 |
lukas_formanek | 15:bf11392ccaea | 89 | #define DS3231_bit_12_24 0x40 |
lukas_formanek | 15:bf11392ccaea | 90 | |
lukas_formanek | 15:bf11392ccaea | 91 | #define DS3231_Day 0x03 |
lukas_formanek | 15:bf11392ccaea | 92 | #define DS3231_Date 0x04 |
lukas_formanek | 15:bf11392ccaea | 93 | #define DS3231_Month_Century 0x05 |
lukas_formanek | 15:bf11392ccaea | 94 | #define DS3231_Year 0x06 |
lukas_formanek | 15:bf11392ccaea | 95 | #define DS3231_Alarm1_Seconds 0x07 |
lukas_formanek | 15:bf11392ccaea | 96 | #define DS3231_Alarm1_Minutes 0x08 |
lukas_formanek | 15:bf11392ccaea | 97 | #define DS3231_Alarm1_Hours 0x09 |
lukas_formanek | 15:bf11392ccaea | 98 | #define DS3231_Alarm1_Day_Date 0x0A |
lukas_formanek | 15:bf11392ccaea | 99 | #define DS3231_Alarm2_Minutes 0x0B |
lukas_formanek | 15:bf11392ccaea | 100 | #define DS3231_Alarm2_Hours 0x0C |
lukas_formanek | 15:bf11392ccaea | 101 | #define DS3231_Alarm_2_Day_Date 0x0D |
lukas_formanek | 15:bf11392ccaea | 102 | |
lukas_formanek | 15:bf11392ccaea | 103 | #define DS3231_Control 0x0E |
lukas_formanek | 15:bf11392ccaea | 104 | // DS3231 Control bits |
lukas_formanek | 15:bf11392ccaea | 105 | #define DS3231_bit_A1IE 1 |
lukas_formanek | 15:bf11392ccaea | 106 | #define DS3231_bit_A2IE 2 |
lukas_formanek | 15:bf11392ccaea | 107 | #define DS3231_bit_INTCN 4 |
lukas_formanek | 15:bf11392ccaea | 108 | #define DS3231_bit_SQW_1Hz 0 |
lukas_formanek | 15:bf11392ccaea | 109 | #define DS3231_bit_SQW_1024Hz 8 |
lukas_formanek | 15:bf11392ccaea | 110 | #define DS3231_bit_SQW_4096Hz 16 |
lukas_formanek | 15:bf11392ccaea | 111 | #define DS3231_bit_SQW_8192Hz 24 |
lukas_formanek | 15:bf11392ccaea | 112 | #define DS3231_bit_CONV 32 |
lukas_formanek | 15:bf11392ccaea | 113 | #define DS3231_bit_BBSQW 64 |
lukas_formanek | 15:bf11392ccaea | 114 | #define DS3231_bit_EOSCb 128 |
lukas_formanek | 15:bf11392ccaea | 115 | |
lukas_formanek | 15:bf11392ccaea | 116 | |
lukas_formanek | 15:bf11392ccaea | 117 | #define DS3231_Control_Status 0x0F |
lukas_formanek | 15:bf11392ccaea | 118 | // DS3231 Control/Status bits |
lukas_formanek | 15:bf11392ccaea | 119 | #define DS3231_bit_BSY 0x04 |
lukas_formanek | 15:bf11392ccaea | 120 | #define DS3231_bit_EN32kHz 0x08 |
lukas_formanek | 15:bf11392ccaea | 121 | #define DS3231_bit_OSF 0x80 |
lukas_formanek | 15:bf11392ccaea | 122 | |
lukas_formanek | 15:bf11392ccaea | 123 | #define DS3231_Aging_Offset 0x10 |
lukas_formanek | 15:bf11392ccaea | 124 | #define DS3231_MSB_Temp 0x11 |
lukas_formanek | 15:bf11392ccaea | 125 | #define DS3231_LSB_Temp 0x12 |
lukas_formanek | 15:bf11392ccaea | 126 | |
lukas_formanek | 16:610f7091e0ac | 127 | /** |
lukas_formanek | 16:610f7091e0ac | 128 | * ds3231_cntl_stat_t - Struct for containing control and status |
lukas_formanek | 16:610f7091e0ac | 129 | * register data. |
lukas_formanek | 16:610f7091e0ac | 130 | * |
lukas_formanek | 16:610f7091e0ac | 131 | * Members: |
lukas_formanek | 16:610f7091e0ac | 132 | * |
lukas_formanek | 16:610f7091e0ac | 133 | * - uint8_t control - Binary data for read/write of control register |
lukas_formanek | 16:610f7091e0ac | 134 | * |
lukas_formanek | 16:610f7091e0ac | 135 | * - uint8_t status - Binary data for read/write of status register |
lukas_formanek | 16:610f7091e0ac | 136 | */ |
lukas_formanek | 16:610f7091e0ac | 137 | typedef struct |
lukas_formanek | 16:610f7091e0ac | 138 | { |
lukas_formanek | 16:610f7091e0ac | 139 | uint8_t control; |
lukas_formanek | 16:610f7091e0ac | 140 | uint8_t status; |
lukas_formanek | 16:610f7091e0ac | 141 | }ds3231_cntl_stat_t; |
lukas_formanek | 16:610f7091e0ac | 142 | |
lukas_formanek | 15:bf11392ccaea | 143 | /* Interface to MAXIM DS3231 RTC */ |
lukas_formanek | 15:bf11392ccaea | 144 | class DS3231 |
lukas_formanek | 15:bf11392ccaea | 145 | {public : |
lukas_formanek | 16:610f7091e0ac | 146 | |
lukas_formanek | 16:610f7091e0ac | 147 | /** |
lukas_formanek | 16:610f7091e0ac | 148 | * ds3231_regs_t - enumerated DS3231 registers |
lukas_formanek | 16:610f7091e0ac | 149 | */ |
lukas_formanek | 16:610f7091e0ac | 150 | typedef enum |
lukas_formanek | 16:610f7091e0ac | 151 | { |
lukas_formanek | 16:610f7091e0ac | 152 | SECONDS, |
lukas_formanek | 16:610f7091e0ac | 153 | MINUTES, |
lukas_formanek | 16:610f7091e0ac | 154 | HOURS, |
lukas_formanek | 16:610f7091e0ac | 155 | DAY, |
lukas_formanek | 16:610f7091e0ac | 156 | DATE, |
lukas_formanek | 16:610f7091e0ac | 157 | MONTH, |
lukas_formanek | 16:610f7091e0ac | 158 | YEAR, |
lukas_formanek | 16:610f7091e0ac | 159 | ALRM1_SECONDS, |
lukas_formanek | 16:610f7091e0ac | 160 | ALRM1_MINUTES, |
lukas_formanek | 16:610f7091e0ac | 161 | ALRM1_HOURS, |
lukas_formanek | 16:610f7091e0ac | 162 | ALRM1_DAY_DATE, |
lukas_formanek | 16:610f7091e0ac | 163 | ALRM2_MINUTES, |
lukas_formanek | 16:610f7091e0ac | 164 | ALRM2_HOURS, |
lukas_formanek | 16:610f7091e0ac | 165 | ALRM2_DAY_DATE, |
lukas_formanek | 16:610f7091e0ac | 166 | CONTROL, |
lukas_formanek | 16:610f7091e0ac | 167 | STATUS, |
lukas_formanek | 16:610f7091e0ac | 168 | AGING_OFFSET, //don't touch this register |
lukas_formanek | 16:610f7091e0ac | 169 | MSB_TEMP, |
lukas_formanek | 16:610f7091e0ac | 170 | LSB_TEMP |
lukas_formanek | 16:610f7091e0ac | 171 | }ds3231_regs_t; |
lukas_formanek | 16:610f7091e0ac | 172 | |
lukas_formanek | 15:bf11392ccaea | 173 | /** Create an instance of the DS3231 connected to specfied I2C pins |
lukas_formanek | 15:bf11392ccaea | 174 | * |
lukas_formanek | 15:bf11392ccaea | 175 | * @param sda The I2C data pin |
lukas_formanek | 15:bf11392ccaea | 176 | * @param scl The I2C clock pin |
lukas_formanek | 15:bf11392ccaea | 177 | */ |
lukas_formanek | 15:bf11392ccaea | 178 | DS3231(PinName sda, PinName scl); |
lukas_formanek | 15:bf11392ccaea | 179 | |
lukas_formanek | 15:bf11392ccaea | 180 | /** set I2C bus speed |
lukas_formanek | 15:bf11392ccaea | 181 | * @param frequency : I2C clocl frequenct (Hz) |
lukas_formanek | 15:bf11392ccaea | 182 | */ |
lukas_formanek | 15:bf11392ccaea | 183 | void setI2Cfrequency(int frequency); |
lukas_formanek | 15:bf11392ccaea | 184 | |
lukas_formanek | 15:bf11392ccaea | 185 | /** Read the temperature |
lukas_formanek | 15:bf11392ccaea | 186 | * |
lukas_formanek | 15:bf11392ccaea | 187 | * @return The temperature |
lukas_formanek | 15:bf11392ccaea | 188 | */ |
lukas_formanek | 15:bf11392ccaea | 189 | float readTemp(); |
lukas_formanek | 15:bf11392ccaea | 190 | |
lukas_formanek | 15:bf11392ccaea | 191 | /** Read the time registers |
lukas_formanek | 15:bf11392ccaea | 192 | * @param hours |
lukas_formanek | 15:bf11392ccaea | 193 | * @param minutes |
lukas_formanek | 15:bf11392ccaea | 194 | * @param seconds |
lukas_formanek | 15:bf11392ccaea | 195 | */ |
lukas_formanek | 15:bf11392ccaea | 196 | void readTime(int *hours, int *minutes, int *seconds); |
lukas_formanek | 15:bf11392ccaea | 197 | |
lukas_formanek | 15:bf11392ccaea | 198 | /** force temperature conversion |
lukas_formanek | 15:bf11392ccaea | 199 | * |
lukas_formanek | 15:bf11392ccaea | 200 | */ |
lukas_formanek | 15:bf11392ccaea | 201 | void convertTemperature(); |
lukas_formanek | 15:bf11392ccaea | 202 | |
lukas_formanek | 15:bf11392ccaea | 203 | /** Set the time registers |
lukas_formanek | 15:bf11392ccaea | 204 | * @param hours |
lukas_formanek | 15:bf11392ccaea | 205 | * @param minutes |
lukas_formanek | 15:bf11392ccaea | 206 | * @param seconds |
lukas_formanek | 15:bf11392ccaea | 207 | */ |
lukas_formanek | 15:bf11392ccaea | 208 | void setTime(int hours, int minutes, int seconds); |
lukas_formanek | 15:bf11392ccaea | 209 | |
lukas_formanek | 15:bf11392ccaea | 210 | /** Read the date registers |
lukas_formanek | 15:bf11392ccaea | 211 | * @param date |
lukas_formanek | 15:bf11392ccaea | 212 | * @param month |
lukas_formanek | 15:bf11392ccaea | 213 | * @param year |
lukas_formanek | 15:bf11392ccaea | 214 | */ |
lukas_formanek | 15:bf11392ccaea | 215 | void readDate(int *date, int *month, int *year); |
lukas_formanek | 15:bf11392ccaea | 216 | |
lukas_formanek | 15:bf11392ccaea | 217 | /** Set the date registers |
lukas_formanek | 15:bf11392ccaea | 218 | * @param dayOfWeek : day of week |
lukas_formanek | 15:bf11392ccaea | 219 | * @param date |
lukas_formanek | 15:bf11392ccaea | 220 | * @param month |
lukas_formanek | 15:bf11392ccaea | 221 | * @param year |
lukas_formanek | 15:bf11392ccaea | 222 | */ |
lukas_formanek | 15:bf11392ccaea | 223 | void setDate(int dayOfWeek, int date, int month, int year); |
lukas_formanek | 15:bf11392ccaea | 224 | |
lukas_formanek | 15:bf11392ccaea | 225 | /** Read the date and time registers |
lukas_formanek | 15:bf11392ccaea | 226 | * @param dayOfWeek : day of week |
lukas_formanek | 15:bf11392ccaea | 227 | * @param date |
lukas_formanek | 15:bf11392ccaea | 228 | * @param month |
lukas_formanek | 15:bf11392ccaea | 229 | * @param year |
lukas_formanek | 15:bf11392ccaea | 230 | * @param hours |
lukas_formanek | 15:bf11392ccaea | 231 | * @param minutes |
lukas_formanek | 15:bf11392ccaea | 232 | * @param seconds |
lukas_formanek | 15:bf11392ccaea | 233 | */ |
lukas_formanek | 15:bf11392ccaea | 234 | void readDateTime(int *dayOfWeek, int *date, int *month, int *year, int *hours, int *minutes, int *seconds); |
lukas_formanek | 15:bf11392ccaea | 235 | |
lukas_formanek | 15:bf11392ccaea | 236 | /** Read a register |
lukas_formanek | 15:bf11392ccaea | 237 | * @param reg : register address |
lukas_formanek | 15:bf11392ccaea | 238 | * @return The register content |
lukas_formanek | 15:bf11392ccaea | 239 | */ |
lukas_formanek | 15:bf11392ccaea | 240 | int readRegister(char reg); |
lukas_formanek | 15:bf11392ccaea | 241 | |
lukas_formanek | 15:bf11392ccaea | 242 | /** Write to a register |
lukas_formanek | 15:bf11392ccaea | 243 | * @param reg : register address |
lukas_formanek | 15:bf11392ccaea | 244 | * @param The register content |
lukas_formanek | 15:bf11392ccaea | 245 | */ |
lukas_formanek | 15:bf11392ccaea | 246 | void writeRegister(int reg,char byte); |
lukas_formanek | 15:bf11392ccaea | 247 | |
lukas_formanek | 15:bf11392ccaea | 248 | /** set OSF (Oscillator Stop Flag) bit to 0 in Control Status register |
lukas_formanek | 15:bf11392ccaea | 249 | * should be done just after power up DS3231 |
lukas_formanek | 15:bf11392ccaea | 250 | * OSF bit is automaticaly set to 1 when on power up or when the DS3231 oscillator stops |
lukas_formanek | 15:bf11392ccaea | 251 | */ |
lukas_formanek | 15:bf11392ccaea | 252 | void eraseOSF(); |
lukas_formanek | 15:bf11392ccaea | 253 | |
lukas_formanek | 15:bf11392ccaea | 254 | /** Return OSF bit. If true the oscillator stopped or the DS3231 just powered up |
lukas_formanek | 15:bf11392ccaea | 255 | * @return The OSF bit |
lukas_formanek | 15:bf11392ccaea | 256 | */ |
lukas_formanek | 15:bf11392ccaea | 257 | bool OSF(); |
lukas_formanek | 15:bf11392ccaea | 258 | |
lukas_formanek | 15:bf11392ccaea | 259 | bool error; |
lukas_formanek | 15:bf11392ccaea | 260 | |
lukas_formanek | 16:610f7091e0ac | 261 | uint16_t set_cntl_stat_reg(ds3231_cntl_stat_t data); |
lukas_formanek | 16:610f7091e0ac | 262 | |
lukas_formanek | 15:bf11392ccaea | 263 | private : |
lukas_formanek | 16:610f7091e0ac | 264 | uint8_t w_adrs, r_adrs; |
lukas_formanek | 15:bf11392ccaea | 265 | I2C i2c; |
lukas_formanek | 15:bf11392ccaea | 266 | int bcd2dec(int k); // bcd to decimal conversion |
lukas_formanek | 15:bf11392ccaea | 267 | int dec2bcd(int k); // decimal to bcd conversion |
lukas_formanek | 15:bf11392ccaea | 268 | void decodeTime(int regHours, int regMinutes, int regSeconds,int *Hours, int *Minutes, int *Seconds); |
lukas_formanek | 15:bf11392ccaea | 269 | void decodeDate(int regDate,int regMonth, int regYear, int *date, int *month, int *year); |
lukas_formanek | 15:bf11392ccaea | 270 | }; |
lukas_formanek | 15:bf11392ccaea | 271 | |
lukas_formanek | 15:bf11392ccaea | 272 | |
lukas_formanek | 15:bf11392ccaea | 273 | #endif |