Ir ao conteúdo
  • Cadastre-se

Problema com ds1307 + pic +lcd ccs


diego.maga

Posts recomendados

Olá pessoal estou querendo fazer aparecer as horas em um display e lcd e o mesmo esta funcionado,porém após um pequeno tempo de simulação as horas começam a ficar estranhas, se alteram com uns valores doidos.estou postando as fotos e codigo fonte, se alguem puder me ajudar ficarei grato.

BIBLIOTECA DS1307

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

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

/// ///

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

#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)

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(5);

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 0777777777

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 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(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 &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(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));

}

CODIGO FONTE

#include <16F876a.h>

#use delay(clock=4000000)

#include <dds1307.c>

#include <lcd_flexB.C>

//============================Variaveis utilizada===============================

int sec; //Variavel que armazena o valor dos segundos

int mim; //Variavel que armazena o valor dos minutos

int hrs; //Variavel que armazena o valor das horas

int dia; //Variavel que armazena o valor do dia

int mes; //Variavel que armazena o valor do mes

int ano; //Variavel que armazena o valor ano

int dow; //Variavel que armazena o valor dia da semana (Seg,Ter,Qua,....)

//==============================================================================

void main()

{

ds1307_init(); //Inicializa o componente ds1307

delay_ms(100); //Aguarda 1000ms

ds1307_set_date_time(9,9,10,5,23,57,00); //9/09/10 23:59:50 dia da semana 5

delay_ms(100); //Aguarda 1000ms

lcd_init(); //Inicializa LCD

delay_ms(10); //Aguarda 10ms

inicio(); //Chama a função inicio

while(true)

{

ds1307_get_date(dia,mes,ano,dow);

delay_ms(10); //Aguarda 10ms

ds1307_get_time(hrs,mim,sec);

delay_ms(10); //Aguarda 10ms

lcd_gotoxy(1,1); printf(lcd_putc,"%02d:%02d:%02d"hrs,mim,sec);

lcd_gotoxy(2,2); printf(lcd_putc,"%02d/%02d/%02d",dia,mes,ano);

}

}

LOGO AO INICIAR

75111733.jpg

DEPOIS DE UM TEMPO DE SIMULAÇÃO

48580621.jpg

CIRCUITO eletrônico

58403421.jpg

Link para o comentário
Compartilhar em outros sites

1º: você chama a função inicio(); que não existe no seu código, aqui tive q comentar.

2º: Veja o cristal q você colocou no DS137: 32768K? o correto é 32.768K

3º: Ponha um delay_ms (1000) logo depois de escrever no LCD. Pois você atualiza os segundos, não precisa escrever no LCD em tempo real.

4º: Monte o circuito numa protoboard e teste. Não confie demais no Proteus.

Falou

Link para o comentário
Compartilhar em outros sites

1º: você chama a função inicio(); que não existe no seu código, aqui tive q comentar.

2º: Veja o cristal q você colocou no DS137: 32768K? o correto é 32.768K

3º: Ponha um delay_ms (1000) logo depois de escrever no LCD. Pois você atualiza os segundos, não precisa escrever no LCD em tempo real.

4º: Monte o circuito numa protoboard e teste. Não confie demais no Proteus.

Falou

Alterei o valor do cristal ,não tinha reparado a este detalhes,outra coisa que percebi que esse é só as vezes que acontece,tem hora que não apresenta erro, e as vezes logo ao iniciar.Será que pode ser do proprio PROTEUS esse problema.

Outra coisa importante é a simulação X realidade,gostaria de saber se você já simulou alguma vez no proteus e funcionou e chegou na hora da pratica e nada ou vice e versa.

Link para o comentário
Compartilhar em outros sites

Na maioria das vezes funciona no Proteus e não funciona na prática.

Isso acontece pois o proteus engole ignora muita coisa.

As vezes o proteus também não dá conta de fazer os circuitos funcionarem e na pratica de boa.

Depende doq você faz.

Uso o proteus sempre antes de montar. Fiz mais facild e debugar o codigo.

Falou

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para 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...