Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
DavidsonrSouza

Problemas com DS1307 + PIC em C

Recommended Posts

Bom dia pessoal!

Estou com um projeto de controle para um sinal de escola.

O projeto consiste em um circuito que dispara o sinal no inicio das aulas, nos intervalos, e no término das aulas, nos 3 turnos e só de segunda a sexta com as seguintes especificações:

Vai ter um display LCD16X2, Um teclado com 6 botões, Saída a relé para o acionamento da saída e usando um microcontrolador PIC18f452.

Como estava difícil implementar o calendário e o relógio com o microcontrolador, resolvi usar o ccto integrado RTC DS1307, mas meus problemas estavam apenas começando.

Depois de semanas de pesquisas (aqui no fórum e no google), consegui a comunicar com o RTC, porém, consigo apenas modificar os valores no mesmo, mas não consigo ler os valores do RTC.

acredito que seja as funções de leitura do RTC ou nas conversões nos dados de saída, mas como entendo pouco de programação, não consegui resolver o problema.

O problema é que tenho prazo para entregar o projeto montado e operante, e decidi pedir ajuda a vocês.

Se só conseguir ler o RTC, já "desgarra" o meu projeto.

Segue a seguir o código fonte e as bibliotecas que estou usando, tudo é de apenas testes então não reparem a bagunça, muitas funções inacabadas e não usadas.

Código fonte:

#include "16f877a.h"
#use delay(clock=20M)
#fuses hs,nowdt,nobrownout,nolvp,put,noprotect
#include"lcd.c"
#include"RTC_DS1307(original).c"
#include<string.h>

#define mais input(pin_a0)
#define menos input(pin_a1)
#define ok input(pin_a4)
#define muda input(pin_a2)

#define rele pin_a3

short seleciona_menu=0; //0=configura tempo 1=lê dados do rtc
short entra=0; //fica dentro das funções
short fica=0; //fica dentro do comando até salvar

short bisexto=0; //se o ano é bisexto, bisexto=1; se não, bisexto=0

int seconds=0;
int minutes=0;
int hours=0;
int date=0;
int day=0;
int month=0;
int year=0;



/*

// 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);
}


*/

char dia_semana_converte(day)
//lê o dia da semana
{
char dia_semana[7][4]={"dom","seg","ter","qua","qui","sex","sab"};
char dia_hoje[4];
switch(day)
{
case 1: strcpy(dia_hoje,dia_semana[day-1]);
return (dia_hoje);
break;

case 2: strcpy(dia_hoje,dia_semana[day-1]);
return (dia_hoje);
break;

case 3: strcpy(dia_hoje,dia_semana[day-1]);
return (dia_hoje);
break;

case 4: strcpy(dia_hoje,dia_semana[day-1]);
return (dia_hoje);
break;

case 5: strcpy(dia_hoje,dia_semana[day-1]);
return (dia_hoje);
break;

case 6: strcpy(dia_hoje,dia_semana[day-1]);
return (dia_hoje);
break;

case 7: strcpy(dia_hoje,dia_semana[day-1]);
return (dia_hoje);
break;
default:
break;
}
}


void configura_tempo()
{
while(entra)
{
lcd_escreve("\fAcerte as\nHoras:");
while(fica)////hora
{
if(mais)
{
hours++;
if(hours>23) hours=0;
printf(lcd_escreve,"\fAcerte as Horas:\n %u:%u",hours,minutes);
while(mais);
}
if(menos)
{
hours--;
if(hours==255) hours=23;
printf(lcd_escreve,"\fAcerte as Horas:\n %u:%u",hours,minutes);
while(menos);
}
if(muda)
{
lcd_escreve("\fAcerte os\nMinutos:");
fica=!fica;
while(muda);
}
}
while(!fica)////minuto
{
if(mais)
{
minutes++;
if(minutes>59) minutes=0;
printf(lcd_escreve,"\fAcerte minutos:\n %u:%u",hours,minutes);
while(mais);
}
if(menos)
{
minutes--;
if(minutes==255) minutes=59;
printf(lcd_escreve,"\fAcerte minutos:\n %u:%u",hours,minutes);
while(menos);
}
if(muda)
{
fica=!fica;
lcd_escreve("\fAcerte o Ano:");
while(muda);
}
}
while(fica)////ano
{
if(mais)
{
year++;
//if(date>12) month=0;
printf(lcd_escreve,"\fAcerte o ano:\n %u/%u/%u",date,month,year);
while(mais);
}
if(menos)
{
year--;
//if(minutes==255) minutes=59;
printf(lcd_escreve,"\fAcerte o ano:\n %u/%u/%u",date,month,year);
while(menos);
}
if(muda)
{
fica=!fica;
lcd_escreve("\fO ano é\nbisexto?");
while(muda);
}
}
while(!fica)////bisexto
{
if(mais)
{
bisexto=1;
lcd_escreve("\fSim.");
while(mais);
}
if(menos)
{
bisexto=0;
lcd_escreve("\fNao.");
while(menos);
}
if(muda)
{
fica=!fica;
lcd_escreve("\fAcerte o Mes:");
while(muda);
}
}
while(fica)////mes
{
if(mais)
{
month++;
if(month>12) month=0;
printf(lcd_escreve,"\fAcerte o mes:\n %u/%u/%u",date,month,year);
while(mais);
}
if(menos)
{
month--;
if(month==255) month=12;
printf(lcd_escreve,"\fAcerte o mes:\n %u/%u/%u",date,month,year);
while(menos);
}
if(muda)
{
fica=!fica;
lcd_escreve("\fAcerte o dia\ndo Mes:");
while(muda);
}
}
while(!fica)////dia do mes
{
if(mais)
{
date++;
if(month==(1 || 3 || 5 || 7 || 8 || 10 || 12))//mes de 31 dias
{
if(date>31) date=1;
}
if(month==(4 || 6 || 9 || 11))//mes de 30 dias
{
if(date>30) date=1;
}
if(month==2 && bisexto==1)//mes de fevereiro com 29dias
{
if(date>29) date=1;
}
if(month==2 && bisexto==0)//mes de fevereiro com 28dias
{
if(date>28) date=1;
}
printf(lcd_escreve,"\fAcerte o dia:\n %u/%u/%u",date,month,year);
while(mais);
}
if(menos)
{
date--;
if(month==(1 || 3 || 5 || 7 || 8 || 10 || 12))//mes de 31 dias
{
if(date==0) date=31;
}
if(month==(4 || 6 || 9 || 11))//mes de 30 dias
{
if(date==0) date=30;
}
if(month==2 && bisexto==1)//mes de fevereiro com 29dias
{
if(date==0) date=29;
}
if(month==2 && bisexto==0)//mes de fevereiro com 28dias
{
if(date==0) date=28;
}
printf(lcd_escreve,"\fAcerte o dia:\n %u/%u/%u",date,month,year);
while(menos);
}
if(muda)
{
fica=!fica;
lcd_escreve("\fAcerte o dia\nda Semana:");
while(muda);
}
}
while(fica)////dia da semana
{
if(mais)
{
day++;
if(day>7) day=1;
printf(lcd_escreve,"\fHoje é %s.",dia_semana_converte(day));
while(mais);
}
if(menos)
{
day--;
if(day==0) day=7;
printf(lcd_escreve,"\fHoje é %s.",dia_semana_converte(day));
while(menos);
}
if(muda)
{
fica=!fica;
lcd_escreve("\fPressione ok/nppara salvar:");
while(muda);
}
}
while(!fica)
{
if(muda)
{
fica=!fica;
while(muda);
}
if(ok)
{
ds1307_set_date_time(date,month,year,day,hours,minutes,0);
lcd_escreve("\fSalvo");
while(ok);
}
}

}
}



void main()
{
lcd_ini();
while(1)
{
a:
lcd_escreve("\f Le tempo/data\n Conf. tempo");
while(!entra)
{
if(seleciona_menu)
{
lcd_pos_xy(0,0);
lcd_escreve("a");
while(!entra && seleciona_menu)
{
if(ok)
{
//lcd_escreve("\fentrou");
delay_ms(1000);
entra=1;
fica=1;
while(ok);
configura_tempo();
}
if(mais || menos)
{
seleciona_menu=!seleciona_menu;
while(mais || menos);
}
}
}

if(!seleciona_menu)
{
lcd_pos_xy(0,1);
lcd_escreve("a");
while(!entra && !seleciona_menu)
{
if(ok)
{
//lcd_escreve("\fentrou");
delay_ms(1000);
while(ok);
ds1307_get_date(date,month,year,day);
printf(lcd_escreve,"\f%u/%u/%u\n%s",date,month,year,dia_semana_converte(day));
delay_ms(1000);
ds1307_get_time(hours,minutes,seconds);
printf(lcd_escreve,"\f%u:%u:%u",hours,minutes,seconds);
delay_ms(1000);
goto a;
}
if(mais || menos)
{
seleciona_menu=!seleciona_menu;
while(mais || menos);
}
}
}
}
}
}

