Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
DS3231.cpp@0:084c63e7e80d, 2019-10-19 (annotated)
- Committer:
- hi1000
- Date:
- Sat Oct 19 02:09:39 2019 +0000
- Revision:
- 0:084c63e7e80d
The first version of ROT-CANBUS R01/00819
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| hi1000 | 0:084c63e7e80d | 1 | #include "DS3231.h" |
| hi1000 | 0:084c63e7e80d | 2 | |
| hi1000 | 0:084c63e7e80d | 3 | DS3231::DS3231(PinName sda, PinName scl) : i2c(sda, scl) |
| hi1000 | 0:084c63e7e80d | 4 | { |
| hi1000 | 0:084c63e7e80d | 5 | } |
| hi1000 | 0:084c63e7e80d | 6 | |
| hi1000 | 0:084c63e7e80d | 7 | |
| hi1000 | 0:084c63e7e80d | 8 | // BCD to decimal conversion |
| hi1000 | 0:084c63e7e80d | 9 | int DS3231::bcd2dec(int k) |
| hi1000 | 0:084c63e7e80d | 10 | {return(((k&0xF0)>>4)*10+(k&0x0F));} |
| hi1000 | 0:084c63e7e80d | 11 | |
| hi1000 | 0:084c63e7e80d | 12 | |
| hi1000 | 0:084c63e7e80d | 13 | // decimal to BCD conversion |
| hi1000 | 0:084c63e7e80d | 14 | int DS3231::dec2bcd(int k) |
| hi1000 | 0:084c63e7e80d | 15 | {return((k/10)*16+(k%10));} |
| hi1000 | 0:084c63e7e80d | 16 | |
| hi1000 | 0:084c63e7e80d | 17 | void DS3231::setI2Cfrequency(int frequency) |
| hi1000 | 0:084c63e7e80d | 18 | {i2c.frequency(frequency); |
| hi1000 | 0:084c63e7e80d | 19 | } |
| hi1000 | 0:084c63e7e80d | 20 | |
| hi1000 | 0:084c63e7e80d | 21 | // read temperature from DS3231 |
| hi1000 | 0:084c63e7e80d | 22 | float DS3231::readTemp() |
| hi1000 | 0:084c63e7e80d | 23 | {char buf[2]; |
| hi1000 | 0:084c63e7e80d | 24 | buf[0]=DS3231_MSB_Temp; |
| hi1000 | 0:084c63e7e80d | 25 | int w=i2c.write(DS3231_Address,buf,1); |
| hi1000 | 0:084c63e7e80d | 26 | int r=i2c.read(DS3231_Address,buf,2); |
| hi1000 | 0:084c63e7e80d | 27 | error=((w!=0)||(r!=0)); |
| hi1000 | 0:084c63e7e80d | 28 | return(buf[0]+buf[1]/256.0);} |
| hi1000 | 0:084c63e7e80d | 29 | |
| hi1000 | 0:084c63e7e80d | 30 | // force temperatue conversion |
| hi1000 | 0:084c63e7e80d | 31 | void DS3231::convertTemperature() |
| hi1000 | 0:084c63e7e80d | 32 | { |
| hi1000 | 0:084c63e7e80d | 33 | int Control=readRegister(DS3231_Control)|DS3231_bit_CONV; |
| hi1000 | 0:084c63e7e80d | 34 | writeRegister(DS3231_Control,Control); |
| hi1000 | 0:084c63e7e80d | 35 | } |
| hi1000 | 0:084c63e7e80d | 36 | |
| hi1000 | 0:084c63e7e80d | 37 | // decode time registers |
| hi1000 | 0:084c63e7e80d | 38 | void DS3231::decodeTime(int regHours, int regMinutes, int regSeconds,int *Hours, int *Minutes, int *Seconds) |
| hi1000 | 0:084c63e7e80d | 39 | { |
| hi1000 | 0:084c63e7e80d | 40 | *Hours=bcd2dec(regHours); |
| hi1000 | 0:084c63e7e80d | 41 | *Minutes=bcd2dec(regMinutes); |
| hi1000 | 0:084c63e7e80d | 42 | *Seconds=bcd2dec(regSeconds); |
| hi1000 | 0:084c63e7e80d | 43 | } |
| hi1000 | 0:084c63e7e80d | 44 | |
| hi1000 | 0:084c63e7e80d | 45 | |
| hi1000 | 0:084c63e7e80d | 46 | // read time registers dand decode them to decimal |
| hi1000 | 0:084c63e7e80d | 47 | void DS3231::readTime(int *hours, int *minutes, int *seconds) |
| hi1000 | 0:084c63e7e80d | 48 | { |
| hi1000 | 0:084c63e7e80d | 49 | char buf[3]; |
| hi1000 | 0:084c63e7e80d | 50 | buf[0]=DS3231_Seconds; |
| hi1000 | 0:084c63e7e80d | 51 | int w=i2c.write(DS3231_Address,buf,1); |
| hi1000 | 0:084c63e7e80d | 52 | int r=i2c.read(DS3231_Address,buf,3); |
| hi1000 | 0:084c63e7e80d | 53 | decodeTime(buf[2],buf[1],buf[0],hours,minutes,seconds); |
| hi1000 | 0:084c63e7e80d | 54 | error=((w!=0)||(r!=0)); |
| hi1000 | 0:084c63e7e80d | 55 | } |
| hi1000 | 0:084c63e7e80d | 56 | |
| hi1000 | 0:084c63e7e80d | 57 | // set time register |
| hi1000 | 0:084c63e7e80d | 58 | void DS3231::setTime(int hours, int minutes, int seconds) |
| hi1000 | 0:084c63e7e80d | 59 | { |
| hi1000 | 0:084c63e7e80d | 60 | writeRegister(DS3231_Seconds,dec2bcd(seconds)); |
| hi1000 | 0:084c63e7e80d | 61 | writeRegister(DS3231_Minutes,dec2bcd(minutes)); |
| hi1000 | 0:084c63e7e80d | 62 | writeRegister(DS3231_Hours,dec2bcd(hours)); |
| hi1000 | 0:084c63e7e80d | 63 | } |
| hi1000 | 0:084c63e7e80d | 64 | |
| hi1000 | 0:084c63e7e80d | 65 | // decode date registers |
| hi1000 | 0:084c63e7e80d | 66 | void DS3231::decodeDate(int regDate,int regMonth, int regYear, int *date, int *month, int *year) |
| hi1000 | 0:084c63e7e80d | 67 | { |
| hi1000 | 0:084c63e7e80d | 68 | *date=bcd2dec(regDate); |
| hi1000 | 0:084c63e7e80d | 69 | int century=regMonth&128; |
| hi1000 | 0:084c63e7e80d | 70 | *month=bcd2dec(regMonth&127); |
| hi1000 | 0:084c63e7e80d | 71 | *year=bcd2dec(regYear); |
| hi1000 | 0:084c63e7e80d | 72 | if (century==0) // only XXth and XXIst centuries allowed |
| hi1000 | 0:084c63e7e80d | 73 | {*year=*year+1900;} |
| hi1000 | 0:084c63e7e80d | 74 | else |
| hi1000 | 0:084c63e7e80d | 75 | {*year=*year+2000;} |
| hi1000 | 0:084c63e7e80d | 76 | } |
| hi1000 | 0:084c63e7e80d | 77 | |
| hi1000 | 0:084c63e7e80d | 78 | // read date registers |
| hi1000 | 0:084c63e7e80d | 79 | void DS3231::readDate(int *date, int *month, int *year) |
| hi1000 | 0:084c63e7e80d | 80 | { |
| hi1000 | 0:084c63e7e80d | 81 | char buf[3]; |
| hi1000 | 0:084c63e7e80d | 82 | buf[0]=DS3231_Date; |
| hi1000 | 0:084c63e7e80d | 83 | int w=i2c.write(DS3231_Address,buf,1); |
| hi1000 | 0:084c63e7e80d | 84 | int r=i2c.read(DS3231_Address,buf,3); |
| hi1000 | 0:084c63e7e80d | 85 | decodeDate(buf[0],buf[1],buf[2],date,month,year); |
| hi1000 | 0:084c63e7e80d | 86 | error=((w!=0)||(r!=0)); |
| hi1000 | 0:084c63e7e80d | 87 | } |
| hi1000 | 0:084c63e7e80d | 88 | |
| hi1000 | 0:084c63e7e80d | 89 | // set the date registers |
| hi1000 | 0:084c63e7e80d | 90 | void DS3231::setDate(int dayOfWeek, int date, int month, int year) |
| hi1000 | 0:084c63e7e80d | 91 | { |
| hi1000 | 0:084c63e7e80d | 92 | writeRegister(DS3231_Date,dec2bcd(date)); |
| hi1000 | 0:084c63e7e80d | 93 | writeRegister(DS3231_Day,dayOfWeek); |
| hi1000 | 0:084c63e7e80d | 94 | int century=0; // only XXth and XXIst centuries allowed |
| hi1000 | 0:084c63e7e80d | 95 | if (year<1900){year=1900;} |
| hi1000 | 0:084c63e7e80d | 96 | if (year>2099){year=2099;} |
| hi1000 | 0:084c63e7e80d | 97 | if (year<2000) |
| hi1000 | 0:084c63e7e80d | 98 | {year=year-1900;} |
| hi1000 | 0:084c63e7e80d | 99 | else |
| hi1000 | 0:084c63e7e80d | 100 | {year=year-2000;century=1;} |
| hi1000 | 0:084c63e7e80d | 101 | writeRegister(DS3231_Month_Century,dec2bcd(month)+128*century); |
| hi1000 | 0:084c63e7e80d | 102 | writeRegister(DS3231_Year,dec2bcd(year)); |
| hi1000 | 0:084c63e7e80d | 103 | } |
| hi1000 | 0:084c63e7e80d | 104 | |
| hi1000 | 0:084c63e7e80d | 105 | // read date and time registers |
| hi1000 | 0:084c63e7e80d | 106 | void DS3231::readDateTime(int *dayOfWeek, int *date, int *month, int *year, int *hours, int *minutes, int *seconds) |
| hi1000 | 0:084c63e7e80d | 107 | { |
| hi1000 | 0:084c63e7e80d | 108 | char buf[7]; |
| hi1000 | 0:084c63e7e80d | 109 | buf[0]=DS3231_Seconds; |
| hi1000 | 0:084c63e7e80d | 110 | int w=i2c.write(DS3231_Address,buf,1); |
| hi1000 | 0:084c63e7e80d | 111 | int r=i2c.read(DS3231_Address,buf,7); |
| hi1000 | 0:084c63e7e80d | 112 | decodeTime(buf[2],buf[1],buf[0],hours,minutes,seconds); |
| hi1000 | 0:084c63e7e80d | 113 | *dayOfWeek=buf[3]; |
| hi1000 | 0:084c63e7e80d | 114 | decodeDate(buf[4],buf[5],buf[6],date,month,year); |
| hi1000 | 0:084c63e7e80d | 115 | error=((w!=0)||(r!=0)); |
| hi1000 | 0:084c63e7e80d | 116 | } |
| hi1000 | 0:084c63e7e80d | 117 | |
| hi1000 | 0:084c63e7e80d | 118 | // read a register |
| hi1000 | 0:084c63e7e80d | 119 | int DS3231::readRegister(char reg) |
| hi1000 | 0:084c63e7e80d | 120 | { |
| hi1000 | 0:084c63e7e80d | 121 | char buf[1]; |
| hi1000 | 0:084c63e7e80d | 122 | buf[0]=reg; |
| hi1000 | 0:084c63e7e80d | 123 | int w=i2c.write(DS3231_Address,buf,1); |
| hi1000 | 0:084c63e7e80d | 124 | int r=i2c.read(DS3231_Address,buf,1); |
| hi1000 | 0:084c63e7e80d | 125 | error=((w!=0)||(r!=0)); |
| hi1000 | 0:084c63e7e80d | 126 | return(buf[0]); |
| hi1000 | 0:084c63e7e80d | 127 | } |
| hi1000 | 0:084c63e7e80d | 128 | |
| hi1000 | 0:084c63e7e80d | 129 | // write a register |
| hi1000 | 0:084c63e7e80d | 130 | void DS3231::writeRegister(int reg,char byte) |
| hi1000 | 0:084c63e7e80d | 131 | { |
| hi1000 | 0:084c63e7e80d | 132 | char buf[2]; |
| hi1000 | 0:084c63e7e80d | 133 | buf[0]=reg; |
| hi1000 | 0:084c63e7e80d | 134 | buf[1]=byte; |
| hi1000 | 0:084c63e7e80d | 135 | int w=i2c.write(DS3231_Address,buf,2); |
| hi1000 | 0:084c63e7e80d | 136 | error=(w!=0); |
| hi1000 | 0:084c63e7e80d | 137 | } |
| hi1000 | 0:084c63e7e80d | 138 | |
| hi1000 | 0:084c63e7e80d | 139 | void DS3231::eraseOSF() |
| hi1000 | 0:084c63e7e80d | 140 | { |
| hi1000 | 0:084c63e7e80d | 141 | int reg=readRegister(DS3231_Control_Status); |
| hi1000 | 0:084c63e7e80d | 142 | reg=reg&0x7F; |
| hi1000 | 0:084c63e7e80d | 143 | writeRegister(DS3231_Control_Status,reg); |
| hi1000 | 0:084c63e7e80d | 144 | } |
| hi1000 | 0:084c63e7e80d | 145 | |
| hi1000 | 0:084c63e7e80d | 146 | bool DS3231::OSF() |
| hi1000 | 0:084c63e7e80d | 147 | { |
| hi1000 | 0:084c63e7e80d | 148 | int reg=readRegister(DS3231_Control_Status); |
| hi1000 | 0:084c63e7e80d | 149 | return(reg&DS3231_bit_OSF); |
| hi1000 | 0:084c63e7e80d | 150 | } |