Ir ao conteúdo
  • Cadastre-se

Projeto de relógio com termômetro (lm35) com PIC16F877A


Ir à solução Resolvido por joseca,

Posts recomendados

Colega MatheusLPS,lembra do seu projeto do relogio com termometro(lm35)com PIC16F877A  e aos colegas que puderem dar uma sugestão do pode estar ocorrendo no projeto.

O relogio esta pulando a contagem de segundos,por exemplo do 15 para 0 17 e com isso a contagem do tempo fica prejudicada,as vezes da isso 2 vezes,adiantando com isso  a contagem final do relogio.

Na simulação no Proteus tambem da isso,segue um video que fiz do projeto montado.

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@joseca,

 

Não me lembro de como o código estava gerando a temporização, mas com certeza é simples de resolver. Eu costumo usar um RTC para gerar o tempo, programo ele para gerar interrupção a cada segundo, e leio os dados e apesento, assim sempre mostra corretamente.

 

Nesse projeto creio que a temporização está sendo gerada por interrupção de Timer que não está sendo feita exatamente a cada 1 segundo, deve ter alguma fração, e isso costuma gerar esse problema. Mas estou supondo apenas, pois não me lembro desse projeto...

 

Paulo

Link para o comentário
Compartilhar em outros sites

Ola Paulo,segue abaixo o codigo

 

 

#include <16F877A.h>#device adc=10                   //Habilitar ADC de 10 bits, obrigatório. Pode                                 //ser utilizado de 8 bits também.#FUSES NOWDT                    //No Watch Dog Timer#FUSES XT                          //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=4000000) #include <ds1307.c>#include <lcd.c> #define botao_incremento PIN_B0#define botao_decremento PIN_B1 BYTE sec;BYTE mim;BYTE hrs;BYTE day;BYTE month;BYTE yr;BYTE dow; int8 modo;int16 adc;float temperatura; int8 tempo; char dia_da_semana[7][8]={   "DOMINGO",   "SEGUNDA",   "TERCA",   "QUARTA",   "QUINTA",   "SEXTA",   "sábado",}; #int_timer1void trata_tempo(){   tempo++;      if (tempo == 10)// 5 segundos   {      output_toggle (PIN_B5);  //inverte o nivel logico de RB5      tempo=0;      disable_interrupts( INT_TIMER1);               //Habilita interrupção timer1   }   set_timer1 (3036);} #int_ccp1void trata_ccp_1(){   if ((modo == 0) && (tempo ==0))   {      output_toggle (PIN_B5);      enable_interrupts( INT_TIMER1);               //Habilita interrupção timer1      set_timer1 (3036);   }} #int_ccp2void trata_ccp_2(){   modo++;   if (modo == 1)   {      disable_interrupts(INT_TIMER1);               //Habilita interrupção timer1      output_high (PIN_b5);   }         if (modo > 7 )   {            modo = 0;   }      if (modo == 0 )   {      enable_interrupts( INT_TIMER1);               //Habilita interrupção timer1         }} void main(){    output_high (PIN_B5);   setup_ccp1(CCP_CAPTURE_RE);   setup_ccp2(CCP_CAPTURE_RE);   setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);   //Configuração do Timer1 para clock interno = 1E6 dividido por 8   set_timer1 (3036);                           //Preload do Timer1      enable_interrupts( INT_TIMER1);               //Habilita interrupção timer1   enable_interrupts (int_ccp1);   enable_interrupts (int_ccp2);   enable_interrupts (global);      setup_adc_ports(AN0);         //Configura canal 0 analógico   setup_adc(ADC_CLOCK_INTERNAL);    //De acordo com relógio interno.      set_adc_channel(0);           //Habilita canal 0   delay_us(20);                 //Espera um pouco, obrigatório!         ds1307_init();   lcd_init();   modo = 0;      while(true)   {      switch (modo)      {                                                                      case 1:         {                        if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               hrs++;            }                        if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               hrs--;            }                        if (hrs == 24 )            {               hrs = 0;            }                        if (hrs == 255 )            {               hrs = 23;            }                        printf(lcd_putc,"\fAjustar Hora:\n%u",hrs);                        delay_ms (100);            break;         }                  case 2:         {                        if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               mim++;            }                        if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               mim--;            }                        if (mim == 60 )            {               mim = 0;            }                        if (mim == 255 )            {               mim = 59;            }                                                printf(lcd_putc,"\fAjustar Minutos:\n%u",mim);                        delay_ms (100);            break;         }                  case 3:         {                        if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               sec++;            }                        if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               sec--;            }                        if (sec == 60 )            {               sec = 0;            }                        if (sec == 255 )            {               sec = 59;            }                        printf(lcd_putc,"\fAjustar Segundos:\n%u",sec);                        delay_ms (100);            break;         }                  case 4:         {                        if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               day++;            }                        if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               day--;            }                        if (day == 32 )            {               day = 1;            }                        if (day == 0 )            {               day = 31;            }                        printf(lcd_putc,"\fDia do Mes:\n%u",day);                        delay_ms (100);            break;         }                  case 5:         {                        if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               month++;            }                        if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               month--;            }                        if (month == 13 )            {               month = 1;            }                        if (month == 0 )            {               month = 12;            }                        printf(lcd_putc,"\fAjustar Mes:\n%u",month);                        delay_ms (100);            break;         }                  case 6:         {                        if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               yr++;            }                        if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               yr--;            }                        if (yr == 100 )            {               yr = 1;            }                        if (yr == 0 )            {               yr = 99;            }                        printf(lcd_putc,"\fAjustar Ano:\n%u",yr);                        delay_ms (100);            break;         }                  case 7:         {                        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;            }                        printf(lcd_putc,"\fDia da Semana:\n%s",dia_da_semana[dow-1]);                        delay_ms (100);                        ds1307_set_date_time(day,month,yr,dow,hrs,mim,sec);                                                                                                   break;         }                  default:         {         if ((mim == 59) && (sec ==59)){                     output_high(pin_b4);            delay_ms(100);            output_low(pin_b4);            delay_ms(100);            output_high(pin_b4);            delay_ms(100);            output_low(pin_b4);                                             }                  {              adc = read_adc();               //Lê canal 0            temperatura = (5.0 * adc * 100) / 1024.0;         //Conversão para tensão.                   ds1307_get_date(day,month,yr,dow);            ds1307_get_time(hrs,mim,sec);                        printf(lcd_putc,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d %2.0f%cC",dia_da_semana[dow-1],hrs,mim,sec,day,month,yr,temperatura,0xdf);                          delay_ms(1000);         }      }   }}}