A biblioteca do lcd:

/************************************************************************/
/* MOD_LCD.C - Biblioteca de manipula??o de m?dulo LCD */
/* */
/* Autor: F?bio Pereira */
/* */
/************************************************************************/

// As defini??es a seguir s?o utilizadas para acesso aos pinos do display
// caso o pino RW n?o seja utilizado, comente a defini??o lcd_rw
#ifndef lcd_enable
#define lcd_enable pin_b6 // pino enable do LCD
#define lcd_rs pin_b7 // pino rs do LCD
//#define lcd_rw pin_e2 // pino rw do LCD
#define lcd_d4 pin_b2 // pino de dados d4 do LCD
#define lcd_d5 pin_b3 // pino de dados d5 do LCD
#define lcd_d6 pin_b5 // pino de dados d6 do LCD
#define lcd_d7 pin_b4 // pino de dados d7 do LCD
#endif

#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 linhas
#define lcd_seg_lin 0x40 // Endere?o da segunda linha na RAM do LCD

// a constante abaixo define a seq??ncia de inicializa??o do m?dulo LCD
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};

byte lcd_le_byte()
// l? um byte do LCD (somente com pino RW)
{
byte dado;
// configura os pinos de dados como entradas
input(lcd_d4);
input(lcd_d5);
input(lcd_d6);
input(lcd_d7);
// se o pino rw for utilizado, coloca em 1
#ifdef lcd_rw
output_high(lcd_rw);
#endif
output_high(lcd_enable); // habilita display
dado = 0; // zera a vari?vel de leitura
// l? os quatro bits mais significativos
if (input(lcd_d7)) bit_set(dado,7);
if (input(lcd_d6)) bit_set(dado,6);
if (input(lcd_d5)) bit_set(dado,5);
if (input(lcd_d4)) bit_set(dado,4);
// d? um pulso na linha enable
output_low(lcd_enable);
output_high(lcd_enable);
// l? os quatro bits menos significativos
if (input(lcd_d7)) bit_set(dado,3);
if (input(lcd_d6)) bit_set(dado,2);
if (input(lcd_d5)) bit_set(dado,1);
if (input(lcd_d4)) bit_set(dado,0);
output_low(lcd_enable); // desabilita o display
return dado; // retorna o byte lido
}

void lcd_envia_nibble( byte dado )
// envia um dado de quatro bits para o display
{
// coloca os quatro bits nas saidas
output_bit(lcd_d4,bit_test(dado,0));
output_bit(lcd_d5,bit_test(dado,1));
output_bit(lcd_d6,bit_test(dado,2));
output_bit(lcd_d7,bit_test(dado,3));
// d? um pulso na linha enable
output_high(lcd_enable);
output_low(lcd_enable);
}


void lcd_envia_byte( boolean endereco, byte dado )
{
// coloca a linha rs em 0
output_low(lcd_rs);
// aguarda o display ficar desocupado
//while ( bit_test(lcd_le_byte(),7) ) ;
// configura a linha rs dependendo do modo selecionado
output_bit(lcd_rs,endereco);
delay_us(100); // aguarda 100 us
// caso a linha rw esteja definida, coloca em 0
#ifdef lcd_rw
output_low(lcd_rw);
#endif
// desativa linha enable
output_low(lcd_enable);
// envia a primeira parte do byte
lcd_envia_nibble(dado >> 4);
// envia a segunda parte do byte
lcd_envia_nibble(dado & 0x0f);
}


void lcd_ini()
// rotina de inicializa??o do display
{
byte conta;
output_low(lcd_d4);
output_low(lcd_d5);
output_low(lcd_d6);
output_low(lcd_d7);
output_low(lcd_rs);
#ifdef lcd_rw
output_high(lcd_rw);
#endif
output_low(lcd_enable);
delay_ms(15);
// envia uma seq??ncia de 3 vezes 0x03
// e depois 0x02 para configurar o m?dulo
// para modo de 4 bits
for(conta=1;conta<=3;++conta)
{
lcd_envia_nibble(3);
delay_ms(5);
}
lcd_envia_nibble(2);
// envia string de inicializa??o do display
for(conta=0;conta<=3;++conta) lcd_envia_byte(0,INI_LCD[conta]);
}

void lcd_pos_xy( byte x, byte y)
{
byte endereco;
if(y!=1)
endereco = lcd_seg_lin;
else
endereco = 0;
endereco += x-1;
lcd_envia_byte(0,0x80|endereco);
}

void lcd_escreve( char c)
// envia caractere para o display
{
switch (c)
{
case '\f' : lcd_envia_byte(0,1);
delay_ms(2);
break;
case '\n' :
case '\r' : lcd_pos_xy(1,2);
break;
case '\b' : lcd_envia_byte(0,0x10);
break;
default : lcd_envia_byte(1,c);
break;
}
}

char lcd_le( byte x, byte y)
// le caractere do display
{
char valor;
// seleciona a posi??o do caractere
lcd_pos_xy(x,y);
// ativa rs
output_high(lcd_rs);
// l? o caractere
valor = lcd_le_byte();
// desativa rs
output_low(lcd_rs);
// retorna o valor do caractere
return valor;
}

A biblioteca do RTCDS1307:

////////////////////////////////////////////////////////////////////////////////
/// DS1307.C ///
/// Driver for Real Time Clock ///
/// ///
/// ds1307_init() - Enable oscillator without clearing the seconds register ///
/// used when PIC loses power and DS1307 run from 3V BAT ///
/// - Disable squarewave output ///
/// ///
/// ds1307_set_date_time(dia,mes,ano,dow,hora,mim,seg) Set the date/time ///
/// ///
/// ds1307_get_date(dia,mes,ano,dow) Obter data ///
/// ///
/// ds1307_get_time(hora,mim,seg) Obter tempo ///
/// ///
////////////////////////////////////////////////////////////////////////////////

#define RTC_SDA PIN_b0
#define RTC_SCL PIN_b1

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

BYTE seg;
BYTE mim;
BYTE hora;
BYTE dow;
BYTE dia;
BYTE mes;
BYTE ano;

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
BYTE segundos = 0;

i2c_start();
i2c_write(0xD0); // WR to RTC
//delay_us(3);
i2c_write(0x00); // REG 0
//delay_us(3);
i2c_stop();
//delay_us(3);
i2c_start();
i2c_write(0xD1); // RD from RTC
//delay_us(3);
segundos = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
delay_us(3);
i2c_stop();
segundos &= 0x7F;

delay_us(3);

i2c_start();
i2c_write(0xD0); // WR to RTC
//delay_us(3);
i2c_write(0x00); // REG 0
//delay_us(3);
i2c_write(bin2bcd(segundos)); // Start oscillator with current "seconds value
//delay_us(3);
i2c_stop();
i2c_start();
i2c_write(0xD0); // WR to RTC
//delay_us(3);
i2c_write(0x07); // Control Register
//delay_us(3);
i2c_write(0x80); // Disable squarewave output pin
//delay_us(3);
i2c_stop();

}

void ds1307_set_date_time(BYTE dia, BYTE mes, BYTE ano, BYTE dow, BYTE hora, BYTE mim, BYTE seg)
{
seg &= 0x7F;
hora &= 0x3F;

i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_write(bin2bcd(seg)); // REG 0
i2c_write(bin2bcd(mim)); // REG 1
i2c_write(bin2bcd(hora)); // REG 2
i2c_write(bin2bcd(dow)); // REG 3
i2c_write(bin2bcd(dia)); // REG 4
i2c_write(bin2bcd(mes)); // REG 5
i2c_write(bin2bcd(ano)); // REG 6
i2c_write(0x80); // REG 7 - Disable squarewave output pin
i2c_stop();
}

void ds1307_get_date(BYTE *dia, BYTE *mes, BYTE *ano, BYTE *dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03); // Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
*dow = bcd2bin(i2c_read() & 0x7f); // REG 3
*dia = bcd2bin(i2c_read() & 0x3f); // REG 4
*mes = bcd2bin(i2c_read() & 0x1f); // REG 5
*ano = bcd2bin(i2c_read(0)); // REG 6
i2c_stop();
}

void ds1307_get_time(BYTE *hora, BYTE *mim, BYTE *seg)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
*seg = bcd2bin(i2c_read() & 0x7f);
*mim = bcd2bin(i2c_read() & 0x7f);
*hora = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;

temp = binary_value;
retval = 0;

while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}

return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;

temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;

// Now return: (Tens * 8) + (Tens * 2) + Ones

return(temp + (temp >> 2) + (bcd_value & 0x0f));
}

Também tenho o ccto de simulação no Proteus

esquemamg.png

Só que não sei como colocar o esquema funcionando aqui no fórum.

Conto com a ajuda de vocês.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa. Estou trabalhando com o mesmo RTC a algum tempo já só que com o PIC32. Fiz uma biblioteca pra usar ele e uma pra I2C. Adapte o codigo para o 18F que deve funcionar. Boa sorte no projeto.

/*******************************************************************

*******************************************************************/

#define I_ACKDT I2C1CONbits.ACKDT

#define I_ACKEN I2C1CONbits.ACKEN

#define I_RCEN I2C1CONbits.RCEN

#define I_PEN I2C1CONbits.PEN

#define I_RSEN I2C1CONbits.RSEN

#define I_SEN I2C1CONbits.SEN

#define I_ACKSTAT I2C1STATbits.ACKSTAT

#define I_TRSTAT I2C1STATbits.TRSTAT

#define itx I2C1TRN

#define irx I2C1RCV

#define I_LIMIT 10

#define I_WR 0

#define I_RD 1

#define I_ACK 0

#define I_NACK 1

void iStart(void)

{

I_SEN=1;

while( I_SEN );

}

void iRestart(void)

{

I_RSEN=1;

while( I_RSEN );

}

void iStop(void)

{

I_PEN=1;

while( I_PEN );

}

BOOL iWriteByte(unsigned char iWbyte)

{

while( I_TRSTAT );

itx = iWbyte;

while( I_TRSTAT );

if( I_ACKSTAT )

return 0;

else

return 1;

}

unsigned char iWrite(unsigned char iWslave,unsigned char iWaddr, unsigned char *iWbuf, unsigned char iWtam)

{

unsigned char iWerr;

iStart();

if( iWriteByte(iWslave) )

{

if( iWriteByte(iWaddr) )

{

iWerr=0x00;

for( ; iWtam; iWtam-- )

{

if( !iWriteByte( *iWbuf ) )

iWerr = 0x09;

iWbuf++;

}

}

else

iWerr = 0x05; //não setou endereço inicial

}

else

iWerr = 0x03; //nao encontrou slave

iStop();

return iWerr;

}

unsigned char iReadByte(BOOL iRack)

{

I_ACKDT = iRack;

while( I_RCEN );

I_RCEN=1;

while( I_RCEN );

I_ACKEN=1;

while( I_ACKEN );

return irx;

}

unsigned char iRead(unsigned char iRslave, unsigned char iRaddr, unsigned char *iRbuf, unsigned char iRtam)

{

unsigned char iRerr;

iStart();

if( iWriteByte(iRslave) )

{

if( iWriteByte(iRaddr) )

{

iRestart();

if( iWriteByte(iRslave|I_RD) )

{

iRerr=0x00;

for(;iRtam;iRtam--)

{

if( iRtam>1)

*iRbuf = iReadByte(I_ACK);

else

*iRbuf = iReadByte(I_NACK);

iRbuf++;

}

}

else

iRerr=0x11;

}

else

iRerr=0x05;

}

else

iRerr=0x03;

iStop();

return iRerr;

}

/*******************************************************************

*******************************************************************/

/*

***** I2C slave address

*/

#define RTC_ADDRESS 0xD0

/*

***** Register Map

*/

#define RTC_SECONDS 0x00

#define RTC_CH 0x80

#define RTC_MINUTES 0x01

#define RTC_HOURS 0x02

#define RTC_12_24 0x40

#define RTC_AM_PM 0x20

#define RTC_DAY 0x03

#define RTC_DATE 0x04

#define RTC_MONTH 0x05

#define RTC_YEAR 0x06

#define RTC_CONTROL 0x07

#define RTC_OUT 0x80

#define RTC_SQWE 0x10

#define RTC_RS1 0x02

#define RTC_RS0 0x01

/*

***** System Config Options

*/

#define RTC_MODE_12 0x40

#define RTC_MODE_24 0x00

#define RTC_OUT_CLOCK 0x10

#define RTC_OUT_FIXED 0x00

#define RTC_LEVEL_HIGH 0x80

#define RTC_LEVEL_LOW 0x00

#define RTC_FREQ_1 0x00

#define RTC_FREQ_4096 0x01

#define RTC_FREQ_8192 0x02

#define RTC_FREQ_32768 0x03

/*

***** Desfault System Config

*/

#define RTC_MODE RTC_MODE_24

#define RTC_OUT_MODE RTC_OUT_CLOCK

#define RTC_LEVEL RTC_LEVEL_HIGH

#define RTC_FREQ RTC_FREQ_1

/*

***** Data Struct

*/

typedef struct

{

BOOL CH;

BOOL MODE;

BOOL AM_PM;

unsigned char second;

unsigned char minute;

unsigned char hour;

unsigned char day;

unsigned char date;

unsigned char month;

unsigned char year;

}RTC_DATA;

/*

***** Converts a BCD byte into a DEC

*/

unsigned char BCDtoDEC(unsigned char valBCD)

{

unsigned char valDEC;

valDEC = (valBCD&0x0F);

valDEC += (((valBCD&0xF0)>>4)*10);

return valDEC;

}

/*

***** Converts a DEC byte into a BCD

*/

unsigned char DECtoBCD(unsigned char valDEC)

{

//valDEC = valDEC%100;

return( ((valDEC/10)<<4) | (valDEC%10) );

}

/*

***** Config RTC

*/

unsigned char RTCConfig( unsigned char RTCCconfig )

{

return iWrite( RTC_ADDRESS, RTC_CONTROL, &RTCCconfig, 1 );

}

/*

***** Reset RTC

*/

unsigned char RTCReset(void)

{

#if RTC_OUT_MODE==RTC_OUT_CLOCK

unsigned char RTCRbuf[8]={0,0,RTC_MODE,0,0,0,0,RTC_OUT_MODE|RTC_FREQ};

#elif RTC_OUT_MODE==RTC_OUT_FIXED

unsigned char RTCRbuf[8]={0,0,RTC_MODE,0,0,0,0,RTC_OUT_MODE|RTC_LEVEL};

#endif

return iWrite( RTC_ADDRESS, RTC_SECONDS, RTCRbuf, 8 );

}

/*

***** Get RTC Calendar

*/

unsigned char RTCGetCalendar( RTC_DATA * RTCGCdata )

{

unsigned char RTCGCreturn, RTCGCbuf[7];

RTCGCreturn = iRead( RTC_ADDRESS, RTC_SECONDS, RTCGCbuf, 7 );

if( !RTCGCreturn )

{

RTCGCdata->CH = !!(RTCGCbuf[0]&RTC_CH);

if( RTCGCdata->CH )

{

RTCGCdata->MODE = 0;

RTCGCdata->AM_PM = 0;

RTCGCdata->second = 0;

RTCGCdata->minute = 0;

RTCGCdata->hour = 0;

RTCGCdata->day = 0;

RTCGCdata->date = 0;

RTCGCdata->month = 0;

RTCGCdata->year = 0;

}

else

{

RTCGCdata->second = BCDtoDEC( RTCGCbuf[0]&0x7F );

RTCGCdata->minute = BCDtoDEC( RTCGCbuf[1]&0x7F );

RTCGCdata->MODE = !!( RTCGCbuf[2]&RTC_12_24 );

if( RTCGCdata->MODE == 1 )

{//12 hr mode

RTCGCdata->AM_PM = !!( RTCGCbuf[2]&RTC_AM_PM );

RTCGCdata->hour = BCDtoDEC( RTCGCbuf[2]&0x1F );

}

else

{//24 hr mode

RTCGCdata->AM_PM = 0;

RTCGCdata->hour = BCDtoDEC( RTCGCbuf[2]&0x3F );

}

RTCGCdata->day = BCDtoDEC( RTCGCbuf[3]&0x07 );

RTCGCdata->date = BCDtoDEC( RTCGCbuf[4]&0x3F );

RTCGCdata->month = BCDtoDEC( RTCGCbuf[5]&0x1F );

RTCGCdata->year = BCDtoDEC( RTCGCbuf[6] );

}

}

return RTCGCreturn;

}

/*

***** Set RTC Calendar

*/

unsigned char RTCSetCalendar( RTC_DATA * RTCSCdata )

