// ****************************************************************************************************************************************************
// usando o relogio de tempo real PCF8583
//
// Data: 27/11/2009
// Autor: Aguivone
// Descrição: demonstra como usar um rtc da Philips 
// *************************************************************************************************************************************************************************************************************************
#include <16F877A.h> 
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP 
#use delay(clock=4M) 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) 
#use I2C(master, scl=PIN_C3, sda=PIN_C4)
#define PCF8583_Ende_escrita 0xA0 
#define PCF8583_Ende_leitura 0xA1 
#define PCF8583_Status_controle 0x00 
#define PCF8583_Centesimo_seg 0x01 
#define PCF8583_Segundos 0x02 
#define PCF8583_Minutos 0x03 
#define PCF8583_Horas 0x04 
#define PCF8583_Ano_Dia 0x05 
#define PCF8583_Mes_Semana 0x06 
#define PCF8583_Timer 0x07 
#define PCF8583_Controle_Alarme 0x08 
#define PCF8583_Alarme_centesimo 0x09 
#define PCF8583_Alarme_segundos 0x0A 
#define PCF8583_Alarme_minutos 0x0B 
#define PCF8583_Alarme_horas 0x0C 
#define PCF8583_Alarme_dia 0x0D 
#define PCF8583_Alarme_mes 0x0E 
#define PCF8583_Alarme_timer 0x0F 
#define PCF8583_Reg_Ano 0x10 //1° endereço da ram do ci
// usados para modo contador. 
#define PCF8583_Inicio_de_contagem 0x00 
#define PCF8583_Fim_de_contagem 0x80 
int segundos=45; 
int minutos=59; 
int horas=24; 
int dia=31; 
int mes=7; 
int ano=2;//0 à 3 
int semana=1;//0 = Sunday, 1 = Monday, etc.
char dia_da_semana[8][10] = 
{ 
{"Domingo"}
,{"Segunda"}
,{"Terca"}
,{"Quarta"}
,{"Quinta"}
,{"Sexta"}
,{"Sabado"} 
};
//---------------------------------------------- 
void PCF8583_escreve_byte(int8 endereco, int8 dados) 
{ 
disable_interrupts(GLOBAL); 
i2c_start(); //inicializa a comunicaçao i2c
i2c_write(PCF8583_Ende_escrita); 
i2c_write(endereco); 
i2c_write(dados); 
i2c_stop(); //finaliza comunicação
enable_interrupts(GLOBAL); 
} 
//---------------------------------------------- 
int PCF8583_ler_byte(int endereco) 
{ 
int lido; 
disable_interrupts(GLOBAL); 
i2c_start(); 
i2c_write(PCF8583_Ende_escrita); 
i2c_write(endereco); 
i2c_start(); 
i2c_write(PCF8583_Ende_leitura); 
lido = i2c_read(0);//ler sem ack =0 , ler com ack = 1 
i2c_stop(); 
enable_interrupts(GLOBAL); 
return(lido); //retorna o valor lido 
} 
//---------------------------------------------- 
// converte de binario para bcd (8 bits), de 0 a 99
int BINparaBCD(int valor) 
{ 
int BCD=0; 
while(1) 
{ 
if(valor >= 10) 
{ 
valor -= 10; 
BCD += 0x10; 
} 
else //incrementa casas decimais. 
{ 
BCD += valor; 
break; 
} 
} 
return(BCD); //retorna o valor
} 
// converte de bcd para binario (8 bits), de 0 a 99
int BCDparaBIN(int valor) 
{ 
int temp=15;
int temp2=240;
temp &= valor;
temp2 &= valor;
temp2 >>= 4;
temp2 *= 10;
valor=temp+temp2;
return(valor); 
} 
//---------------------------------------------- 
void PCF8583_programar_tempo(void) 
{
int8 bcd_sec; 
int8 bcd_min; 
int8 bcd_hrs; 
int8 bcd_dia; 
int8 bcd_mes; 
// Converte binario para bcd
bcd_sec = BINparaBCD(segundos); 
bcd_min = BINparaBCD(minutos); 
bcd_hrs = BINparaBCD(horas); 
bcd_dia = BINparaBCD(dia) | (ano << 6); bcd_mes = BINparaBCD(mes) | (semana << 5); // para contagem antes de escrever nos registradores de datas PCF8583_escreve_byte(PCF8583_Status_controle,PCF8583_Fim_de_contagem); // deve-se desabilitar as interrupçoes para fazer a comunicação I2C. disable_interrupts(GLOBAL); i2c_start(); i2c_write(PCF8583_Ende_escrita); i2c_write(PCF8583_Centesimo_seg); // inicia os centesimos de segundos com 0. i2c_write(0x00); i2c_write(bcd_sec); //escreve os segundos i2c_write(bcd_min); i2c_write(bcd_hrs); i2c_write(bcd_dia); i2c_write(bcd_mes); i2c_stop(); enable_interrupts(GLOBAL); PCF8583_escreve_byte(PCF8583_Status_controle,PCF8583_Inicio_de_contagem); } //---------------------------------------------- // Lê data e tempo dos registradores do // PCF8583. Não é preciso parar a contagem durante a operação de leitura void PCF8583_ler_datas(void) { disable_interrupts(GLOBAL); // lê o PCF8583. i2c_start(); i2c_write(PCF8583_Ende_escrita); i2c_write(PCF8583_Segundos); // inicia lendo segundos. i2c_start(); i2c_write(PCF8583_Ende_leitura); segundos = i2c_read(); minutos = i2c_read(); horas = i2c_read(); dia = i2c_read(); mes = i2c_read(0); i2c_stop(); enable_interrupts(GLOBAL); // converte datas de bcd para inteiro segundos = BCDparaBIN(segundos); minutos = BCDparaBIN(minutos); horas = BCDparaBIN(horas& 0x3F);//pega os 6 bits mais baixos ano = dia >> 6; //rotaciona 6 bits para pegar anos (0 à 3) 
dia = BCDparaBIN(dia & 0x3F);//pega os 6 bits mais baixos 
semana = mes >> 5 ;//rotaciona 5 bits para pegar dia da semana( 0 à 6)
mes = BCDparaBIN(mes & 0x1F); //pega os 5 bits mais baixos 
}
/////////////////////////////////////////////////////////////////////////////////////
//================================= 
void main() 
{ 
PCF8583_escreve_byte(PCF8583_Status_controle, 
PCF8583_Inicio_de_contagem);
PCF8583_programar_tempo();//ajusta data e hora conforme os valores pre ajustados,
while(1) 
{ 
delay_ms(1000);
PCF8583_ler_datas();
printf("hora %u:%u:%u \n\r",horas,minutos,segundos); 
printf("data %u/%u/%u \n\r",dia,mes,ano); 
printf(" hoje e %s \n\r",dia_da_semana[semana]); 
} 
}
Nenhum comentário:
Postar um comentário
olá,digite aqui seu comentário!