Вы находитесь на странице: 1из 4

CDIGO FONTE:

// *****************************************************************************
***********************************************************************
// usando o relogio de tempo real DS1307
//
// Data: 12/11/2010
// Autor: Aguivone
// Descrio: 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)
/////////////////////////////////////////configurao e parametrizao//////////////////
#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 //endereo 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
int
int
int
int
int
int

segundos=50;
minutos=59;
horas=23;
dia_mes=12;
mes=11;
ano=10;//0 99
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 comunicaao i2c
i2c_write(DS1307_Ende_escrita);
i2c_write(endereco);
i2c_write(dados);
i2c_stop(); //finaliza comunicao
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 interrupoes para fazer a comunicao I2C.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1307_Ende_escrita);
i2c_write(DS1307_SEGUNDOS); // inicia a partir do registrador 0(segundos e inici
a 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. No preciso parar a contagem durante a operao 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);
}
}
}

Вам также может понравиться