//--------------------------------------------------------------------------------------------------------- // Autor: Marcelo Gonçalves Damasceno // Data: março/2007 // Compilador: CCS-C (PCW) ver. 3.150 // IDE: MPLAB v7.21 /*=========================================================================================================*/ // *** Definições do Microcontrolador *** #include <16f628.h> #use delay(clock=4000000) #use i2c(Master, SDA=PIN_B1, SCL=PIN_B2) #fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,NOMCLR,NOLVP //palavras de config. // bytes de controle do DS1307 #define ESCREVER 0xd0 #define LER 0xd1 // endereços dos registradores #define REG_SEGUNDOS 0 #define REG_MINUTOS 1 #define REG_HORAS 2 #define REG_DIA_SEMANA 3 #define REG_DIA 4 #define REG_MES 5 #define REG_ANO 6 #define REG_CONTROLE 7 #define TAMANHO_REG 7 #define TAMANHO_SEM 3 #define VALOR_INICIAL_CONTROLE 0x10 //bytes de controle do display #BYTE PORTA = 0x05 #BYTE PORTB = 0x06 #byte DISPLAY=PORTA #bit RS=PORTB.3 #bit EN=PORTB.4 #include //inclui a biblioteca de manipulaçao do LCD // prototipos das funçoes void init(void); void set_time(void); void read_time(void); void lcd(void); void lcd_abre(void); void converte_sem(void); int toBCD(int val_bin); // conversao para BCD int toBIN(int val_bcd); // conversao para inteiro //globais int ds1307[TAMANHO_REG]; int semana[TAMANHO_SEM]; int hora_dez[TAMANHO_REG]; int hora_unid[TAMANHO_REG]; int j; // inicializaçao do hardware void init(void){ disable_interrupts(GLOBAL); // desliga todas as interrupçoes } // set time & date on power-up void set_time(void){ int i; hora_unid[0]= 0; hora_dez[0] = 0; hora_unid[1]= 0; hora_dez[1] = 0; hora_unid[2]= 0; hora_dez[2] = 0; hora_unid[3]= 1; hora_dez[3] = 0; hora_unid[4]= 1; hora_dez[4] = 0; hora_unid[5]= 1; hora_dez[5] = 0; hora_unid[6]= 7; hora_dez[6] = 0; ds1307[REG_DIA_SEMANA]=(hora_unid[3]); converte_sem(); lcd(); ds1307[REG_SEGUNDOS]=0; while (input(pin_b6)){ if (!input(pin_b5)){ hora_unid[2]++; // incrementa o display 1 if(hora_unid[2]>9){ // se o valor do display 1 for maior que 9, hora_unid[2]=0; // zera o display hora_dez[2]++; // incrementa o display 2 } if(hora_dez[2]==2 && hora_unid[2]==4 ){ hora_dez[2]=0; hora_unid[2]=0; } lcd(); delay_ms(200); } } ds1307[REG_HORAS]=(hora_dez[2]*10 + hora_unid[2]); while (!input(pin_b6)); lcd(); while (input(pin_b6)){ if (!input(pin_b5)){ hora_unid[1]++; // incrementa o display 1 if(hora_unid[1]>9){ // se o valor do display 1 for maior que 9, hora_unid[1]=0; // zera o display hora_dez[1]++; // incrementa o display 2 } if(hora_dez[1]>5) hora_dez[1]=0; lcd(); delay_ms(200); } } ds1307[REG_MINUTOS]=(hora_dez[1]*10 + hora_unid[1]); while (!input(pin_b6)); lcd(); while (input(pin_b6)){ if (!input(pin_b5)){ hora_unid[4]++; // incrementa o display 1 if(hora_unid[4]>9){ // se o valor do display 1 for maior que 9, hora_unid[4]=0; // zera o display hora_dez[4]++; // incrementa o display 2 } if(hora_dez[4]==3 && hora_unid[4]==2 ){ hora_dez[4]=0; hora_unid[4]=1; } lcd(); delay_ms(200); } } ds1307[REG_DIA]=(hora_dez[4]*10 + hora_unid[4]); while (!input(pin_b6)); lcd(); while (input(pin_b6)){ if (!input(pin_b5)){ hora_unid[5]++; // incrementa a hora if(hora_unid[5]>9){ // se o valor da hora for maior que 23, hora_unid[5] =0; // zera a hora hora_dez[5]++; } if(hora_dez[5]==1 && hora_unid[5]==3 ){ hora_dez[5]=0; hora_unid[5]=1; } lcd(); delay_ms(200); } } ds1307[REG_MES]=(hora_dez[5]*10 + hora_unid[5]); while (!input(pin_b6)); lcd(); while (input(pin_b6)){ if (!input(pin_b5)){ hora_unid[6]++; // incrementa a hora if(hora_unid[6]>9){ // se o valor da hora for maior que 23, hora_unid[6] =0; // zera a hora hora_dez[6]++; } if(hora_dez[6]==1 && hora_unid[6]==6 ){ hora_dez[6]=0; hora_unid[6]=7; } lcd(); delay_ms(200); } } ds1307[REG_ANO]=(hora_dez[6]*10 + hora_unid[6]); while (!input(pin_b6)); ds1307[REG_DIA_SEMANA]=(hora_unid[3]); converte_sem(); lcd(); while (input(pin_b6)){ if (!input(pin_b5)){ hora_unid[3]++; // incrementa o display 1 if(hora_unid[3]>7) hora_unid[3]=1; // zera o display ds1307[REG_DIA_SEMANA]=(hora_unid[3]); converte_sem(); lcd(); delay_ms(200); } } // convert to BCD for(i=0; i<7; i++){ ds1307[i] = toBCD(ds1307[i]); } delay_ms(20); // write 7 bytes of BCD data to ds1307 i2c_start(); i2c_write(ESCREVER); // start at seconds register i2c_write(REG_SEGUNDOS); // write 7 bytes to registers 0 to 6 for(i=0; i<7; i++){ i2c_write(ds1307[i]); } i2c_write(VALOR_INICIAL_CONTROLE); i2c_stop(); } // read time & date from DS1307 void read_time(void){ int i; i2c_start(); i2c_write(ESCREVER); // start i2c read at seconds register i2c_write(REG_SEGUNDOS); i2c_start(); i2c_write(LER); // read the 7 bytes from the ds1307. Mask off the unused bits ds1307[REG_SEGUNDOS] = i2c_read() & 0x7f; ds1307[REG_MINUTOS] = i2c_read() & 0x7f; ds1307[REG_HORAS] = i2c_read() & 0x3f; ds1307[REG_DIA_SEMANA] = i2c_read() & 0x07; ds1307[REG_DIA] = i2c_read() & 0x3f; ds1307[REG_MES] = i2c_read() & 0x1f; ds1307[REG_ANO] = i2c_read(0); i2c_stop(); converte_sem(); // convert to BIN for(i=0; i<7; i++){ ds1307[i] = toBIN(ds1307[i]); // converte dia_semana } } void converte_sem(void){ switch (ds1307[REG_DIA_SEMANA]) { case 1: { semana[0] = 'S'; semana[1] = 'e'; semana[2] = 'g'; } break; case 2: { semana[0] = 'T'; semana[1] = 'e'; semana[2] = 'r'; } break; case 3: { semana[0] = 'Q'; semana[1] = 'u'; semana[2] = 'a'; } break; case 4: { semana[0] = 'Q'; semana[1] = 'u'; semana[2] = 'i'; } break; case 5: { semana[0] = 'S'; semana[1] = 'e'; semana[2] = 'x'; } break; case 6: { semana[0] = 'S'; semana[1] = 'a'; semana[2] = 'b'; } break; case 7: { semana[0] = 'D'; semana[1] = 'o'; semana[2] = 'm'; } break; } } // esta funcao converte um valor binario de 8 bits // para um valor BCD de 8 bits. Range 0 a 99. int toBCD(int val_bin){ int temp; int retval; temp = val_bin; retval = 0; for(;;){ // obtem os digitos da dezenas atraves de multiplas subtracoes // de 10 da variavel val_bin if(temp >= 10) { temp -= 10; retval += 0x10; // increment tens digit } else // get ones digit by adding remainder { retval += temp; // adjusted result break; } } return(retval); } // esta funcao converte um valor BCD de 8 bits // para um valor binario de 8 bits. int toBIN(int val_bcd){ int i; int temp; int unid; int dez; temp = val_bcd; temp &= 0x0f; unid = temp; hora_unid[j] = temp; temp = val_bcd; for(i=0;i<4;i++) shift_right(&temp,1,0); hora_dez[j]= temp; temp *= 10; dez = temp; temp = dez + unid; j++; if (j>6) j=0; return(temp); } // instruçoes iniciais void lcd_abre(void){ lcd_comando(0x80); lcd_dado('P'); lcd_dado('a'); lcd_dado('r'); lcd_dado('a'); lcd_dado(' '); lcd_dado('a'); lcd_dado('j'); lcd_dado('u'); lcd_dado('s'); lcd_dado('t'); lcd_dado('a'); lcd_dado('r'); lcd_dado(' '); lcd_dado('a'); lcd_dado(' '); lcd_dado(' '); lcd_comando(0xC0); lcd_dado('h'); lcd_dado('o'); lcd_dado('r'); lcd_dado('a'); lcd_dado(' '); lcd_dado('e'); lcd_dado(' '); lcd_dado('a'); lcd_dado(' '); lcd_dado('d'); lcd_dado('a'); lcd_dado('t'); lcd_dado('a'); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); delay_ms(2000); lcd_comando(0x80); lcd_dado('P'); lcd_dado('r'); lcd_dado('e'); lcd_dado('s'); lcd_dado('s'); lcd_dado('i'); lcd_dado('o'); lcd_dado('n'); lcd_dado('e'); lcd_dado(' '); lcd_dado('S'); lcd_dado('E'); lcd_dado('T'); lcd_dado(' '); lcd_dado('e'); lcd_dado(' '); lcd_comando(0xC0); lcd_dado('c'); lcd_dado('o'); lcd_dado('n'); lcd_dado('f'); lcd_dado('i'); lcd_dado('r'); lcd_dado('m'); lcd_dado('e'); lcd_dado(' '); lcd_dado('e'); lcd_dado('m'); lcd_dado(' '); lcd_dado('M'); lcd_dado('O'); lcd_dado('D'); lcd_dado('E'); delay_ms(2000); } // mostra no lcd void lcd(){ lcd_comando(0x80); lcd_dado(hora_dez[4]+0x30); lcd_dado(hora_unid[4]+0x30); lcd_dado('/'); lcd_dado(hora_dez[5]+0x30); lcd_dado(hora_unid[5]+0x30); lcd_dado('/'); lcd_dado('2'); lcd_dado('0'); lcd_dado(hora_dez[6]+0x30); lcd_dado(hora_unid[6]+0x30); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); lcd_dado(semana[0]); lcd_dado(semana[1]); lcd_dado(semana[2]); lcd_comando(0xC0); lcd_dado(hora_dez[2]+0x30); lcd_dado(hora_unid[2]+0x30); lcd_dado(':'); lcd_dado(hora_dez[1]+0x30); lcd_dado(hora_unid[1]+0x30); lcd_dado(':'); lcd_dado(hora_dez[0]+0x30); lcd_dado(hora_unid[0]+0x30); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); lcd_dado(' '); } // funçao principal void main(void){ init(); //inicializaçao dos ports e perifericos do PIC lcd_init(); j=0; delay_ms(200); lcd_abre(); set_time(); for(;;){ read_time(); lcd(); } }