Link para o comentário
Compartilhar em outros sites

@joseca

 

De acordo com o código que você colocou, usei o DS1307 que é um RTC.

 

Não consigo ver o vídeo de onde estou. Quando chegar em casa, dou uma olhada. Mas pelo que você falou, não deveria ocorrer isso não.

 

Outra coisa, tem como você editar o post anterior ond colocou o código e colocar as tags

e

?

 

Falou

Link para o comentário
Compartilhar em outros sites

Desculpe Paulo,não sei se assim que voce pediu...

 

#include <16F877A.h>#device adc=10                   //Habilitar ADC de 10 bits, obrigatório. Pode                                 //ser utilizado de 8 bits também.#FUSES NOWDT                    //No Watch Dog Timer#FUSES XT                          //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=4000000)#include <ds1307.c>#include <lcd.c>#define botao_incremento PIN_B0#define botao_decremento PIN_B1BYTE sec;BYTE mim;BYTE hrs;BYTE day;BYTE month;BYTE yr;BYTE dow;int8 modo;int16 adc;float temperatura;int8 tempo;char dia_da_semana[7][8]={   "DOMINGO",   "SEGUNDA",   "TERCA",   "QUARTA",   "QUINTA",   "SEXTA",   "sábado",};#int_timer1void trata_tempo(){   tempo++;     if (tempo == 10)// 5 segundos   {      output_toggle (PIN_B5);  //inverte o nivel logico de RB5      tempo=0;      disable_interrupts( INT_TIMER1);               //Habilita interrupção timer1   }   set_timer1 (3036);}#int_ccp1void trata_ccp_1(){   if ((modo == 0) && (tempo ==0))   {      output_toggle (PIN_B5);      enable_interrupts( INT_TIMER1);               //Habilita interrupção timer1      set_timer1 (3036);   }}#int_ccp2void trata_ccp_2(){   modo++;   if (modo == 1)   {      disable_interrupts(INT_TIMER1);               //Habilita interrupção timer1      output_high (PIN_b5);   }       if (modo > 7 )   {           modo = 0;   }     if (modo == 0 )   {      enable_interrupts( INT_TIMER1);               //Habilita interrupção timer1        }}void main(){   output_high (PIN_B5);   setup_ccp1(CCP_CAPTURE_RE);   setup_ccp2(CCP_CAPTURE_RE);   setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);   //Configuração do Timer1 para clock interno = 1E6 dividido por 8   set_timer1 (3036);                           //Preload do Timer1     enable_interrupts( INT_TIMER1);               //Habilita interrupção timer1   enable_interrupts (int_ccp1);   enable_interrupts (int_ccp2);   enable_interrupts (global);     setup_adc_ports(AN0);         //Configura canal 0 analógico   setup_adc(ADC_CLOCK_INTERNAL);    //De acordo com relógio interno.     set_adc_channel(0);           //Habilita canal 0   delay_us(20);                 //Espera um pouco, obrigatório!        ds1307_init();   lcd_init();   modo = 0;     while(true)   {      switch (modo)      {                                                               case 1:         {                       if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               hrs++;            }                       if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               hrs--;            }                       if (hrs == 24 )            {               hrs = 0;            }                       if (hrs == 255 )            {               hrs = 23;            }                       printf(lcd_putc,"\fAjustar Hora:\n%u",hrs);                       delay_ms (100);            break;         }                 case 2:         {                       if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               mim++;            }                       if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               mim--;            }                       if (mim == 60 )            {               mim = 0;            }                       if (mim == 255 )            {               mim = 59;            }                                             printf(lcd_putc,"\fAjustar Minutos:\n%u",mim);                       delay_ms (100);            break;         }                 case 3:         {                       if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               sec++;            }                       if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               sec--;            }                       if (sec == 60 )            {               sec = 0;            }                       if (sec == 255 )            {               sec = 59;            }                       printf(lcd_putc,"\fAjustar Segundos:\n%u",sec);                       delay_ms (100);            break;         }                 case 4:         {                       if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               day++;            }                       if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               day--;            }                       if (day == 32 )            {               day = 1;            }                       if (day == 0 )            {               day = 31;            }                       printf(lcd_putc,"\fDia do Mes:\n%u",day);                       delay_ms (100);            break;         }                 case 5:         {                       if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               month++;            }                       if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               month--;            }                       if (month == 13 )            {               month = 1;            }                       if (month == 0 )            {               month = 12;            }                       printf(lcd_putc,"\fAjustar Mes:\n%u",month);                       delay_ms (100);            break;         }                 case 6:         {                       if (input(BOTAO_INCREMENTO))            {               delay_ms (75);               yr++;            }                       if (input(BOTAO_DECREMENTO))            {               delay_ms (75);               yr--;            }                       if (yr == 100 )            {               yr = 1;            }                       if (yr == 0 )            {               yr = 99;            }                       printf(lcd_putc,"\fAjustar Ano:\n%u",yr);                       delay_ms (100);            break;         }                 case 7:         {                       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;            }                       printf(lcd_putc,"\fDia da Semana:\n%s",dia_da_semana[dow-1]);                       delay_ms (100);                       ds1307_set_date_time(day,month,yr,dow,hrs,mim,sec);                                                                                              break;         }                 default:         {         if ((mim == 59) && (sec ==59)){                    output_high(pin_b4);            delay_ms(100);            output_low(pin_b4);            delay_ms(100);            output_high(pin_b4);            delay_ms(100);            output_low(pin_b4);                                          }                 {             adc = read_adc();               //Lê canal 0            temperatura = (5.0 * adc * 100) / 1024.0;         //Conversão para tensão.                ds1307_get_date(day,month,yr,dow);            ds1307_get_time(hrs,mim,sec);                       printf(lcd_putc,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d %2.0f%cC",dia_da_semana[dow-1],hrs,mim,sec,day,month,yr,temperatura,0xdf);                         delay_ms(1000);         }      }   }}}

 

