Ir ao conteúdo
  • Cadastre-se

Problemas com DS1307 + PIC em C


Visitante

Posts recomendados

Bom dia povo, desculpe por desenterrar este topico mas é que estou tentando acoplar um RTC no meu projeto onde seria interessante o RTC mandar um pulso na saida a cada hora e isso eu não estou entendendo como é feito. Não to conseguindo entender como o pic programa o DS1307 para despertar.

 

Alguem poderia me dar uma ajudinha rapida???

Link para o comentário
Compartilhar em outros sites

amigos  gostaria d saber   como  faço para  associar os drives  ou melhor  as biblioteca  do  Ds1307   no Ccs  pois  dar erro  como se não existisse  dentro do programa

desde  ja agradeço 

obs:  ja  fiz esta pergunta  algumas vezes mas por incrível que pareça ainda não consegui  resolver  pra não  tirar o foco destas ou de outras discussões 

1 --> motivo pelo qual não abri  o um tópico    resposta ----> porque  muitas das vezes  o assunto teria que ser ressuscitado de outro  tópico como este  então  para que este  fique mas completo  pois esta relacionado decidi perguntar aqui mesmo ok galera  

Link para o comentário
Compartilhar em outros sites

@circuit

Veja:

http://forum.clubedohardware.com.br/forums/topic/862157-resolvido-relogio-com-ds1307-termometro-com-lm35-display-lcd-e-pic-16f877a/#entry4866660

Falou

@Ivan (eletronic)

Olha a inicialização do DS1307:

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(0x80);     // Disable squarewave output pin    i2c_stop(); }
você precisa alterar o registrador 0x07.

Deixar você pensar um pouquinho.

Falou

Link para o comentário
Compartilhar em outros sites

Senhores, tentei compilar o programa com a modificação acima e não ia, dava um erro informando que a expressão teria que tem uma variavel.

Com isso o codigo ficou assim:

 

 
int square = 16;
/* 16   1Hz
   17  4kHz
   18  8kHz    
   19  32kHz
 */
 
void ds1307_init(void)
.
.
.
   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
   square = i2c_write(0x07); // Control Register
.
.
.
Link para o comentário
Compartilhar em outros sites

Oi Ivan, Faça o seguinte:
 
Abra a biblioteca, vá até a função "void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE mim, BYTE sec) " e mude o REG 7 para 0x10, como na imagem em anexo:

 

 

Pelo menos foi assim que fiz e funcionou certinho aqui...


Oi Ivan, Faça o seguinte:
 
Abra a biblioteca, vá até a função "void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE mim, BYTE sec) " e mude o REG 7 para 0x10, como na imagem em anexo:

 

 

Pelo menos foi assim que fiz e funcionou certinho aqui...


HeHe!
 
Só num consegui colocar a imagem, mas segue o código da biblioteca:

 

Onde tá comentado em português é onde você modificará.
 
 

///////////////////////////////////////////////////////////////////////////////////                               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_e1#define RTC_SCL  PIN_e0 #use i2c(master, sda=RTC_SDA, scl=RTC_SCL)#use i2c(sda=RTC_SDA, scl=RTC_SCL, 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                               // REG 7 - Aqui vc muda de 0x70 para 0x10 que aciona a saída à 1Hz  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(); } /*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));} 

 

Link para o comentário
Compartilhar em outros sites

Senhores acho que me expressei mal, eu tentei dizer que colocando uma variavel igual a expressao o codigo compilou. Então o que postei acima é como comsegui compilar.

 

Ihhh agora ja fiquei com uma grande duvida, pois se eu fizer como o matheus falou pra mim tem sentido porque você esta colocando um valor num endereço da memoria, ja se fizer do jeito que o Davidson mencionou você esta gravando sabe deus o que no endereço 0x10.

 

Ou minha forma de interpretar esta errada?

 

de qualquer forma segue codigo abaixo:

 

///////////////////////////////////////////////////////////////////////////////////                               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,min,sec)  Set the date/time   //////                                                                          ////// ds1307_get_date(day,mth,year,dow)               Get the date             //////                                                                          ////// ds1307_get_time(hr,min,sec)                     Get the time             //////                                                                          /////////////////////////////////////////////////////////////////////////////////// #define RTC_SDA  PIN_C4#define RTC_SCL  PIN_C3 #use i2c(master, sda=RTC_SDA, scl=RTC_SCL) BYTE bin2bcd(BYTE binary_value);BYTE bcd2bin(BYTE bcd_value); int square = 16;/* 16   1Hz   17  4kHz   18  8kHz       19  32kHz */ 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   square = i2c_write(0x07); // Control Register         i2c_write(0x80);      // Disable squarewave output pin   i2c_stop(); }  void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, 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(min));      // 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(0x80);            // 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 &min, 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);  min = bcd2bin(i2c_read() & 0x7f);  hr  = 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)); }  
Link para o comentário
Compartilhar em outros sites

