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.
Dependents: Proyect_Patric_electronic_door_MSC_Ok_ESP
ds1307.cpp
00001 #include "ds1307.h" 00002 00003 DS1307::DS1307(PinName sda, PinName scl ) : ds1307i2c(sda,scl) 00004 { 00005 ds1307i2c.frequency(DS1307_freq); 00006 } 00007 00008 DS1307::~DS1307() 00009 { 00010 } 00011 00012 int DS1307::read( int addr, int quantity, char *data) 00013 { 00014 // note the char array at data must contain 63 locations or unpredictable behavior will happen 00015 // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access 00016 // quantity must be 1 - 63 as the 64th ram location is clobered in this method of access 00017 int test = 0 ; 00018 char temp_data[65]; 00019 00020 if (addr > DS1307_lastram) return (1); // fail because address greater then what chip has to read from 00021 if (addr < 0 ) return (1); // fail because address less then 0 is not available 00022 if (quantity > DS1307_lastreg) return (1); // fail because quantity greater then what can be read 00023 if ((addr + quantity) > DS1307_lastreg ) return (1); // fail because cant read past reg 63 00024 if ( quantity == 0 ) return (1); // fail because zero quantity wanted 00025 temp_data[0] = DS1307_lastreg ; // note this ram location is used to set the addressing pointer in DS1307 00026 temp_data[1] = 0; // just junk to clober this address with 00027 test = ds1307i2c.write(DS1307_addr,temp_data,2); 00028 if (test == 1) return (1); // the write operation failed 00029 //ds1307i2c.stop(); // now the DS1307 is pointing to the first register 00030 if ( addr != 0 ) test = ds1307i2c.read(DS1307_addr,temp_data,addr); // now the DS1307 address pointer is pointing to correct address 00031 if (test == 1) return (1); // the read operation failed 00032 test = ds1307i2c.read(DS1307_addr,data,quantity); // read the DS1307 registers now 00033 if (test == 1) return (1); // read operation failed 00034 return(0); // looks like the data read was good 00035 } 00036 00037 void DS1307::stop() 00038 { 00039 00040 } 00041 00042 int DS1307::read(int addr, int *data) 00043 { 00044 // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access 00045 int test = 0; 00046 char temp_data[65]; 00047 test = DS1307::read(addr, 1, &temp_data[0]); 00048 if (test == 1) return(1); // fail because read to DS1307 failed 00049 *data = (int)temp_data[0]; // returing the read data by pointer 00050 return (0); // the single read is successfull 00051 } 00052 00053 int DS1307::write( int addr, int quantity, char *data) 00054 { 00055 // note the char array at data must contain 63 locations or unpredictable behavior will happen 00056 // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access 00057 // quantity must be 1 - 63 as the 64th ram location is clobered in this method of access 00058 int test = 0 ; 00059 char temp_data[65] ; 00060 int loop = 0; 00061 00062 if (addr > DS1307_lastram) return (1); // fail because address greater then what chip has to read from 00063 if (addr < 0 ) return (1); // fail because address less then 0 is not available 00064 if (quantity > DS1307_lastreg) return (1); // fail because quantity greater then what can be read 00065 if (quantity == 0) return (1); // fail because zero quantity is wanted 00066 if ((addr + quantity) > DS1307_lastreg ) return (1); // fail because cant read past reg 63 00067 00068 temp_data[0] = (char)addr; 00069 for ( ; loop < quantity ; loop++ ) { 00070 temp_data[loop+1] = *(data + loop); 00071 } 00072 test = ds1307i2c.write(DS1307_addr, temp_data, (quantity + 1)); 00073 //ds1307i2c.stop(); 00074 return(test); // 0 for success 1 for failure to write 00075 } 00076 00077 int DS1307::write( int addr, int data ) 00078 { 00079 // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access 00080 int test = 0 ; 00081 char temp_data[2] ; 00082 00083 temp_data[0] = (char)addr; 00084 temp_data[1] = (char)data; 00085 if (addr > DS1307_lastram) return (1); // fail because address greater then what chip has to read from 00086 if (addr < 0 ) return (1); // fail because address less then 0 is not available 00087 test = ds1307i2c.write(DS1307_addr, temp_data, 2); 00088 //ds1307i2c.stop(); 00089 return(test); 00090 } 00091 00092 int DS1307::start_clock(void) // start the clock 00093 { 00094 int test = 0; 00095 int junk = 0; 00096 00097 test = DS1307::read(DS1307_sec, &junk); 00098 if (test == 1) return(1); // fail because read to DS1307 failed 00099 junk = ( 0x7F & junk); // basicaly i mask bit 8 to set it to zero 00100 test = DS1307::write(DS1307_sec,junk); // now write the seconds back to register and because bit 8 is zero this starts clock. 00101 if (test == 1) return(1); // fail because read to DS1307 failed 00102 return(test); // 00103 } 00104 00105 int DS1307::stop_clock(void) // stop clock 00106 { 00107 int test = 0; 00108 int junk = 0; 00109 00110 test = DS1307::read(DS1307_sec, &junk); 00111 if (test == 1) return(1); // fail because read to DS1307 failed 00112 junk = ( 0x7F & junk); // basicaly i mask bit 8 to set it to zero but keep all other bits 00113 junk = ( 0x80 | junk); // basicaly i mask bit 8 to set it to one 00114 test = DS1307::write(DS1307_sec,junk); // now write the seconds back to register and because bit 8 is one this starts clock. 00115 if (test == 1) return(1); // fail because read to DS1307 failed 00116 return(test); // 00117 } 00118 00119 int DS1307::twelve_hour(void) // set 12 hour mode 00120 { 00121 int test = 0; 00122 int junk = 0; 00123 00124 test = DS1307::read(DS1307_hour, &junk); 00125 if (test == 1) return(1); // fail because read to DS1307 failed 00126 if ((junk & 0x40) == 0x40) return(0); // return because 12 mode is active now all done! 00127 00128 junk = ( junk & 0x3F); // only use 24 hour time values 00129 if (junk == 0x00) 00130 junk = 0x12; 00131 else if (junk >= 0x13) 00132 if (junk < 0x20) { 00133 junk = junk - 0x12; 00134 junk = (junk | 0x20); // add back the pm indicator 00135 } else 00136 switch (junk) { 00137 case 0x20: 00138 junk = 0x28; 00139 break; 00140 case 0x21: 00141 junk = 0x29; 00142 break; 00143 case 0x22: 00144 junk = 0x30; 00145 break; 00146 case 0x23: 00147 junk = 0x31; 00148 break; 00149 } 00150 00151 test = DS1307::write(DS1307_hour,(0x40 | junk)); // set bit 6 with the new 12 hour time converted from the 24 hour time 00152 if (test == 1) return(1); // fail because read to DS1307 failed 00153 00154 return(0); 00155 } 00156 00157 int DS1307::twentyfour_hour(void) // set 24 hour mode 00158 { 00159 int test = 0; 00160 int junk = 0; 00161 00162 test = DS1307::read(DS1307_hour, &junk); 00163 if (test == 1) return(1); // fail because read to DS1307 failed 00164 if ((junk & 0x40) == 0) return(0); // return because 24 mode is active now all done! 00165 00166 junk = (junk & 0xBF); // get value bits and am/pm indicator bit but drop 12/24 hour bit 00167 00168 if (junk > 0x12) 00169 if ( junk <= 0x27 ) 00170 junk = junk - 0x0E; 00171 else 00172 junk = junk - 0x08; 00173 00174 test = DS1307::write(DS1307_hour,( 0xBF & junk)); // clear bit 6 and set the new 24 hour time converted from 12 hour time 00175 if (test == 1) return(1); // fail because read to DS1307 failed 00176 00177 return(0); 00178 } 00179 00180 int DS1307::settime(int sec, int min, int hour, int day, int date, int month, int year) // to set the current time and start clock 00181 { 00182 // sec = 0 to 59, min = 0 to 59, hours = 0 to 23 ( 24 hour mode only ), day = 1 to 7 ( day of week ), date = 1 to 31, month = 1 to 12, year 0 to 99 ( this is for 2000 to 2099) 00183 DS1307::stop_clock(); 00184 00185 if (1 == DS1307::hilow_check( 59, 0, sec)) { 00186 return(1); // failed because recieved value is not in bounds 00187 } else { 00188 if (1 == (DS1307::write(DS1307_sec,DS1307::dectobcd(sec)))) return(1); // failed to write for some reason 00189 } 00190 00191 if (1 == DS1307::hilow_check( 59, 0, min)) { 00192 return(1); // failed because recieved value is not in bounds 00193 } else { 00194 if (1 == (DS1307::write(DS1307_min,DS1307::dectobcd(min)))) return(1); // failed to write for some reason 00195 } 00196 00197 if (1 == DS1307::twentyfour_hour()) return(1); // failed to set 24 hour format 00198 if (1 == DS1307::hilow_check( 23, 0, hour)) { // note setting 24 hour mode befor and after writing the hour value ensures 24 hour mode is set 00199 return(1); // failed because recieved value is not in bounds 00200 } else { 00201 if (1 == (DS1307::write(DS1307_hour,DS1307::dectobcd(hour)))) return(1); // failed to write for some reason 00202 } 00203 if (1 == DS1307::twentyfour_hour()) return(1); // failed to set 24 hour format 00204 00205 if (1 == DS1307::hilow_check( 7, 1, day)) { 00206 return(1); // failed because recieved value is not in bounds 00207 } else { 00208 if (1 == (DS1307::write(DS1307_day,DS1307::dectobcd(day)))) return(1); // failed to write for some reason 00209 } 00210 00211 if (1 == DS1307::hilow_check( 31, 1, date)) { 00212 return(1); // failed because recieved value is not in bounds 00213 } else { 00214 if (1 == (DS1307::write(DS1307_date,DS1307::dectobcd(date)))) return(1); // failed to write for some reason 00215 } 00216 00217 if (1 == DS1307::hilow_check( 12, 1, month)) { 00218 return(1); // failed because recieved value is not in bounds 00219 } else { 00220 if (1 == (DS1307::write(DS1307_month,DS1307::dectobcd(month)))) return(1); // failed to write for some reason 00221 } 00222 00223 if (1 == DS1307::hilow_check( 99, 0, year)) { 00224 return(1); // failed because recieved value is not in bounds 00225 } else { 00226 if (1 == (DS1307::write(DS1307_year,DS1307::dectobcd(year)))) return(1); // failed to write for some reason 00227 } 00228 00229 DS1307::start_clock(); 00230 return (0); // time is now set 00231 } 00232 00233 int DS1307::gettime(int *sec, int *min, int *hour, int *day, int *date, int *month, int *year) // to get the current time information 00234 { 00235 // sec = 0 to 59, min = 0 to 59, hours = 0 to 23 ( 24 hour mode only ), day = 1 to 7 ( day of week ), date = 1 to 31, month = 1 to 12, year 0 to 99 ( this is for 2000 to 2099) 00236 if (1 == DS1307::read(DS1307_sec,sec)) return(1); // failed to read for some reason 00237 *sec = (*sec & 0x7F ); // drop the clock start stop bit 00238 *sec = DS1307::bcdtodec( *sec); // bcd is now dec value 00239 00240 if (1 == DS1307::read(DS1307_min,min)) return(1); // failed to read for some reason 00241 *min = (*min & 0x7F ); // drop bit 7 because it should be 0 anyways 00242 *min = DS1307::bcdtodec( *min); // bcd is now dec value 00243 00244 if (1 == DS1307::read(DS1307_hour,hour)) return(1); // failed to read for some reason 00245 if ((*hour & 0x40) == 0x40) { // if true then 12 hour mode is set currently so change to 24 hour, read value, and return to 12 hour mode 00246 if (1 == DS1307::twentyfour_hour()) return(1); // failed to set 24 hour mode for some reason 00247 if (1 == DS1307::read(DS1307_hour,hour)) return(1); // failed to read for some reason 00248 *hour = (*hour & 0x3F ); // drop bit 7 & 6 they are not used for 24 hour mode reading 00249 *hour = DS1307::bcdtodec( *hour); // bcd is now dec value 00250 if (1 == DS1307::twelve_hour()) return(1); // failed to return to 12 hour mode for some reason 00251 } else { // in 24 hour mode already so just read the hour value 00252 if (1 == DS1307::read(DS1307_hour,hour)) return(1); // failed to read for some reason 00253 *hour = (*hour & 0x3F ); // drop bit 7 & 6 they are not used for 24 hour mode reading 00254 *hour = DS1307::bcdtodec( *hour); // bcd is now dec value 00255 } 00256 00257 if (1 == DS1307::read(DS1307_day,day)) return(1); // failed to read for some reason 00258 *day = (*day & 0x07 ); // drop the non used bits 00259 *day = DS1307::bcdtodec( *day); // bcd is now dec value 00260 00261 if (1 == DS1307::read(DS1307_date,date)) return(1); // failed to read for some reason 00262 *date = (*date & 0x3F ); // drop bit 6 and 7 not used for date value 00263 *date = DS1307::bcdtodec( *date); // bcd is now dec value 00264 00265 if (1 == DS1307::read(DS1307_month,month)) return(1); // failed to read for some reason 00266 *month = (*month & 0x1F ); // drop bit 5, 6 and 7 not used for month value 00267 *month = DS1307::bcdtodec( *month); // bcd is now dec value 00268 00269 if (1 == DS1307::read(DS1307_year,year)) return(1); // failed to read for some reason 00270 *year = DS1307::bcdtodec( *year); // bcd is now dec value 00271 00272 return (0); // data returned is valid 00273 } 00274 00275 00276 int DS1307::dectobcd( int dec) 00277 { 00278 int low = 0; 00279 int high = 0; 00280 00281 high = dec / 10; // this gives the high nibble value 00282 low = dec - (high * 10); // this gives the lower nibble value 00283 return ((high *16) + low); // this is the final bcd value but in interger format 00284 } 00285 00286 int DS1307::bcdtodec( int bcd) 00287 { 00288 int low = 0; 00289 int high = 0; 00290 00291 high = bcd / 16; 00292 low = bcd - (high * 16); 00293 return ((high * 10) + low); 00294 00295 } 00296 00297 int DS1307::hilow_check( int hi, int low, int value) 00298 { 00299 if ((value >= low)&(value <= hi)) 00300 return(0); // value is equal to or inbetween hi and low 00301 else 00302 return(1); // value is not equal to or inbetween hi and low 00303 }
Generated on Fri Jul 15 2022 11:55:58 by