{

unsigned char RTCSCbuf[7];

RTCSCbuf[0] = DECtoBCD( RTCSCdata->second );

RTCSCbuf[1] = DECtoBCD( RTCSCdata->minute );

if( RTCSCdata->MODE == 1 )

{//12 hr mode

RTCSCbuf[2] = DECtoBCD( RTCSCdata->hour );

RTCSCbuf[2] |= RTC_12_24;

RTCSCbuf[2] |= (RTCSCdata->AM_PM<<5);

}

else

{//24 hr mode

RTCSCbuf[2] = DECtoBCD( RTCSCdata->hour );

}

RTCSCbuf[3] = DECtoBCD( RTCSCdata->day );

RTCSCbuf[4] = DECtoBCD( RTCSCdata->date );

RTCSCbuf[5] = DECtoBCD( RTCSCdata->month );

RTCSCbuf[6] = DECtoBCD( RTCSCdata->year );

return iWrite( RTC_ADDRESS, RTC_SECONDS, RTCSCbuf, 7 );

}

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • Autor do tópico
  • Beleza edu.

    Parabens cara, fazer uma biblioteca num é pra qualquer um!

    Não querendo abusar, Será que não tem como você postar um exemplo de uso das suas bibliotecas ai não?

    Ou se possível você dar uma olhada no meu código pra ver onde está errado. Como eu disse, só não estou conseguindo ler o RTC (consegui até que consigo, mas só leio zeros), as vezes é uma coisa boba, mas para um leigo no assunto como eu, passa despercebido, entende.

    Se der pra você conferir meu código, eu te passo o esquema de simulação no Proteus.

    Agradeço a atenção. :)

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Boa tarde pessoal,

    Vou explicar melhor meu problema a vocês: Quando vou ler o RTC, só consigo ler zeros, e não os dados; as funções que efetuam a leitura são as seguintes:

    void ds1307_get_date(BYTE *dia, BYTE *mes, BYTE *ano, BYTE *dow)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x03); // Start at REG 3 - Day of week
    i2c_start();
    i2c_write(0xD1);
    *dow = bcd2bin(i2c_read() & 0x7f); // REG 3
    *dia = bcd2bin(i2c_read() & 0x3f); // REG 4
    *mes = bcd2bin(i2c_read() & 0x1f); // REG 5
    *ano = bcd2bin(i2c_read(0)); // REG 6
    i2c_stop();
    }

    void ds1307_get_time(BYTE *hora, BYTE *mim, BYTE *seg)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x00); // Start at REG 0 - Seconds
    i2c_start();
    i2c_write(0xD1);
    *seg = bcd2bin(i2c_read() & 0x7f);
    *mim = bcd2bin(i2c_read() & 0x7f);
    *hora = bcd2bin(i2c_read(0) & 0x3f);
    i2c_stop();

    }

    Em que as variáveis que uso para retornar os valores são todas inteiras de 8 bits e mostro através da função printf.

    No geral, meu código fica assim para ler a data:

    ds1307_get_date(date,month,year,day);//função que lê a data.
    printf(lcd_escreve,"\f%u/%u/%u\n%s",date,month,year,dia_semana_converte(day));//mostro os valores da data no display

    E assim para ler as horas:

    ds1307_get_time(hours,minutes,seconds);//função que lê as horas
    printf(lcd_escreve,"\f%u:%u:%u",hours,minutes,seconds);mostra as horas no display

    conto com a ajuda de vocês!

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Eaii irmão,

    Tava vendo seu esquemático, que valores de resistores de pullup do SDA e SCL você ta colocando na hora de monta no protoboard? parece ser de 10k no esquemático. O datasheet do RTC não sugere um valor para estes resistores de pullup (Rpu), porém lembro que quando montei tive problemas com 10k de pullup, as vezes os valores lidos davam umas loucuras e voltavam ao normal. Testei com 4k7 e 5k6, ambos funcionaram sem problemas. ( deixava o RTC funcionando dias). Adotei como padrão de pullup para tensão de 5V 4k7 e 5k6.

    Outra coisa importante é você garantir o tempo mínimo de transmissão dos dados especificado no datasheet (datasheet Maxim DALLAS - AC Electrical Characteristics pg.3) o proteus muitas das vezes ignora estas especificações. Como está usando i²C em Hardware ( #use i2c ) coloque na diretiva a especificação da frequencia. talvez ela esteja muito alta como está usando um cristal em Mhz ( fmax do rtc = 100 khz )

    tente colocar:

    #use i2c(master, sda=RTC_SDA, scl=RTC_SCL, FAST = 100000) // frequencia em 100khz

    Abraço!!!

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Valeu rafael.luc pela dica, mas pena que já tinha visitado essa página, foi de uma página desse tipo que tive a ideia de usar o RTC que antes eu nem conhecia.

    Ao AlyssonMachado, os resistores eram de 10K mesmo, mudei aqui para 4K7 e depois para 5K6 e não funcionou, mudei também a frequencia como você pediu, mas também não funcionou; Só não montei no protoboard ainda porque tô esperando os componentes chegarem. sei que não dá pra confiar só no Proteus, mas era pra pelo menos dar algum sinal, você não acha, pois para gravar dá certo; ou será que é falha do Proteus, porque se for, aí que não confio nele mesmo!

    Ah, outra coisa, você viu a função de ler o rtc? Minha desconfiança maior é nela, será que a conversão que é feita na função está correta? não entendi direito essa conversão. Afinal, ela converte de qual código BCD?

    Tomara que os componentes cheguem esse fim-de-semana que aí testo tudo na prática.

    Obrigado!!!

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • ou Alysson, Beleza!

    Meus componentes chegaram ontem.

    Ai montei no protoboard mas não funciona o danado do circuito. tá igual no proteus. So que não dá pra ver se gravou no rtc. Do mesmo jeito que funciona as funções no proteus também funciona no protoboard, só leio zeros!

    Tá osso fazer isso funcionar. Será o que que é em...

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Dê uma olhada nesse tópico:

    Relogio com ds1307, termometro com lm35, display lcd, e pic 16f877a

    Uma vez que você tem o relógio funcionando, fica fácil selecionar o horário de acionar as saídas.

    E o código é portável para o PIC18f452.

    Falou

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Boa tarde galera!

    Estava comparando a biblioteca que tenho aqui com a que o MatheusLPS falou pra mim dar uma olhada e reparei as seguintes diferenças:

    Minha biblioteca:


    #define RTC_SDA PIN_C4
    #define RTC_SCL PIN_C3

    #use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

    A outra biblioteca:


    #define RTC_SDA PIN_b2
    #define RTC_SCL PIN_b1

    #use i2c(master, sda=RTC_SDA, scl=RTC_SCL, fast = 100000)
    #use i2c(sda=PIN_b2, scl=PIN_b1, stream=I2C_HW)

    e também essas funções na minha:


    void ds1307_get_date(BYTE *dia, BYTE *mes, BYTE *ano, BYTE *dow)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x03); // Start at REG 3 - Day of week
    i2c_start();
    i2c_write(0xD1);
    *dow = bcd2bin(i2c_read() & 0x7f); // REG 3
    *dia = bcd2bin(i2c_read() & 0x3f); // REG 4
    *mes = bcd2bin(i2c_read() & 0x1f); // REG 5
    *ano = bcd2bin(i2c_read(0)); // REG 6
    i2c_stop();
    }

    void ds1307_get_time(BYTE *hora, BYTE *mim, BYTE *seg)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x00); // Start at REG 0 - Seconds
    i2c_start();
    i2c_write(0xD1);
    *seg = bcd2bin(i2c_read() & 0x7f);
    *mim = bcd2bin(i2c_read() & 0x7f);
    *hora = bcd2bin(i2c_read(0) & 0x3f);
    i2c_stop();

    }

    pra outra:


    void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x03); // Start at REG 3 - Day of week
    i2c_start();
    i2c_write(0xD1);
    dow = bcd2bin(i2c_read() & 0x7f); // REG 3
    day = bcd2bin(i2c_read() & 0x3f); // REG 4
    mth = bcd2bin(i2c_read() & 0x1f); // REG 5
    year = bcd2bin(i2c_read(0)); // REG 6
    i2c_stop();
    }

    void ds1307_get_time(BYTE &hr, BYTE &mim, BYTE &sec)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x00); // Start at REG 0 - Seconds
    i2c_start();
    i2c_write(0xD1);
    sec = bcd2bin(i2c_read() & 0x7f);
    mim = bcd2bin(i2c_read() & 0x7f);
    hr = bcd2bin(i2c_read() & 0x3f);
    i2c_stop();

    }

    feito do jeito da segunda, consegui ler os valores do rtc diferentes de zero (:aplausos:viva!!!).

    Só que não estou conseguindo ler a data corretamente:

    quando gravo 00/00/00 - 0 (dia/mes/ano - dia da semana) e depois leio, aparece:00/10/-9. outro ex.:

    quando gravo 05/05/05 - 05 (dia/mes/ano - dia da semana) e depois leio, é mostrado no display: 05/10/-9.

    Parece que apenas o dia é mostrado corretamente, mas o ano e o mês aparece diferente.

    Também estava pensando em colocar a saída sqw/out oscilando em um Hertz, que aí por meio de interrupção externa atualizo o display.

    Vi na seguinte função que esse pino é configurado para não oscilar:


    void ds1307_init(void)
    {
    BYTE seconds = 0;

    i2c_start();
    i2c_write(0xD0); // WR to RTC
    i2c_write(0x00); // REG 0
    i2c_start();
    i2c_write(0xD1); // RD from RTC
    seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
    i2c_stop();
    seconds &= 0x7F;

    delay_us(3);

    i2c_start();
    i2c_write(0xD0); // WR to RTC
    i2c_write(0x00); // REG 0
    i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value
    i2c_start();
    i2c_write(0xD0); // WR to RTC
    i2c_write(0x07); // Control Register
    i2c_write(0x10); // Disable squarewave output pin [COLOR="Red"]aqui desliga a saída [/COLOR]
    i2c_stop();

    }

    O que devo colocar pra acionar a saída sqw/out em 1Hz?

    Não entendi nem de onde que veio esse 0x10...

    Estava fazendo os testes com o PIC16F877A no Proteus e no protoboard, só que minha programação ficou meio grande e vou ter que passar pro PIC18F452.

    Vou trocar o microcontrolador do esquema no proteus pra testar lá também.

    Valeu Matheus pela força, Agora tá quase!!!

    Abs.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Pessoal, bom dia!

    Agora acho que entendi o 0x10 que destaquei acima: ele que é o byte gravado no registrador de controle, e convertido para binário dá 0b00010000. Setando apenas o bit4(SQWE).

    O engraçado é que apenas o bit 4 setado configura a saida ativada e com o clock em 1Hz (pelo menos foi o que entendi).

    Mas mesmo desse jeito a saída não está ativada. O que será que é então?

    Estou testando no Proteus e no protoboard e tá do mesmo jeito.

    Vou dar uma organizada aqui no meu novo código pra te mostrarem.

    Da uma força aí galera, porque sou iniciante em programação e tô aprendendo sozinho.

    Até +!

    Galera, desisti do meu código depois de ficar o final de semana inteiro procurando o entender o porque de não estar conseguindo ler a data corretamente.

    Decidi então alterar o código que o Matheus me mostrou para minha aplicação e nada, mas deu pra perceber que o problema está na leitura do da data(antes desconfiava de ser algum bug no meu código).

    Além de ficar menor, o programa já aciona a saída SQWE, que através dela atualizo o tempo no display.

    Agora tô precisando de uma força é para acertar a leitura da data.

    Segue meu novo código fonte:


    #include"18F452.h"

    #FUSES NOWDT //No Watch Dog Timer
    #FUSES HS //Clock >4Mhz
    #FUSES PUT //Power Up Timer
    #FUSES NOPROTECT //Code not protected from reading
    #FUSES NOBROWNOUT //No brownout reset
    #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
    #FUSES NOCPD //No EE protection

    #use delay(clock=12M)

    #include"ds1307.c"
    #include"lcd.c"

    #define botao_incremento PIN_A0
    #define botao_decremento PIN_A1
    #define troca_modo PIN_A2

    BYTE sec;
    BYTE mim;
    BYTE hrs;
    BYTE day;
    BYTE month;
    BYTE yr;
    BYTE dow;

    int8 modo;
    //int16 adc;
    //float temperatura;

    char dia_da_semana[7][8]=
    {
    "DOMINGO",
    "SEGUNDA",
    "TERCA",
    "QUARTA",
    "QUINTA",
    "SEXTA",
    "sábado",
    };

    #int_ext
    void trata_ext()
    {
    ds1307_get_date(day,month,yr,dow);
    ds1307_get_time(hrs,mim,sec);
    delay_ms(50);
    printf(lcd_escreve,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d ",dia_da_semana[dow-1],hrs,mim,sec,day,month,yr);
    delay_ms(50);
    }


    void main()
    {

    enable_interrupts (global | int_ext);
    ds1307_init();
    lcd_ini();
    ds1307_get_date(day,month,yr,dow);
    ds1307_get_time(hrs,mim,sec);
    delay_ms(50);
    printf(lcd_escreve,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d ",dia_da_semana[dow-1],hrs,mim,sec,day,month,yr);
    delay_ms(5000);
    modo = 0;

    while(1)
    {
    switch (modo)
    {
    case 1:
    {
    if (input(BOTAO_INCREMENTO))
    {
    delay_ms (75);
    yr++;
    }

    if (input(BOTAO_DECREMENTO))
    {
    delay_ms (75);
    yr--;
    }

    if (yr > 99 )
    {
    yr = 1;
    }

    if (yr == 0 )
    {
    yr = 99;
    }
    if(input(TROCA_MODO))
    {
    modo++;
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    printf(lcd_escreve,"\fAjustar Ano:\n%u",yr);
    delay_ms (100);
    break;

    }

    case 2:
    {
    if (input(BOTAO_INCREMENTO))
    {
    delay_ms (75);
    month++;
    }

    if (input(BOTAO_DECREMENTO))
    {
    delay_ms (75);
    month--;
    }

    if (month > 12 )
    {
    month = 1;
    }

    if (month == 0 )
    {
    month = 12;
    }
    if(input(TROCA_MODO))
    {
    modo++;
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    printf(lcd_escreve,"\fAjustar Mes:\n%u",month);
    delay_ms (100);
    break;

    }

    case 3:
    {
    if (input(BOTAO_INCREMENTO))
    {
    delay_ms (75);
    day++;
    }

    if (input(BOTAO_DECREMENTO))
    {
    delay_ms (75);
    day--;
    }

    if (day > 31 )
    {
    day = 1;
    }

    if (day == 0 )
    {
    day = 31;
    }
    if(input(TROCA_MODO))
    {
    modo++;
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    printf(lcd_escreve,"\fDia do Mes:\n%u",day);
    delay_ms (100);
    break;

    }

    case 4:
    {
    if (input(BOTAO_INCREMENTO))
    {
    delay_ms (75);
    dow++;
    }

    if (input(BOTAO_DECREMENTO))
    {
    delay_ms (75);
    dow--;
    }

    if (dow > 7 )
    {
    dow = 1;
    }

    if (dow == 0)
    {
    dow = 7;
    }
    if(input(TROCA_MODO))
    {
    modo++;
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    printf(lcd_escreve,"\fDia da Semana:\n%s",dia_da_semana[dow-1]);
    delay_ms (100);
    break;
    }

    case 5:
    {
    if (input(BOTAO_INCREMENTO))
    {
    delay_ms (75);
    hrs++;
    }

    if (input(BOTAO_DECREMENTO))
    {
    delay_ms (75);
    hrs--;
    }

    if (hrs > 23 )
    {
    hrs = 0;
    }

    if (hrs == 255 )
    {
    hrs = 23;
    }
    if(input(TROCA_MODO))
    {
    modo++;
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    printf(lcd_escreve,"\fAjustar Hora:\n%u",hrs);
    delay_ms (100);
    break;

    }

    case 6:
    {
    if (input(BOTAO_INCREMENTO))
    {
    delay_ms (75);
    mim++;
    }

    if (input(BOTAO_DECREMENTO))
    {
    delay_ms (75);
    mim--;
    }

    if (mim > 59 )
    {
    mim = 0;
    }

    if (mim == 255 )
    {
    mim = 59;
    }
    if(input(TROCA_MODO))
    {
    modo++;
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    printf(lcd_escreve,"\fAjustar Minutos:\n%u",mim);
    delay_ms (100);
    break;
    }

    case 7:
    {
    if (input(BOTAO_INCREMENTO))
    {
    delay_ms (75);
    sec++;
    }

    if (input(BOTAO_DECREMENTO))
    {
    delay_ms (75);
    sec--;
    }

    if (sec > 59 )
    {
    sec = 0;
    }

    if (sec == 255 )
    {
    sec = 59;
    }
    if(input(TROCA_MODO))
    {
    modo++;
    ds1307_set_date_time(day,month,yr,dow,hrs,mim,sec);
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    printf(lcd_escreve,"\fAjustar Segundos:\n%u",sec);
    delay_ms (100);
    break;
    }

    default:
    {

    if(input(TROCA_MODO))
    {
    modo++;
    while(input(TROCA_MODO));
    if (modo > 7 )
    {
    modo = 0;
    }
    }
    }
    }
    }
    }

    E a nova biblioteca do RTC:


    ////////////////////////////////////////////////////////////////////////////////
    /// DS1307.C ///
    /// Driver for Real Time Clock ///
    /// ///
    /// ds1307_init() - Enable oscillator without clearing the seconds register -///
    /// used when PIC loses power and DS1307 run from 3V BAT ///
    /// - Disable squarewave output ///
    /// ///
    /// ds1307_set_date_time(day,mth,year,dow,hour,mim,sec) Set the date/time ///
    /// ///
    /// ds1307_get_date(day,mth,year,dow) Get the date ///
    /// ///
    /// ds1307_get_time(hr,mim,sec) Get the time ///
    /// ///
    ////////////////////////////////////////////////////////////////////////////////

    #define RTC_SDA PIN_B2
    #define RTC_SCL PIN_B1

    #use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
    #use i2c(sda=PIN_B2, scl=PIN_B1, stream=I2C_HW)

    BYTE bin2bcd(BYTE binary_value);
    BYTE bcd2bin(BYTE bcd_value);

    void ds1307_init(void)
    {
    BYTE seconds = 0;

    i2c_start();
    i2c_write(0xD0); // WR to RTC
    i2c_write(0x00); // REG 0
    i2c_start();
    i2c_write(0xD1); // RD from RTC
    seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
    i2c_stop();
    seconds &= 0x7F;

    delay_us(3);

    i2c_start();
    i2c_write(0xD0); // WR to RTC
    i2c_write(0x00); // REG 0
    i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value
    i2c_start();
    i2c_write(0xD0); // WR to RTC
    i2c_write(0x07); // Control Register
    i2c_write(0x10); // Disable squarewave output pin
    i2c_stop();

    }

    void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE mim, BYTE sec)
    {
    sec &= 0x7F;
    hr &= 0x3F;

    i2c_start();
    i2c_write(0xD0); // I2C write address
    i2c_write(0x00); // Start at REG 0 - Seconds
    i2c_write(bin2bcd(sec)); // REG 0
    i2c_write(bin2bcd(mim)); // REG 1
    i2c_write(bin2bcd(hr)); // REG 2
    i2c_write(bin2bcd(dow)); // REG 3
    i2c_write(bin2bcd(day)); // REG 4
    i2c_write(bin2bcd(mth)); // REG 5
    i2c_write(bin2bcd(year)); // REG 6
    i2c_write(0x10); // REG 7 - Disable squarewave output pin
    i2c_stop();
    }

    void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x03); // Start at REG 3 - Day of week
    i2c_start();
    i2c_write(0xD1);
    dow = bcd2bin(i2c_read() & 0x7f); // REG 3
    day = bcd2bin(i2c_read() & 0x3f); // REG 4
    mth = bcd2bin(i2c_read() & 0x1f); // REG 5
    year = bcd2bin(i2c_read(0)); // REG 6
    i2c_stop();
    }

    void ds1307_get_time(BYTE &hr, BYTE &mim, BYTE &sec)
    {
    i2c_start();
    i2c_write(0xD0);
    i2c_write(0x00); // Start at REG 0 - Seconds
    i2c_start();
    i2c_write(0xD1);
    sec = bcd2bin(i2c_read() & 0x7f);
    mim = bcd2bin(i2c_read() & 0x7f);
    hr = bcd2bin(i2c_read() & 0x3f);
    i2c_stop();

    }

    BYTE bin2bcd(BYTE binary_value)
    {
    BYTE temp;
    BYTE retval;

    temp = binary_value;
    retval = 0;

    while(1)
    {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
    temp -= 10;
    retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
    retval += temp;
    break;
    }
    }

    return(retval);
    }


    // Input range - 00 to 99.
    BYTE bcd2bin(BYTE bcd_value)
    {
    BYTE temp;

    temp = bcd_value;
    // Shifting upper digit right by 1 is same as multiplying by 8.
    temp >>= 1;
    // Isolate the bits for the upper digit.
    temp &= 0x78;

    // Now return: (Tens * 8) + (Tens * 2) + Ones

    return(temp + (temp >> 2) + (bcd_value & 0x0f));
    }

    Alguém tem alguma ideia?

    Editado por Bcpetronzio
    Unir Post seguidos em menos de 24 horas, use a opção editar

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Lembrando que a saida é em dreno aberto. Precisa de pull-up!!

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Obrigado Edu. pela observação; só que já estou usando os resistores de pull-up.

    O meu problema é de software mesmo, pois consigo gravar as horas e a data também, mas na hora de ler, só as horas que leio certo, a data mostra uns valores que não variam com o passar do tempo e diferente do que gravei. estou testando no protoboard e no proteus, e tá a mesma coisa. E no proteus mostra que a data no RTC fica diferente do que a que estou lendo.

    você num sabe o que é não?

    Meu código ta aí em cima, se der, dá uma olhada.

    Até +!

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    DavidsonrSouza, por que não utiliza o código do link que te passei?

    Nele já está imprementado a hora e a data.

    Só falta você implementar quando precisa ativar a saída.

    Falou

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Vamos com calma, nao tenho tempo pra ler todo o código mas com base nos sintomas vamos tentar algum medicamento ae ;]

    Você ja deu uma olhada no bit CH (clock halt), ele indica quando há alguma falha na contagem. Se nao me engano ele fica embutido com os segundos. Há outros bits que também estão anexos nos registradores e devem ser ignorados na hora de se fazer a leitura. Tens como postar o hardware atualizado? Vou dar uma lida no ultimo codigo que postastes e ver se encontro algo.

    EDIT 1:

    Cara não ta errado essa declaração dos ponteiros na função de leitura? Está sendo usado o & para criar o ponteiro quando o correto seria um *. Assim como no código para fazer menção ao conteúdo dos mesmo deve-se usar o * também. Não sou muito bom com o CCS, mas em qualquer compilador normal de C eu faria assim:

    void get_time( char *hr, char *min, char *seg)

    {

    *hr = ...;

    *min = ...;

    *seg = ...;

    }

    E no main chamaria desse modo:

    get_time( &mhr, &mmin, &mseg );

    Deste modo eu passo para a função o endereço do registrador e ela utiliza como um ponteiro. O CCS é cheio das maluquices e teria que saber mais a fundo como ele se comporta com relação aquele trecho mas no HI-TECH (normalmente uso) teria que utilizar os ponteiros da forma acima.

    EDIT 2:

    A função de conversão de BCD para decimal também me parece meio estranha. Aqueles shifts e tudo mais não me parecem certos. Teria que ver um modo mais claro de fazer a conversão. No codigo que postei acima tem ambas as logicas de conversão e é garantido.

    Editado por edu.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Pois é MatheusLPS, na resposta n°11 coloquei os códigos que estou usando, que foi o que você me passou com as modificações nescessárias, só que não entendo porque está tão difícil colocar essa programação toda pra funcionar; quando consigo ler a data, a hora sai errada e vice-versa. Ai depois de muito tempo consegui ler as duas corretamente desse jeito:

    Só que aí não tá dando pra gravar o danado do RTC!

    #int_ext
    void trata_ext()
    {
    teste=1;
    if(teste)
    {
    ds1307_get_time(horas,minutos,segundos);
    //delay_ms(50);
    ds1307_get_date(dia,mes,ano,semana);
    delay_ms(50);
    //printf(lcd_escreve,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d ",dia_da_semana[semana-1],horas,minutos,segundos,dia,mes,ano);
    }
    if(teste)
    {
    ds1307_get_date(day,month,yr,dow);
    ds1307_get_time(hrs,mim,sec);
    delay_ms(50);
    printf(lcd_escreve,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d ",dia_da_semana[dow-1],hrs,mim,sec,day,month,yr);
    }
    //printf(lcd_escreve,"\f%s %02d:\%02d:\%02d",dia_da_semana[dow],hrs,mim,sec);
    //delay_ms(50);
    //printf(lcd_escreve,"\n%02d/\%02d/\%02d ",day,month,yr);
    }

    Essa parte é uma interrupção externa no pino B0 de um PIC18F452, acionada pela própria saída SQWE do RTC.

    Note que pra conseguir ler a data e a hora corretamente, tive que ler duas vezes o RTC, gravando os valores em variáveis diferentes, pois só assim funcionou.

    E aquela variável "teste" foi só um teste que fiz antes de conseguir fazer funcionar, portanto, ignore-a.

    Se você quiser, te mando a programação com todas as bibliotecas que estou usando e o arquivo de simulação no Proteus.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Já tentou montar na bancada para ver se funciona sem precisar ler duas vezes?

    No link que te mostrou o user que solicitou o código disse que no proteus as vezes sai hora ou data errada.

    Vou se se compro um DS1307 aqui na minha cidade e tento montar na proto para testar...

    Falou

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Testei sim no protoboard, tá do mesmo jeito.

    O edu. falou que umas partes do código que estou usando tá meio estranho, só que antes eu tava usando mais ou menos do jeito que ele falou e não lia nada, só zeros.

    você tem alguma ideia do q pode ser???

    Agora como disse, consigo ler tudo, mas num grava nada.

    Isso tudo só funciona em partes, o problema é que tá difícil de entender o que tá acontecendo aqui.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Veja bem, você está desconsiderando um bit muito importante no RTC. O bit CH no registrador dos segundos informa se o valor dos demais registradores está correto ou errado. No seu programa, na parte de inicialização ele simplesmente lê os segundos e depois zera o bit e volta a escrever, desse modo, ele ignora se os valores são validos ou não. No meu programa você precisa verificar se esse bit está setado e então zerar ele, caso contrário a contagem não inicia e ele permanece no 0. Enquanto esse bit estiver em 1 não haverá contagem. Também tens de cuidar com o pino Vbat, ele não serve para carregar/descarregar a bateria, ele somente serve de entrada de alimentação. Se desejas que a bateria seja carregada para depois alimentar o RTC deves colocar um diodo e um resistor de uma fonte de 3V3 para que sempre que o circuito estiver alimentado carregar a bateria. Leia o datasheet atenciosamente e veja melhor o funcionamento do bit CH e depois reveja seu código. Vou procurar aqui o trecho de inicialização que utilizei na aplicação que desenvolvi com aquelas bibliotecas.

    EDIT:

    	//init rtc
    RTCGetCalendar( &calendario );
    if( calendario.CH )
    {
    RTCReset();
    }

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Boa noite edu.!

    estou tentando usar suas bibliotecas mais dá um monte de erros na hora de compilar. veja a imagem:

    outputd.jpg

    Tá faltando alguma outra biblioteca ou são só essas mesmas?

    Tem alguns erros do tipo:

    "Expecting a("

    que significa que está faltando fechar os parenteses, Posso fechá-los? Qual compilador você usa? aqui eu uso o CCS C (PCW).

    Vou ir tentando aqui, mas se você tiver um exemplo usando-as tem como postar?

    Vai dar uma clareada boa!

    Como eu disse, sou um leigo quando o assunto é programação e estou aprendendo agora.

    Outra coisa, eu uso os pinos RD1 para SCL e RD0 para SDA, como configuro esses pinos na sua biblioteca?

    Até mais!

    Ah, já ia me esquecendo de postar minha programação.

    Na resposta #16 você me pediu, então la vai:

    #include"18F452.h"

    #FUSES NOWDT //No Watch Dog Timer

    #FUSES HS //Clock >4Mhz

    #FUSES PUT //Power Up Timer

    #FUSES NOPROTECT //Code not protected from reading

    #FUSES NOBROWNOUT //No brownout reset

    #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

    #FUSES NOCPD //No EE protection

    #use delay(clock=12M)

    #include"ds1307.c"

    #include"lcd.c"

    #define botao_incremento PIN_A3

    #define botao_decremento PIN_A2

    #define troca_modo PIN_A1

    #define led_lcd pin_d6

    #define rele pin_c3

    #define buzzer pin_b5

    BYTE sec;

    BYTE mim;

    BYTE hrs;

    BYTE day;

    BYTE month;

    BYTE yr;

    BYTE dow;

    int segundos=0;

    int minutos=0;

    int horas=0;

    int dia=0;

    int mes=0;

    int ano=0;

    int semana=0;

    short teste=0;

    int8 modo;

    //int16 adc;

    //float temperatura;

    char dia_da_semana[7][8]=

    {

    "DOMINGO",

    "SEGUNDA",

    "TERCA",

    "QUARTA",

    "QUINTA",

    "SEXTA",

    "sábado",

    };

    #int_ext

    void trata_ext()

    {

    teste=1;

    if(teste)

    {

    ds1307_get_time(horas,minutos,segundos);

    //delay_ms(50);

    ds1307_get_date(dia,mes,ano,semana);

    delay_ms(50);

    //printf(lcd_escreve,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d ",dia_da_semana[semana-1],horas,minutos,segundos,dia,mes,ano);

    }

    if(teste)

    {

    ds1307_get_date(day,month,yr,dow);

    ds1307_get_time(hrs,mim,sec);

    delay_ms(50);

    printf(lcd_escreve,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d ",dia_da_semana[dow-1],hrs,mim,sec,day,month,yr);

    }

    //printf(lcd_escreve,"\f%s %02d:\%02d:\%02d",dia_da_semana[dow],hrs,mim,sec);

    //delay_ms(50);

    //printf(lcd_escreve,"\n%02d/\%02d/\%02d ",day,month,yr);

    }

    void main()

    {

    ds1307_init();

    lcd_ini();

    ds1307_get_date(day,month,yr,dow);

    ds1307_get_time(hrs,mim,sec);

    output_bit(buzzer,1);

    delay_ms(500);

    output_bit(led_lcd,1);

    output_bit(buzzer,0);

    printf(lcd_escreve,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d ",dia_da_semana[dow-1],hrs,mim,sec,dia,month,yr);

    delay_ms(5000);

    enable_interrupts(global | int_ext);

    modo = 0;

    while(1)

    {

    switch (modo)

    {

    case 1:

    {

    if (input(BOTAO_INCREMENTO))

    {

    delay_ms (75);

    yr++;

    }

    if (input(BOTAO_DECREMENTO))

    {

    delay_ms (75);

    yr--;

    }

    if (yr > 99 )

    {

    yr = 1;

    }

    if (yr == 0 )

    {

    yr = 99;

    }

    if(input(TROCA_MODO))

    {

    modo++;

    while(input(TROCA_MODO));

    if (modo > 7 )

    {

    modo = 0;

    }

    }

    printf(lcd_escreve,"\fAjustar Ano:\n%02d",yr);

    delay_ms (100);

    break;

    }

    case 2:

    {

    if (input(BOTAO_INCREMENTO))

    {

    delay_ms (75);

    month++;

    }

    if (input(BOTAO_DECREMENTO))

    {

    delay_ms (75);

    month--;

    }

    if (month > 12 )

    {

    month = 1;

    }

    if (month == 0 )

    {

    month = 12;

    }

    if(input(TROCA_MODO))

    {

    modo++;

    while(input(TROCA_MODO));

    if (modo > 7 )

    {

    modo = 0;

    }

    }

    printf(lcd_escreve,"\fAjustar Mes:\n%02d",month);

    delay_ms (100);

    break;

    }

    case 3:

    {

    if (input(BOTAO_INCREMENTO))

    {

    delay_ms (75);

    day++;

    }

    if (input(BOTAO_DECREMENTO))

    {

    delay_ms (75);

    day--;

    }

    if (day > 31 )

    {

    day = 1;

    }

    if (day == 0 )

    {

    day = 31;

    }

    if(input(TROCA_MODO))

    {

    modo++;

    while(input(TROCA_MODO));

    if (modo > 7 )

    {

    modo = 0;

    }

    }

    printf(lcd_escreve,"\fDia do Mes:\n%02d",day);

    delay_ms (100);

    break;

    }

    case 4:

    {

    if (input(BOTAO_INCREMENTO))

    {

    delay_ms (75);

    dow++;

    }

    if (input(BOTAO_DECREMENTO))

    {

    delay_ms (75);

    dow--;

    }

    if (dow > 7 )

    {

    dow = 1;

    }

    if (dow == 0)

    {

    dow = 7;

    }

    if(input(TROCA_MODO))

    {

    modo++;

    while(input(TROCA_MODO));

    if (modo > 7 )

    {

    modo = 0;

    }

    }

    printf(lcd_escreve,"\fDia da Semana:\n%s",dia_da_semana[dow-1]);

    delay_ms (100);

    break;

    }

    case 5:

    {

    if (input(BOTAO_INCREMENTO))

    {

    delay_ms (75);

    hrs++;

    }

    if (input(BOTAO_DECREMENTO))

    {

    delay_ms (75);

    hrs--;

    }

    if (hrs > 23 )

    {

    hrs = 0;

    }

    if (hrs == 255 )

    {

    hrs = 23;

    }

    if(input(TROCA_MODO))

    {

    modo++;

    while(input(TROCA_MODO));

    if (modo > 7 )

    {

    modo = 0;

    }

    }

    printf(lcd_escreve,"\fAjustar Hora:\n%02d",hrs);

    delay_ms (100);

    break;

    }

    case 6:

    {

    if (input(BOTAO_INCREMENTO))

    {

    delay_ms (75);

    mim++;

    }

    if (input(BOTAO_DECREMENTO))

    {

    delay_ms (75);

    mim--;

    }

    if (mim > 59 )

    {

    mim = 0;

    }

    if (mim == 255 )

    {

    mim = 59;

    }

    if(input(TROCA_MODO))

    {

    modo++;

    while(input(TROCA_MODO));

    if (modo > 7 )

    {

    modo = 0;

    }

    }

    printf(lcd_escreve,"\fAjustar Minutos:\n%02d",mim);

    delay_ms (100);

    break;

    }

    case 7:

    {

    if (input(BOTAO_INCREMENTO))

    {

    delay_ms (75);

    sec++;

    }

    if (input(BOTAO_DECREMENTO))

    {

    delay_ms (75);

    sec--;

    }

    if (sec > 59 )

    {

    sec = 0;

    }

    if (sec == 255 )

    {

    sec = 59;

    }

    if(input(TROCA_MODO))

    {

    modo++;

    ds1307_set_date_time(day,month,yr,dow,hrs,mim,sec);

    while(input(TROCA_MODO));

    delay_ms (100);

    if (modo > 7 )

    {

    modo = 0;

    }

    enable_interrupts(global | int_ext);

    }

    printf(lcd_escreve,"\fAjustar Segundos:\n%02d",sec);

    delay_ms (100);

    break;

    }

    default:

    {

    if(input(TROCA_MODO))

    {

    disable_interrupts(global | int_ext);

    modo++;

    while(input(TROCA_MODO));

    if (modo > 7 )

    {

    modo = 0;

    }

    }

    }

    }

    }

    }

    ////////////////////////////////////////////////////////////////////////////////

    /// DS1307.C ///

    /// Driver for Real Time Clock ///

    /// ///

    /// ds1307_init() - Enable oscillator without clearing the seconds register -///

    /// used when PIC loses power and DS1307 run from 3V BAT ///

    /// - Disable squarewave output ///

    /// ///

    /// ds1307_set_date_time(day,mth,year,dow,hour,mim,sec) Set the date/time ///

    /// ///

    /// ds1307_get_date(day,mth,year,dow) Get the date ///

    /// ///

    /// ds1307_get_time(hr,mim,sec) Get the time ///

    /// ///

    ////////////////////////////////////////////////////////////////////////////////

    #define RTC_SDA PIN_d0

    #define RTC_SCL PIN_d1

    #use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

    #use i2c(sda=PIN_d0, scl=PIN_d1, stream=I2C_HW)

    BYTE bin2bcd(BYTE binary_value);

    BYTE bcd2bin(BYTE bcd_value);

    void ds1307_init(void)

    {

    BYTE seconds = 0;

    i2c_start();

    i2c_write(0xD0); // WR to RTC

    i2c_write(0x00); // REG 0

    i2c_start();

    i2c_write(0xD1); // RD from RTC

    seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307

    i2c_stop();

    seconds &= 0x7F;

    delay_us(3);

    i2c_start();

    i2c_write(0xD0); // WR to RTC

    i2c_write(0x00); // REG 0

    i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value

    i2c_start();

    i2c_write(0xD0); // WR to RTC

    i2c_write(0x07); // Control Register

    i2c_write(0x10); // Disable squarewave output pin

    i2c_stop();

    }

    void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE mim, BYTE sec)

    {

    sec &= 0x7F;

    hr &= 0x3F;

    i2c_start();

    i2c_write(0xD0); // I2C write address

    i2c_write(0x00); // Start at REG 0 - Seconds

    i2c_write(bin2bcd(sec)); // REG 0

    i2c_write(bin2bcd(mim)); // REG 1

    i2c_write(bin2bcd(hr)); // REG 2

    i2c_write(bin2bcd(dow)); // REG 3

    i2c_write(bin2bcd(day)); // REG 4

    i2c_write(bin2bcd(mth)); // REG 5

    i2c_write(bin2bcd(year)); // REG 6

    i2c_write(0x10); // REG 7 - Disable squarewave output pin

    i2c_stop();

    }

    void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)

    {

    i2c_start();

    i2c_write(0xD0);

    i2c_write(0x03); // Start at REG 3 - Day of week

    i2c_start();

    i2c_write(0xD1);

    dow = bcd2bin(i2c_read() & 0x7f); // REG 3

    day = bcd2bin(i2c_read() & 0x3f); // REG 4

    mth = bcd2bin(i2c_read() & 0x1f); // REG 5

    year = bcd2bin(i2c_read(0)); // REG 6

    i2c_stop();

    }

    void ds1307_get_time(BYTE &hr, BYTE &mim, BYTE &sec)

    {

    i2c_start();

    i2c_write(0xD0);

    i2c_write(0x00); // Start at REG 0 - Seconds

    i2c_start();

    i2c_write(0xD1);

    sec = bcd2bin(i2c_read() & 0x7f);

    mim = bcd2bin(i2c_read() & 0x7f);

    hr = bcd2bin(i2c_read() & 0x3f);

    i2c_stop();

    }

    BYTE bin2bcd(BYTE binary_value)

    {

    BYTE temp;

    BYTE retval;

    temp = binary_value;

    retval = 0;

    while(1)

    {

    // Get the tens digit by doing multiple subtraction

    // of 10 from the binary value.

    if(temp >= 10)

    {

    temp -= 10;

    retval += 0x10;

    }

    else // Get the ones digit by adding the remainder.

    {

    retval += temp;

    break;

    }

    }

    return(retval);

    }

    // Input range - 00 to 99.

    BYTE bcd2bin(BYTE bcd_value)

    {

    BYTE temp;

    temp = bcd_value;

    // Shifting upper digit right by 1 is same as multiplying by 8.

    temp >>= 1;

    // Isolate the bits for the upper digit.

    temp &= 0x78;

    // Now return: (Tens * 8) + (Tens * 2) + Ones

    return(temp + (temp >> 2) + (bcd_value & 0x0f));

    }

    Do jeito que tá está lendo direitinho o RTC, mas não esta gravando os valores.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Como você sabe se gravou certo se não consegue ler? E vice vera? As minhas bibliotecas não vão funcionar, foram feitas para PIC32MX no compilador C32, completamente diferente do que estas usando, mas a lógica é correta. Acho melhor trabalhar em cima do que tens. Em primeiro lugar, lestes o datasheet do componente? Ele tem um seção dedicada a I2C que informa qual deve ser o procedimento para leitura ou escrita de um byte no RTC. Faça no main mesmo um codigo direto na I2C lendo e jogando no LCD, se funcionar passe para uma função e depois para uma biblioteca. Sair pegando tudo pronto e juntando não é garantia que funciona. Vou exemplificar a lógica básica que utilizei no meu programa:

    Inicializa I2C

    Lê registrador dos segundo

    Se bit CH=1

    -Reseta os registradores do RTC

    -Ajusta hora padrão

    Se bit CH=0

    -Segue o programa normal

    No programa principal poder ler o valor do RTC periodicamente (nem que seja um timer, e escrever no LCD). Quando recem ligares o circuito o RTC será carregado com a data padrão, dali em diante ele deve manter os valores corretos. Faça o simples e foque em cima do problema, tire os penduricalhos do programa e deixe só o RTC até que funcione, depois adicione o resto.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • E ai edu.!

    Sei que estava gravando certo porque também estou simulando no Proteus.

    Estava fazendo como você me sugeriu quando lembrei de uma coisa na configuração do PIC

    Cara, estava tentando entender porque num funciona tudo junto, hora funciona uma coisa, hora outra. Aí lembrei de colocar uma linha em meu programa que parece que resolveu:

    setup_adc_ports(no_analog);

    Depois que fiz isso, está lendo e gravando corretamente. Ainda num testei direito porque já tava na hora de largar serviço, mas amanhã vou testar direitinho e depois coloco aqui se deu certo ou não.

    você sabe o porque disso? Pois quando não definimos nada, o compilador (PCW) por padrão já deveria definir todos os pinos como digitais num é.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Pessoal, tinha dado uma sumida mais agora eu tô aí.:D

    Depois da grande ajuda de todos vocês consegui resolver meu problema.

    Aprendi bastante coisa sobre esse RTC e comunicação I2C.

    Meu problema era na leitura dos valores mesmo. Exatamente como o edu. me falou:

    get_time( &mhr, &mmin, &mseg );

    Demorou pra cair a ficha aqui, mas acontece que entendo muito pouco de programação.

    Agora tá tudo Ok aqui! Valeu mesmo galera!

    Até +!!!

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Opa, fico muito feliz em saber que consegui ajudar. Espero que não pares por ai, a programação é vasta e sempre tem algo novo para aprender. Continue seus estudos e sempre conte com a ajuda do pessoal do fórum !

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Crie uma conta ou entre para comentar

    Você precisar ser um membro para fazer um comentário






    Sobre o Clube do Hardware

    No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

    Direitos autorais

    Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

    ×