Matthias Hemmer
/
PCF8563_RealTimeClock_MatthiasHemmer
Bertl2014 Bulme
Revision 0:84a4a0aa3ea6, committed 2017-05-06
- Comitter:
- hemmer_matthias
- Date:
- Sat May 06 20:12:01 2017 +0000
- Commit message:
- Bertl2014
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/I2C/myi2c.cpp Sat May 06 20:12:01 2017 +0000 @@ -0,0 +1,54 @@ +#include "myi2c.h" + +PCF8563::PCF8563(PinName sda, PinName scl) : i2c (sda, scl) +{ + i2c.frequency(PCF8563_FREQ); //set the frequency +} +/* + * read function from the TRC + * read a value and return it + */ +uint8_t PCF8563::read(int i2c_r, int address) +{ + uint8_t value; //temp 8bit + i2c.start(); //start + i2c.write(i2c_r); //write address + i2c.write(address); + i2c.start(); //restart + i2c.write(address); //read address + value = i2c.read(0); + i2c.stop(); + + return value; //returns var value of the method +} +uint8_t PCF8563::read(int i2c_w, int i2c_r, int address) +{ + uint8_t value; //temp 8bit + i2c.start(); //start + i2c.write(i2c_w); //write address + i2c.write(address); + i2c.start(); //restart + i2c.write(i2c_r); //read address + value = i2c.read(0); + i2c.stop(); + return value; +} +/* firtly you write the address from the rtc + * secondly the register address + * last but not leat your value + */ +void PCF8563::write(int i2c_w, int address, int value) +{ + i2c.start(); //start + i2c.write(i2c_w); //i2c write address + i2c.write(address); + i2c.write(value); + i2c.stop(); //stop +} +/* + * Binary Coded Decimal converter into decimal + */ +uint8_t PCF8563::bcdToDec(uint8_t val) +{ + return (10*((val>>4)& 0x0F)+(val & 0x0F)); //convert from bcd to dec +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/I2C/myi2c.h Sat May 06 20:12:01 2017 +0000 @@ -0,0 +1,40 @@ +#ifndef MBED_PCF8563_H +#define MBED_PCF8563_H + +#include "mbed.h" + +#define PCF8563_FREQ 400000 // bus speed 400 kHz + +class PCF8563 +{ +public: + //define the i2c pins + PCF8563(PinName sda, PinName scl); + /**read from an I2C address + *@para: the read address of the I2C device + *@param: for only one i2c address of the device + */ + uint8_t read(int i2c_r,int address); //read class + /**read from an I2C address + * for two different parameters + *@param: the write address of the I2C device + *@param: the read address of the I2C device + *@param: the register where you will read from + */ + uint8_t read(int i2c_w, int i2c_r, int address); //read class + /**wirte from an I2C address + *@param: the write address of the I2C device + *@param: a register address of the I2C device + *@param: set a value to this address of th I2C device + */ + void write(int i2c_w, int address, int value); //write class + /**convert from Binary Coded Decimal to Decimal + *@param: set a value which must be converted + *returns a Decimal value + */ + uint8_t bcdToDec(uint8_t val); //convertation from bcd to dec + +private: + I2C i2c; //unsing the i2c library +}; +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF8563/PCF8563_addr.h Sat May 06 20:12:01 2017 +0000 @@ -0,0 +1,22 @@ +// i2c addresses +const uint8_t PCF8563_ADR_WR = 0xA2; +const uint8_t PCF8563_ADR_RD = 0xA3; +// control and status +const uint8_t CONTROL1 = 0x00; +const uint8_t CONTROL2 = 0x01; +// time and date +const uint8_t SECONDS = 0x02; +const uint8_t MINUTES = 0x03; +const uint8_t HOURS = 0x04; +const uint8_t DAYS = 0x05; +const uint8_t WEEKDAYS = 0x06; +const uint8_t MONTHS = 0x07; +const uint8_t YEARS = 0x08; +// alarm +const uint8_t MINUTE_ALARM = 0x09; +const uint8_t HOUR_ALARM = 0x0A; +const uint8_t DAY_ALARM = 0x0B; +const uint8_t WEEKDAY_ALARM = 0x0C; +// clock and timer +const uint8_t CLOCKOUT_FREQ = 0x0D; +const uint8_t TIMER_CINTROL = 0x0E; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat May 06 20:12:01 2017 +0000 @@ -0,0 +1,207 @@ +/* RTC8563 Real Time Clock + * creator: Matthias Hemmer + * date: 16.01.2017 + * handover date: 30.01.2017 + * + * |-------------------------| + * |!!the RTC must be reseted| + * |-------------------------| + * + */ +//include mbed library +#include "mbed.h" +//include i2c class +#include "myi2c.h" +//include string library from C++ string library +#include <string> +//include the addresses for the PCF8563 +#include "PCF8563_addr.h" +using namespace std; + +PCF8563 pcf8563(p28, p27); //SDA,SCL +Serial pc(USBTX,USBRX); //RS232 connection + +void send(); //read parameters and write it via serial to pc +void send_hh_mm_ss(); //send only the time in format: hh:mm:ss +void send_date(); //send only the date in format: dd:month:yyyy +void set_date(int year, int month, int day, int hour, int minute, int second); //set day class +void toggle(); //toogle the bool between ture and false +string ConvertToDate(uint8_t value); //convert from hex to string + +//global parameters +bool check = false; //toogle variable +uint8_t second, minute, hour, day, week, month, year; // uint8_t is a 8 bit integer +string century_month(" "); //initialzied +char c; //char from the pc keyboard entry + +//interrupt for the serial port +void callback() +{ + c = pc.getc(); //save the Character which was send from the pc + + switch(c) { + case 'C': + toggle(); + break; + case 'c': + toggle(); + break; + case 't': + send_hh_mm_ss(); + break; + case 'T': + send_hh_mm_ss(); + break; + case 'd': + send_date(); + break; + case 'D': + send_date(); + break; + } +} +/* + * the programm have to set the date and read it in a second clock about the serial port to the pc + * if "C" or "c" are pressed the date will send to the pc and if it will be presss a second time it will stop + * before you can send another option you HAVE TO stop with a 'C' or 'c' + * if "T" or "t" are pressed than it send the current time from the rtc to the pc in format: hh:mm:ss + * if "D" od "d" are pressed than it send the date from the rtc to the pc in format: dd.month.yyyy + */ +int main() +{ + pc.attach(&callback); //if any key will be pressed on the keyboard from the pc it will call an interrupt + + pc.baud(9600); //set the rate of the serial port to 9600; default: 9600 + + //set at first the date + set_date(0x99, 0x01, 0x02, 0x04, 0x05, 0x00); + + //shows up the menu + pc.printf( "C/c: Gibt das Datum in sekunden dakt aus.\n\r" + "T/t: Gibt die aktuelle Zeit der Echtzeituhr aus.\n\r" + "D/d: Gibt das aktuelle Datum der Echtzeituhr aus.\n\r"); + + while(1) { + switch(c) { + case 'C': + send(); + break; + case 'c': + send(); + break; + } + } +}//end main +/* + * set function, the first address is the register, the second is the argument + * example: set(register, 0x01); set the reigster to one + * + * 1. set the STOP bit 1 (look shema datasheet) at the reigster CONTROL1 + * 2. set the time + * 3. set the STOP bit 0 (look shema datasheet) at the register CONTROL1 + */ +void set_date(int year, int month, int day, int hour, int minute, int second) +{ + uint8_t week_val = 0x05; //SAT + //set the STOP bit + pcf8563.write(PCF8563_ADR_WR, CONTROL1, 0x20); //set CONTROL1 STOP bit = 1 0b00100000 + pcf8563.write(PCF8563_ADR_WR, CONTROL2, 0x00); //set CONTROL2 0b00000000 + //set date + pcf8563.write(PCF8563_ADR_WR, YEARS, year); + pcf8563.write(PCF8563_ADR_WR, MONTHS, month); + pcf8563.write(PCF8563_ADR_WR, WEEKDAYS, week_val); + pcf8563.write(PCF8563_ADR_WR, DAYS, day); + pcf8563.write(PCF8563_ADR_WR, HOURS, hour); + pcf8563.write(PCF8563_ADR_WR, MINUTES, minute); + pcf8563.write(PCF8563_ADR_WR, SECONDS, second); + //releas the STOP bit + //CLOCKOUT_FREQ must set to 0, see shema datasheet + pcf8563.write(PCF8563_ADR_WR, CLOCKOUT_FREQ, 0x00); //0x83 = TE on & 1Hz + pcf8563.write(PCF8563_ADR_WR, TIMER_CINTROL, 0x00); // see datasheet + pcf8563.write(PCF8563_ADR_WR, CONTROL1, 0x00); //set CONTROL1 STOP bit = 0 0b00000000 +}// end set + +//invert the bool check +void toggle() +{ + check = !check; +}//end toggle +void send() +{ + while(check == true) { + //read all parameters and connect the read value with a '&' with a register entry to 1: 0b11111111 + second = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, SECONDS) &0x7F; + minute = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, MINUTES) &0x7F; + hour = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, HOURS) &0x3F; + day = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, DAYS) & 0x3F; + week = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, WEEKDAYS) &0x07; //must not be used + month = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, MONTHS) &0x1F; + year = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, YEARS) &0xFF; + + century_month = ConvertToDate(month); //convert from hex into a string + + /*serial export to pc + *%d02 shows: 00 + *19%02 must be writen, becouse the register of the year goes only until 99 + */ + pc.printf("%d.%s.19%d\n\r%02d:%02d:%02d\n\r", pcf8563.bcdToDec(day), century_month, pcf8563.bcdToDec(year), pcf8563.bcdToDec(hour), pcf8563.bcdToDec(minute), pcf8563.bcdToDec(second)); //ignore warning, becouse it cames from the string library //Warning message: Warning: Non-POD class type passed through ellipsis in "main.cpp" dont' care + + wait(1); //to send only one value + } +}//end send +void send_hh_mm_ss() +{ + //read second, minute and hour from the rtc + second = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, SECONDS) &0x7F; + minute = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, MINUTES) &0x7F; + hour = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, HOURS) &0x3F; + + pc.printf("Aktuelle Zeit: %02d:%02d:%02d\n\r", pcf8563.bcdToDec(hour), pcf8563.bcdToDec(minute), pcf8563.bcdToDec(second)); + wait(1); //to send only one value +}//end send_hh_mm_ss +void send_date() +{ + day = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, DAYS) & 0x3F; + month = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, MONTHS) &0x1F; + year = pcf8563.read(PCF8563_ADR_WR, PCF8563_ADR_RD, YEARS) &0xFF; + + century_month = ConvertToDate(month); //convert from hex into a string + + pc.printf("Ich wurde geboren am %02d.%s.19%d.\n\r", pcf8563.bcdToDec(day), century_month, pcf8563.bcdToDec(year)); //ignore warning, becouse it cames from the string library + wait(1); //to send only one value +}//end send_date +/* + * have to be coded from the user + * month are coded in hex + * return the month in a string (string library used) + */ +string ConvertToDate(uint8_t value) +{ + string month(" "); // initialized + if(value == 0x01) //compare value with a hex coded number until 0x12 is reached (see datashet) + month = "January"; //set the montch + if(value == 0x02) + month = "February"; + if(value == 0x03) + month = "March"; + if(value == 0x04) + month = "April"; + if(value == 0x05) + month = "May"; + if(value == 0x06) + month = "June"; + if(value == 0x07) + month = "July"; + if(value == 0x08) + month = "August"; + if(value == 0x09) + month = "September"; + if(value == 0x10) + month = "October"; + if(value == 0x11) + month ="November"; + if(value == 0x12) + month = "December"; + + return month; +}//end ConvertToDate \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat May 06 20:12:01 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/99b5ccf27215 \ No newline at end of file