@Ivan (eletronic)

Agora entendi o que você fez e o que você desejou fazer.

O post do Davidson indica os locais exatos da modificação que são na inicialização da biblioteca e na gravação da data nela. Mas você fez errado. Veja. Você fez isso:

square = i2c_write(0x07);

Você deveria ter feito isso:

i2c_write(square);

Lembre se que tem que fazer isso em dois lugares. No função init e na outra citada pelo Davidson.

Falou

Além disso, você teve uma interpretação equivocada de como a biblioteca funciona. Observe esse pequeno trecho da função ds1307_init:

i2c_write(0x07);   i2c_write(0x10);
Nesse pequeno trecho, a biblioteca está selecionando o endereço o registrador 0x07 e escrevendo a informação 0x10.

Na função citada pelo Davidson, a biblioteca faz diferente. Ela escolhe a posição 0x00 e vai escrevendo os dados um atrás do outro. Ela faz isso pois no datasheet diz q se você escrever em uma posição, há um contador interno no ds1307 que incrementa sozinho e ele vai selecionando as posições seguintes à serem escritas.

Mas veja que no final da função indicada pelo Davidson, há de novo a escrita do 0x10.

Falou

Link para o comentário
Compartilhar em outros sites

Usando a forma que acaba de explicar sobre o post do Davidson, eu não precisaria usar esta forma:

 

i2c_write(square);

 

correto? 

 

Sendo assim, eu modificaria os seguintes pontos:

delay_us(3);i2c_start();i2c_write(0xD0); // WR to RTCi2c_write(0x00); // REG 0i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds valuei2c_start();i2c_write(0xD0); // WR to RTCi2c_write(0x07); // Control Registeri2c_write(0x10); // Disable squarewave output pin <---------MODIFICAR AQUIi2c_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 addressi2c_write(0x00); // Start at REG 0 - Secondsi2c_write(bin2bcd(sec)); // REG 0i2c_write(bin2bcd(mim)); // REG 1i2c_write(bin2bcd(hr)); // REG 2i2c_write(bin2bcd(dow)); // REG 3i2c_write(bin2bcd(day)); // REG 4i2c_write(bin2bcd(mth)); // REG 5i2c_write(bin2bcd(year)); // REG 6i2c_write(0x10); // REG 7 - Disable squarewave output pin <---------MODIFICAR AQUI 

Desculpe senhores sou meio lento para pegar as coisas, mas é que quero sanar todas as duvidas para realmente aprender, por isso peço paciencia rsrsrrsrrrs

Link para o comentário
Compartilhar em outros sites

@Ivan (eletronic)

Nesse trecho que você colocou seria exatamente onde precisa colocar o i2c_write(square);.

Nos dois locais onde diz MODIFICAR AQUI.

A vantagem de você substituir o 0x10 por uma variável é que você consegue alterar a frequência de saída quando quiser.

Falou

Link para o comentário
Compartilhar em outros sites

Portanto ficou assim:

 

 


 


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

///                               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,min,sec)  Set the date/time   ///

///                                                                                                                          ///

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

///                                                                                                                         ///

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

///                                                                                                                        ///

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


 

#define RTC_SDA  PIN_C4

#define RTC_SCL  PIN_C3

 

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

 

BYTE bin2bcd(BYTE binary_value);

BYTE bcd2bin(BYTE bcd_value);

 

int square = 0x10;

 

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

///    Valores para oscilador da Saida  ///

///                                                         ///

///      1Hz:     16 ou 0x10                     ///

///     4kHz:    17 ou 0x11                     ///

///     8kHz:    18  ou 0x12                    ///

///    32kHz:   19 ou 0x13                     ///

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

 

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(square);               // Disable squarewave output pin

   i2c_stop();

 

}

 

 

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, 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(min));          // 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(square);                // 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 &min, 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);

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

  hr  = 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));


 


Link para o comentário
Compartilhar em outros sites

Oi Ivan, boa noite!

 

Como o Matheus falou, o RTC tem um contador interno que incrementa os registradores a cada dado gravado (  i2c_write();  ). É por isso que ficamos tão confusos na hora de trabalhar com ele. pois o endereço do REG_7 não precisa ser adicionado, mas sim, seu conteúdo. Também tive muitas duvidas pra trabalhar com o DS1307. Se não fosse a galera aqui do fórum eu tava até hoje mexendo, kkk!

 

Não se preocupe com o andamento do tópico, o que importa mesmo é que você aprenda.

 

Um abraço!

Link para o comentário
Compartilhar em outros sites

@Ivan (eletronic)

 

Veja esse trecho final da função DS1307_init:

 

i2c_start();
i2c_write(0xD0);                   ------>      Aqui você está escolhendo qual registrador irá escrever
i2c_write(0x07);                    ------>     Informação redundante.
   
i2c_write(square);                ----->      Aqui você está escrevendo justamente o 0x07. Não precisa do 0x07 da linha de cima.
 
Falou
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...