Code to interface with the MCP7940 Real time clock. Supports getting and setting the time in 24 hour format
Diff: MCP7940.cpp
- Revision:
- 1:8f330348d96b
diff -r 36c08b11e691 -r 8f330348d96b MCP7940.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP7940.cpp Tue Sep 29 07:56:30 2015 +0000 @@ -0,0 +1,165 @@ +#include "MCP7940.h" + + MCP7940::MCP7940(PinName sda, PinName scl):Clock(sda, scl){ + _addr = 0xDE; // 1101 111x + Clock.frequency(100000); + _YearStart = 2000; + } + MCP7940::MCP7940(PinName sda, PinName scl, int StartYear):Clock(sda, scl){ + _addr = 0xDE; // 1101 111x + Clock.frequency(100000); + _YearStart = StartYear; + } + + char MCP7940::IntToBCD(char Data){ + char Tens = Data / 10; + char Units = Data % 10; + char BCD = (Tens << 4 | Units); + return(BCD); + } + char MCP7940::BCDtoInt(char Data){ + char Value; + Value = (((Data & 0xF0 ) >> 4) * 10) + (((Data & 0x0F ))); + return(Value); + } + + int MCP7940::setTime(int Year, int Month, int Day, int Hour, int Mins){ + return(setTime(Year, Month, Day, Hour, Mins, 0, 0)); + } + int MCP7940::setTime(int Year, int Month, int Day, int Hour, int Mins, int Secs){ + return(setTime(Year, Month, Day, Hour, Mins, Secs, 0)); + } + int MCP7940::setTime(int Year, int Month, int Day, int Hour, int Mins, int Secs, int MiliSecs){ + return(setTime(Year, Month, Day, Hour, Mins, Secs, 0,1)); + } + int MCP7940::setTime(int Year, int Month, int Day, int Hour, int Mins, int Secs, int MiliSecs, int DayOfWeek){ + _Day = Day; + _Month = Month; + _Year = Year; + _Hour = Hour; + _Minutes = Mins; + _Seconds = Secs; + _MilliSeconds = MiliSecs; + _DayOfWeek = DayOfWeek; + return(setTime()); + } + void MCP7940::StartClock(){ + char cmd[8]; + cmd[0] = 0x00; // The start register + cmd[1] = 0x00; + + Clock.start(); + Clock.write(_addr,cmd,1) ; + Clock.read(_addr, cmd, 1); + + //Cmd 0 now contains the value of the seconds regsiter + cmd[1] = cmd[0] & 0x7F; //Move the seconds register value and clear the top bit + cmd[0] = 0x00; //Set write location + // Clock.write(_addr,cmd,2); + cmd[1] = cmd[1] | 0x80 ; //Now set the top bit + Clock.write(_addr,cmd,2); //Write to Reg 0x00 the value with top bit set + Clock.stop(); + + } + int MCP7940::setDefaultTime(){ + _Day = 1; + _Month = 10; + _Year = 2015; + _Hour = 1; + _Minutes = 0; + _Seconds = 0; + _MilliSeconds = 0; + _DayOfWeek = 1; + return(setTime()); + } + int MCP7940::setTime(){ + //Write time to the Device + char cmd[8]; + cmd[0] = 0x00; // The start register + cmd[1] = IntToBCD(_Seconds); + cmd[2] = IntToBCD(_Minutes); + cmd[3] = IntToBCD(_Hour); + cmd[4] = IntToBCD(_DayOfWeek) | 0x80; //NB this will clear the PWR Fail and set VBat Enable + cmd[5] = IntToBCD(_Day); + cmd[6] = IntToBCD(_Month); + cmd[7] = IntToBCD(_Year - _YearStart); + + Clock.start(); + Clock.write(_addr, cmd, 8); + Clock.stop(); + + return(1); + } + int MCP7940::getTime(){ + + char cmd[7]; + cmd[0] = 0x00; + + Clock.start(); + //Set the position to Reg 0x00 + Clock.write(_addr, cmd, 1); + //Read 7 bytes from 0x00 + Clock.read(_addr, cmd, 7); + Clock.stop(); + + //printf("%i %i %i %i %i %i %i\r\n", cmd[0], cmd[1],cmd[2],cmd[3],cmd[4], cmd[5], cmd[6]); + + //Convert into numbers - note have to mask out the configuration bits as well + _Day = BCDtoInt(cmd[4] & 0x3F); + _Month = BCDtoInt(cmd[5] & 0x1F); + _Year = BCDtoInt(cmd[6] & 0xFF) + _YearStart; + _Hour = BCDtoInt(cmd[2] & 0x3F); //Should handle 12 or 24 hour here. + _Minutes = BCDtoInt(cmd[1] & 0x7F); + _Seconds = BCDtoInt(cmd[0] & 0x7F); + _DayOfWeek = BCDtoInt(cmd[3] & 0x07); + _MilliSeconds = 0; + //printf("Day: %i Month: %i Year: %i Hour: %i Minute: %i Second: %i\r\n", _Day, _Month,_Year,_Hour,_Minutes, _Seconds); + return(0); + } + char * MCP7940::TimeStamp(){ + TimeStamp(_TimeStamp); + return(_TimeStamp); + } + void MCP7940::TimeStamp(char * buf){ + getTime(); + sprintf(buf,"%04i-%02i-%02iT%02i:%02i:%02i",_Year, _Month,_Day,_Hour,_Minutes,_Seconds); + } + void MCP7940::niceTimeStamp(char * buf){ + getTime(); + sprintf(buf,"%02i/%02i/%04i %02i:%02i:%02i",_Day, _Month,_Year,_Hour,_Minutes,_Seconds); + } + void MCP7940::niceDate(char * buf){ + getTime(); + sprintf(buf,"%02i-%02i-%04i",_Day, _Month,_Year); + } + void MCP7940::niceTime(char * buf){ + getTime(); + sprintf(buf,"%02i:%02i:%02i",_Hour,_Minutes,_Seconds); + } + + int MCP7940::Day(){ + return(_Day); + } + int MCP7940::Month(){ + return(_Month); + } + int MCP7940::Year(){ + return(_Year); + } + int MCP7940::Hour(){ + return(_Hour); + } + int MCP7940::Minutes(){ + return(_Minutes); + + } + int MCP7940::Seconds(){ + return(_Seconds); + } + int MCP7940::MilliSeconds(){ + return(_MilliSeconds); + } + int MCP7940::DayOfWeek(){ + return(_DayOfWeek); + } + \ No newline at end of file