sexta-feira, 12 de novembro de 2010

usando rtc DS1307

olá , este é um exemplo de como usar o RTC DS1307.


CÓDIGO FONTE:

// ****************************************************************************************************************************************************
// usando o relogio de tempo real DS1307
//
// Data: 12/11/2010
// Autor: Aguivone
// Descrição: demonstra como usar um rtc da maxin(dallas)
// *************************************************************************************************************************************************************************************************************************
#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)
/////////////////////////////////////////configuração e parametrização//////////////////
#define DS1307_SEGUNDOS 0
#define DS1307_MINUTOS 1
#define DS1307_HORAS 2 // se no modo 12hrs o bit 5 indica se é AM ou PM
#define DS1307_DIA_DA_SEMANA 3
#define DS1307_DIA_DO_MES 4
#define DS1307_MES 5
#define DS1307_ANO 6
#define DS1307_STATUS_CONTROLE 7
#define DS1307_RAM 8 //endereço inicial da ram
//formato das horas
#define DS1307_12HRS 64 //habilita o bit 6 , das horas
#define DS1307_24HRS 0
//usados para escrita
#define DS1307_Ende_escrita 0xd0
#define DS1307_Ende_leitura 0xd1
//foi disabilitada o SQWV pois consome muito da bateria
#define DS1307_SQWV 0x80
// 32.768 KHz saida (habilitado)
//#define DS1307_SQWV 0x13
///////////////////////////////////////////////////////////////////////////////////////

int segundos=50;
int minutos=59;
int horas=23;
int dia_mes=12;
int mes=11;
int ano=10;//0 à 99
int dia_semana=7;//0 = Sunday, 1 = Monday, etc.// de 0 a 6

char dia_da_semana[8][10] =
{
{"nada"}
,{"Domingo"}
,{"Segunda"}
,{"Terca"}
,{"Quarta"}
,{"Quinta"}
,{"Sexta"}
,{"Sabado"}
};


//----------------------------------------------
void DS1307_escreve_byte(int8 endereco, int8 dados)
{
disable_interrupts(GLOBAL);
i2c_start(); //inicializa a comunicaçao i2c
i2c_write(DS1307_Ende_escrita);
i2c_write(endereco);
i2c_write(dados);
i2c_stop(); //finaliza comunicação
enable_interrupts(GLOBAL);
}

//----------------------------------------------
int DS1307_ler_byte(int endereco)
{
int lido;
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1307_Ende_escrita);
i2c_write(endereco);
i2c_start();
i2c_write(DS1307_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(valor>1)
{
if(valor >= 10) //incrementa casas decimais.
{
valor -= 10;
BCD += 0x10;
}
else
{
BCD += valor;
valor=0;
}
}
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 DS1307_programar_tempo(void)
{

int8 bcd_sec;
int8 bcd_min;
int8 bcd_hrs;
int8 bcd_dia_semana;
int8 bcd_dia_mes;
int8 bcd_mes;
int8 bcd_ano;
int8 bcd_sqwv;
// Converte binario para bcd
bcd_sec = BINparaBCD(segundos);
bcd_min = BINparaBCD(minutos);
bcd_hrs = BINparaBCD(horas=horas|DS1307_24HRS); //faz um ou logico para informar o tipo da data
bcd_dia_semana = BINparaBCD(dia_semana) ;
bcd_dia_mes = BINparaBCD(dia_mes) ;
bcd_mes = BINparaBCD(mes) ;
bcd_ano = BINparaBCD(ano);
bcd_sqwv = BINparaBCD(DS1307_SQWV);
// deve-se desabilitar as interrupçoes para fazer a comunicação I2C.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1307_Ende_escrita);
i2c_write(DS1307_SEGUNDOS); // inicia a partir do registrador 0(segundos e inicia ele com zero).
i2c_write(bcd_sec); //escreve os segundos
i2c_write(bcd_min);
i2c_write(bcd_hrs);
i2c_write(bcd_dia_semana);
i2c_write(bcd_dia_mes);
i2c_write(bcd_mes);
i2c_write(bcd_ano);
i2c_write(bcd_sqwv);
i2c_stop();
enable_interrupts(GLOBAL);
}

//----------------------------------------------
// Lê data e tempo dos registradores do
// PCF8583. Não é preciso parar a contagem durante a operação de leitura

void DS1307_ler_datas(void)
{
disable_interrupts(GLOBAL);
// lê o DS1307.
i2c_start();
i2c_write(DS1307_Ende_escrita);
i2c_write(DS1307_SEGUNDOS); // inicia lendo segundos.
i2c_start();
i2c_write(DS1307_Ende_leitura);
segundos = i2c_read();
minutos = i2c_read();
horas = i2c_read();
dia_semana = i2c_read();
dia_mes = i2c_read();
mes = i2c_read();
ano = 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 (formato 24hrs)
dia_mes = BCDparaBIN(dia_mes);
dia_semana = BCDparaBIN(dia_semana);
mes = BCDparaBIN(mes);
ano = BCDparaBIN(ano);
if(dia_semana==0)
{
disable_interrupts(GLOBAL);
i2c_start();
DS1307_escreve_byte(3,1);
i2c_stop();
enable_interrupts(GLOBAL);
dia_semana=1;
}
}
/////////////////////////////////////////////////////////////////////////////////////

//=================================
void main()
{
DS1307_programar_tempo();//ajusta data e hora conforme os valores pre ajustados, para simular data atual comente esta linha
DS1307_ler_datas();
while(1)
{
delay_ms(1000);
DS1307_ler_datas();
printf("hora %u:%u:%u \n\r",horas,minutos,segundos);
printf("data %u/%u/%u \n\r",dia_mes,mes,ano);
printf(" hoje e %s \n\r",dia_da_semana[dia_semana]);
if(ano>9)
{
printf(" ano atual = 20%u \n\r",ano);
}
else
{
printf(" ano atual = 200%u \n\r",ano);
}

}

}

Um comentário :

olá,digite aqui seu comentário!