#ifndef _RTC_DS3231_H #define _RTC_DS3231_H #define TWI TWIF //_____________________________________________________________________________ #define CPU_SPEED 32000000 #define BAUDRATE_rtc 400000 #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5) #define TWI_BAUDSETTING_rtc TWI_BAUD(CPU_SPEED, BAUDRATE_rtc) //_____ D E F I N I T I O N S __________________________________________________ char rtc_init(void); char rtc_get_temp(void); char rtc_get_clock(void); char rtc_set_clock(char h,char m); unsigned char hex2bcd (unsigned char x); char rtc_set_dat(char y,char mon,char dat,char day); int bcd2bin(int x); //______________________________________________________________________________ U8 rtc_seconds; U8 rtc_minutes; U8 rtc_hours; U8 rtc_days; U8 rtc_dat; U8 rtc_mon; U8 rtc_year; U8 th,tl; char rtc_temp; //______________________________________________________________________________ char rtc_init(void) { int err=0; TWI.MASTER.CTRLA = TWI_MASTER_ENABLE_bm; TWI.MASTER.CTRLB = TWI_SLAVE_SMEN_bm; TWI.MASTER.BAUD = TWI_BAUDSETTING_rtc; TWI.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc; //TWI.MASTER.STATUS |= TWI_MASTER_BUSSTATE_IDLE_gc; if (TWI.MASTER.STATUS == TWI_MASTER_BUSSTATE_IDLE_gc) { TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION TWI.MASTER.ADDR = 0xD0 ; //SEND SLAVE ADRESS while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR SEND DATA TWI.MASTER.DATA = 0x0E; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; TWI.MASTER.DATA = 0; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; TWI.MASTER.CTRLC = TWI_MASTER_BUSSTATE_BUSY_gc; //STOP CONDITION } return TRUE; } //______________________________________________________________________________ char rtc_get_clock(void) { int err=0; TWI.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc; TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION TWI.MASTER.ADDR = 0xD0 ; //SEND SLAVE ADRESS while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR SEND DATA TWI.MASTER.DATA = 0x00; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //read s,m,h from ds3231 TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION //TWI.MASTER.CTRLC = 0x05; TWI.MASTER.ADDR = 0xD1; //SEND SLAVE ADRESS while(!(TWI.MASTER.STATUS & (TWI_MASTER_RIF_bm|TWI_MASTER_WIF_bm))); rtc_seconds = TWI.MASTER.DATA; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_RIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR RECIVE DATA rtc_minutes = TWI.MASTER.DATA; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_RIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR RECIVE DATA rtc_hours = TWI.MASTER.DATA; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_RIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR RECIVE DATA rtc_days = TWI.MASTER.DATA; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_RIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR RECIVE DATA rtc_dat = TWI.MASTER.DATA; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_RIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR RECIVE DATA rtc_mon = TWI.MASTER.DATA; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_RIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR RECIVE DATA rtc_year = TWI.MASTER.DATA; TWI.MASTER.CTRLC=(TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc); rtc_seconds = bcd2bin(rtc_seconds); rtc_minutes = bcd2bin(rtc_minutes); rtc_hours = bcd2bin(rtc_hours); rtc_days = bcd2bin(rtc_days); rtc_dat = bcd2bin(rtc_dat); rtc_mon = bcd2bin(rtc_mon); rtc_year = bcd2bin(rtc_year); return TRUE; } //______________________________________________________________________________ char rtc_get_temp(void) { int err=0; TWI.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc; TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION TWI.MASTER.ADDR = 0xD0 ; //SEND SLAVE ADRESS while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR SEND DATA TWI.MASTER.DATA = 0x0E; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; TWI.MASTER.DATA = 1<<5; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; TWI.MASTER.CTRLC = TWI_MASTER_BUSSTATE_BUSY_gc; //STOP CONDITION //_delay_ms(50); TWI.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc; TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION TWI.MASTER.ADDR = 0xD0 ; //SEND SLAVE ADRESS err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR SEND DATA TWI.MASTER.DATA = 0x11; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //read temp from ds3231 TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION //TWI.MASTER.CTRLC = 0x05; TWI.MASTER.ADDR = 0xD1; //SEND SLAVE ADRESS err=0;while(!(TWI.MASTER.STATUS & (TWI_MASTER_RIF_bm|TWI_MASTER_WIF_bm))){_delay_ms(1);if(++err>250){return FALSE;}}; th = TWI.MASTER.DATA; err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_RIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}}; //WAIT FOR RECIVE DATA tl = TWI.MASTER.DATA; TWI.MASTER.CTRLC=(TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc); // th = th<<1; // rtc_temp = th; // rtc_temp = (rtc_temp<<8) | tl; rtc_temp = th + 0.25*(tl>>6); rtc_temp -= 3; return TRUE; } //______________________________________________________________________________ char rtc_set_clock(char h,char m) { m=hex2bcd(m); h=hex2bcd(h); int err=0; TWI.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc; TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION TWI.MASTER.ADDR = 0xD0; //SEND SLAVE ADRESS err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = 0x01; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = m; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = h; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.CTRLC = TWI_MASTER_BUSSTATE_BUSY_gc; //STOP CONDITION return TRUE; } //______________________________________________________________________________ char rtc_set_dat(char y,char mon,char dat,char day) { day=hex2bcd(day); dat=hex2bcd(dat); mon=hex2bcd(mon); y=hex2bcd(y); int err=0; TWI.MASTER.STATUS |= TWI_MASTER_BUSSTATE_IDLE_gc; TWI.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc; //START CONDIOTION TWI.MASTER.ADDR = 0xD0; //SEND SLAVE ADRESS err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = 0x03; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = day; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = dat; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = mon; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.DATA = y; //SEND SLAVE DATA err=0;while(!(TWI.MASTER.STATUS & TWI_MASTER_WIF_bm)){_delay_ms(1);if(++err>250){return FALSE;}} //WAIT FOR SEND DATA TWI.MASTER.CTRLC = TWI_MASTER_BUSSTATE_BUSY_gc; //STOP CONDITION return TRUE; } //______________________________________________________________________________ U8 hex2bcd (unsigned char x) { unsigned char y; y = (x / 10) << 4; y = y | (x % 10); return (y); } //______________________________________________________________________________ U8 dec2bcd(unsigned char n) { return n + 6 * (n / 10); } //______________________________________________________________________________ U8 decToBcd(U8 val) { // Convert normal decimal numbers to binary coded decimal return ( (val/10*16) + (val%10) ); } //______________________________________________________________________________ int bcd2bin(int x) { int binary; binary = ((x & 0xF0 )>>4 ) * 10 + (x & 0x0F); return (binary); } //______________________________________________________________________________ U8 bcdToDec(U8 val) { // Convert binary coded decimal to normal decimal numbers return ( (val/16*10) + (val%16) ); } #endif