quarta-feira, 8 de setembro de 2010

usando o RTC com o pic

// ****************************************************************************************************************************************************
// 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!