Ola Matheus,voce que é pai da criança,isto é do codigo,kkkkkkkk gostaria de saber o porque desses pulos nos segundos...

Link para o comentário
Compartilhar em outros sites

@joseca

 

Eu tentaria reduzir um pouco mais aquele tempo de delay:

 

 

Tipo, 800, 600..

delay_ms(800);

Isso deve evitar esse pulo de 1 segundo (o LCD atualiza um pouco mais rápido).

 

Em Delphi, eu costumava usar essa temporização inferior a 1 segundo quando tinha que implementar algum relógio. Não deve ser diferente aí nesse caso.

 

 

 

 

LNW

Link para o comentário
Compartilhar em outros sites

Faça uma alteração e poste o resultado;

Onde estiver;

set_timer1 (3036);

Altere para ;

set_timer1(3036 - get_timer1());  

Com essa alteração você vai garantir a precisão do evento do Timer1,mas de qualquer maneira usando um RTC não era para acontecer isso a menos que o rotina de atualização do LCD esteja longa.

Link para o comentário
Compartilhar em outros sites

tentei copilar  mas  não deu galera  desculpa a iguinorancia sem querer  tirar o tópico do rumo  diga passo a passo como se resolve  isso desta imagem  logo abaixo ? sei que tem aver com a falta da biblioteca do ds mas mas onde consigo este arquivo como colar  , em qual pasta dentro  dos arquivos  do ccs?  são essa e outras duvidas  que surgiram aqui  

   uma vez avia perguntado  e fui respondido com boa vontade  mas  não avia conseguido resolver por isso tinha deixado de lado portanto a duvida permanece

