Rostislav Vyroubal, Rostislav Nunvář UREL, FEEC, VUT Brno
xvyrou00stud.feec.vutbr.cz
xnunva00stud.feec.vutbr.cz
/* ******************************************************************************** ** Nazev souboru : MMIA1.c ** Mikrokontroler : ATmega16 ** Popis : Srovnani hodin s PCF8563 a SW hodin s 16MHz krystalem ** Autor : Rostislav Vyroubal, Rostislav Nunvar ** Predmet : Mikroprocesorova technika ** Posledni zmena : 19.4.2010 ******************************************************************************** */ /******************************************************************************* pouzite veci - krystal 16MHz - funkce - pouziva 16 bit citac1 fosc= fclk/(2*N*(1+OCR)) ; N= 1 8 32 64 128 256 1024 fosc= 16000000/(2*256*(1+31249))=1Hz - pocet cyklu citace pro jednu sekundu je 15624 = 0011 1101 0000 1000 ******************************************************************************** */ #include "lcd_h.h" #include "lcd_c.c" #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define F_CPU 16000000UL #define PCF8563 0xA2 // adresa PCF8563 #define I2C_READ 1 // PCF8563 cteni #define I2C_WRITE 0 // PCF8563 zapis #define sekundyRTC 0x02 #define minutyRTC 0x03 #define hodinyRTC 0x04 #define dnyRTC 0x05 #define den_v_tydnuRTC 0x06 #define mesiceRTC 0x07 #define rokyRTC 0x08 char buffer1[20]; char rozdil; unsigned char DEC; // promenny pro RTC unsigned int BCD; unsigned char sekundy; unsigned char minuty; unsigned char hodiny; unsigned char dny; unsigned char den_v_tydnu; unsigned char mesice; unsigned char roky; // promenné pro SW hodiny char sekunda =0; char minuta =0; char hodina =0; char den =0; char mesic =0; int rok =0; unsigned char read(bunka) { i2c_start_wait(PCF8563+I2C_WRITE); // zapis do PCF8563 i2c_write(bunka); // adresa bunky i2c_rep_start(PCF8563+I2C_READ); // cteni z PCF8563 BCD=i2c_readNak(); i2c_stop(); // stop }; unsigned char write(DEC,bunka) { // Prevede DEC do BCD BCD = ((((DEC/10) <<4) & 0xF0) | ((DEC% 10) & 0x0F)); i2c_start_wait(PCF8563+I2C_WRITE); i2c_write(bunka); // vyber adresy( hodiny minuty atd)i2c_write(BCD); // zapise BCD na vybranou adresu i2c_stop(); // stop }; ISR(TIMER1_COMPA_vect) { // Zacatek RTC hodin read(rokyRTC); // cte roky z RTC roky = (((BCD & 0xf0)>>4)*10 + (BCD & 0x0f)); read(mesiceRTC); // cte mesice z RTC mesice = ((((BCD & 0b10011111) & 0xf0)>>4)*10 + (BCD & 0x0f)); read(den_v_tydnuRTC); // cte tydny z RTC den_v_tydnu = BCD & 0b00000111; read(dnyRTC); // cte dny z RTC dny = ((((BCD & 0b00111111) & 0xf0)>>4)*10 + (BCD & 0x0f)); read(hodinyRTC); // cte hodiny z RTC hodiny = ((((BCD & 0b00111111) & 0xf0)>>4)*10 + (BCD & 0x0f)); read(minutyRTC); // cte minuty z RTC minuty = ((((BCD & 0b01111111) & 0xf0)>>4)*10 + (BCD & 0x0f)); read(sekundyRTC); // cte sekundy z RTC sekundy = ((((BCD & 0b01111111) & 0xf0)>>4)*10 + (BCD & 0x0f)) ; // Konec RTC hodin // Zacatek SW hodin sekunda++; if (sekunda>=60) { sekunda=0; minuta++; }; if (minuta>=60) { minuta=0; hodina++; }; if (hodina>=24) { den++; hodina=0; }; switch (mesic) { case 1: if (den==31) { den=1; mesic++; }; break; case 2: if ( (rok % 4)==0 ) { //zbytek po deleni 4 je 0 if (den==30) { den=1; mesic++; } } else{ if (den==29) { den=1; mesic++; }; }; break; case 3: if (den==31) { den=1; mesic++; }; break; case 4: if (den==30) { den=1; mesic++; }; break; case 5: if (den==31) { den=1; mesic++; }; break; case 6: if (den==30) { den=1; mesic++; }; break; case 7: if (den==31) { den=1; mesic++; }; break; case 8: if (den==31) { den=1; mesic++; }; break; case 9: if (den==30) { den=1; mesic++; }; break; case 10: if (den==31) { den=1; mesic++; }; break; case 11: if (den==30) { den=1; mesic++; }; break; case 12: if (den>=31) den=1; mesic=1; rok++; break; }; // Konec SW hodin rozdil = sekunda - sekundy; // sekunda patří SW sekundy RTC // Zacatek zapisu na LCD lcd_gotoxy(0,0); sprintf(buffer1,"RTC:%u:%u:%u ",hodiny,minuty,sekundy); lcd_puts(buffer1); sprintf(buffer1,"SW: %u:%u:%u ", hodina, minuta, sekunda); lcd_gotoxy(0,1); lcd_puts(buffer1); sprintf(buffer1,"D:%u W:%u M:%u R:20%u ",dny,den_v_tydnu, mesice, roky); lcd_gotoxy(0,2); lcd_puts(buffer1); sprintf(buffer1,"Rozdil sekund: %d ", rozdil); lcd_gotoxy(0,3); lcd_puts(buffer1); // konec zapisu na lcd }; int main(void) { DDRA=0b00000000; // PORTA vstupni TCCR1A= 0b00000000; // konfigurace c/c TCCR1B= 0b00001101; //konfigurace c/c TIMSK = (1<<OCIE1A); //povoleni preruseni OCR1AH =0b00111101; //pocet cyklu citace pro jednu sekundu (15624) OCR1AL =0b00001000; sei(); // povoleni globalniho preruseni i2c_init(); // inicializace I2C lcd_init(); // inicializace LCD //* Konfigurace hodin********************************************************** write(10,rokyRTC); // Rok je od 00 do 99 write(4,mesiceRTC); write(1,den_v_tydnuRTC);//0 PO, 1 Ut, ... write(20,dnyRTC); write(21,hodinyRTC); // Bohuzel PCF8563 umoznuje mit den s 32hodinami:-) write(35,minutyRTC); write(0,sekundyRTC); //**************************************************************************** // // Na zacatku ulozime cas z RTC do SW hodin read(hodinyRTC); // cte hodiny z RTC // prevod bcd do bin s osetrenim ignorovanych bitu hodina = ((((BCD & 0b00111111) & 0xf0)>>4)*10 + (BCD & 0x0f)); read(minutyRTC); // cte minuty z RTC minuta = ((((BCD & 0b01111111) & 0xf0)>>4)*10 + (BCD & 0x0f)); read(sekundyRTC); // cte sekundy z RTC sekunda = ((((BCD & 0b01111111) & 0xf0)>>4)*10 + (BCD & 0x0f)) ; while(1) // cekaci smycka { if (bit_is_clear(PINA,PA7)) // Manualni reinicializace lcd pri jeho odpojeni { lcd_init(); lcd_clrscr(); lcd_puts("Loading"); }; asm ("nop"); asm ("nop"); }; }