post-650643-0-93582800-1405092585_thumb.

Link para o comentário
Compartilhar em outros sites

LNW, diminui o delay delay_ms(800);

Agora ele não esta pulando a contagem dos segundos ,mas eventualmente esta mais lento na mudança dos segundos,somente em alguns momentos.....ora conta normal,ora conta alterado.

VTRX,quanto a montagem do projeto em placa de circuito acho que ninguem ainda montou não,outra cois a alteração da linha que voce falou (set_timer1(3036)alterei somente em um lugar,teria que alterar todos??

Link para o comentário
Compartilhar em outros sites

 

(set_timer1(3036)alterei somente em um lugar,teria que alterar todos??

Sim,mas esta mudança apenas 'sincroniza' o carregamento do Timer corretamente pois o registrador do Timer decrementa,neste caso,infinitamente,logo,quando for recarrega-lo,o registrador ja tem um valor decrementado,se sempre recarrega-lo sem esta compensação,o Timer estourará microssegundos mais lento pois ele ja tinha decrementado até chegar na instrução que o recarrega.

O correto era atualizar o display em exatos 1 segundo,mas usando um Timer e não looping + delay.

Se você mesmo montou esta placa,ficou muito bonita,eu mesmo tenho preguiça de montar um relógio assim,mas sempre tive curiosidade.

Se você mesmo montou e comprou os componentes,eu interessaria em comprar de você para testar vários códigos de relógios pois estou muito sem tempo de fazer protótipos :D

 

Olhe este post:

http://forum.clubedohardware.com.br/forums/topic/1033800-pinagem-display-lcd/?hl=%2Bvtrx+%2Blcd#entry5676576

 

Você imagina que desde então ainda esta na caixa?!  -_-

Link para o comentário
Compartilhar em outros sites

Pessoal, esse código foi desse tópico:

 

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

 

De acordo com o @janascimento, ele testou e funcionou normal.

 

O timer1 que configurei no código serve apenas para desligar o backlight depois de algum tempo programado. Por isso, acredito não estar relacionado com o problema relatado.

 

Sobre :

 

O correto era atualizar o display em exatos 1 segundo,mas usando um Timer e não looping + delay.

 

O uso do delay no loop principal de deu ao fato de a única função do PIC nesse circuito é ler do DS1307 e mostrar no LCD. Dessa forma, esse delay não atrapaçha em outras funções.

 

Mesmo se atualizar o LCD em exatos 1 segundo, se  atualização não estiver sincronizada com o DS1307, não vai adiantar.

 

Bom, muitos já deram a resposta. Diminuindo o delay o LCD irá atualizar várias vezes por segundo e evita que ele pule algum número. Tente diminuir ainda mais. Como por exemplo 200mS. Diminua até ele começar a piscar, depois aumente um pouco até parar de piscar.

 

Fora isso, só consigo imaginar o problema sendo no cristal do DS1307. Ele utiliza um cristal bem específico.

 

Sobre a montagem, a mesma ficou muito bem feita. Queria eu ter essa paciência também.

 

 

 

 

 

Falou

Link para o comentário
Compartilhar em outros sites

@MatheusLPS,

 

Realmente ficou muito boa a montagem do Joseca !!!

 

Gostaria de sugerir uma pequena modificação, que acredito que resolveria esse problemas de uma vez.

 

Podemos usar o pino 7 do 1307 para interromper o programa principal, pois neste pino temos uma onda quadrada de exatamente 1 hertz. Basta ligar a um dos pinos de entrada do PIC, e programar pull up nele.

 

Se usar uma interrupção por desçida e chamar a rotina que lê a data e mostra no display, nunca vamos ter os segundos errados, e resolve de vez esses delays....

 

Paulo

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Paulo e MatheusLPS,obrigado pela ajuda estou aprendendo muito,foi falado em problema no cristal,mas como se esta dando esse erro na simulaçao do Proteus tambem??

Matheus peguei o link original com o codigo feito por voce compilei e simulei no proteus,deu esse erro,posso mandar o arquivo do proteus para vocês analizarem....

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

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!