Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

PIC: Cronometro com PIC16F628A

Share:

PIC: Cronometro com PIC16F628A



Olá galera!! Este é um projeto simples de um cronômetro.

Contém os valores de minutos, segundos, milissegundos e também microsegundos :)

Utilizando um clock interno de 4Mhz, o TIMER1 foi utilizado para a contagem dos microssegundos. Configurado com prescaler 1:1, ele leva exatamente 1us para poder incrementar seu valor( registros TMR1L e TMR1H ). O TIMER0 foi utilizado para a contagem dos milissegundos. Configurando para gerar uma interrupção a cada 1ms, ele incrementa os milissegundos, segundos e minutos.

Existem dois botões: um para zerar o tempo e um outro para Iniciar/ Pausar o tempo. O botão de Iniciar/ Pausar foi ligado ao pino RB0, que é o pino de interrupção externa. Foi ligado neste pino para ter uma maior precisão na captura/pausa do tempo.

CÓDIGO
MikroC PRO PIC
sbit LCD_RS at RB6_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB6_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;

sbit Zerar at PORTB.B7;

unsigned MicroSegundos at TMR1L;

typedef struct
{
  char minutos;
  char segundos;
  unsigned mSegundos;
}Cronometro;

Cronometro Crono = {0,0,0};

//1us( contagem dos microsegundos )
void Timer1_Init()
{
    T1CON = 0b00000000; //Prescaler 1:1 e stop
}

//1ms
void Timer0_Init()
{
    OPTION_REG = 0x81; //prescaler 1:4
    TMR0 = 6;   // (4/clock) * (256 - 6) * 4 = 1ms
    TMR0IE_Bit = 0; //stop
}

void Interrupt()
{
 if( TMR0IF_Bit )
 {
    TMR0IF_Bit = 0;
    TMR0 = 6;

    MicroSegundos = 0;
    Crono.mSegundos++;
    if( Crono.mSegundos >= 1000 )
    {
      Crono.mSegundos = 0;
      Crono.segundos++;
      if( Crono.segundos >= 60 )
      {
         Crono.segundos = 0;
         Crono.minutos++;
         if( Crono.minutos >= 99 )
         {
           Crono.minutos = 0;
         }
      }
    }

 }
 else if( INTF_Bit ) // Iniciar/Pausar
 {
    INTF_Bit = 0;
    TMR0IF_Bit = 0;
    TMR0 = 6;
    TMR0IE_Bit = ~TMR0IE_Bit;
    TMR1ON_Bit = ~TMR1ON_Bit;
 }
}

void main()
{
char flag = 0;
#define zerar_flag flag.B1

    CMCON = 7;
    
    Lcd_Init();
    Lcd_Cmd( _LCD_CURSOR_OFF );
    Lcd_Out( 1, 5, " m  s  ms  us" );

    TRISB.B7 = 1;

    GIE_bit = 1;
    PEIE_Bit = 1;
    INTE_Bit = 1;
    
    MicroSegundos = 0;
    Timer0_Init();
    Timer1_Init();

    while(1)
    {
        if( Zerar ) zerar_flag = 1;
        if( !Zerar && zerar_flag )
        {
           zerar_flag = 0;
           Crono.minutos = 0;
           Crono.segundos = 0;
           Crono.mSegundos = 0;
           MicroSegundos = 0;
        }
        
        Lcd_Chr( 2, 5, Crono.minutos/10 + '0' );
        Lcd_Chr_CP( (Crono.minutos%10) + '0' );
        Lcd_Chr_CP(':');
        Lcd_Chr_CP( Crono.segundos/10 + '0' );
        Lcd_Chr_CP( (Crono.segundos%10) + '0' );
        Lcd_Chr_CP(':');
        Lcd_Chr_CP( Crono.mSegundos/100 + '0' );
        Lcd_Chr_CP( (Crono.mSegundos/10%10) + '0' );
        Lcd_Chr_CP( (Crono.mSegundos%10) + '0' );
        Lcd_Chr_CP(':');
        Lcd_Chr_CP( MicroSegundos/100 + '0' );
        Lcd_Chr_CP( (MicroSegundos/10%10) + '0' );
        Lcd_Chr_CP( (MicroSegundos%10) + '0' );
    }

}

13 comentários:

  1. Parabéns pelo site e por mais esse projeto,queria que você se puder me tire uma duvida,como você conhece mais de compiladores,estou usando o Mplab C18,só posso programar em C para a familia PIC 18,você sabe se no MLAB X eu posso programar para as outras familias do PIC(16 ,12 e etc)em C também e se a sintaxe é igual a dos MPLAB antigos ?
    Não estou interessado em programar em assembly e,quero usar outras familias de PIC fora a linha PIC18, se você puder me tirar essa duvida,ficaria grato pois,ai eu decido se migro de compilador ou não!!Desde já agradeço!!!!!!!

    ResponderExcluir
  2. Eu sou o Euritson Simon
    obrigado pelo site...es o maximo preciso da sua ajuda. quero montar um tapete ou estera rolante podes me fornecer um esquema e o seu codigo em linguagem c com o mikroc agradeceria sei que podes. (publica no seu saite) mi deste muita confiança.

    ResponderExcluir
  3. Ola boa tarde, estou tendo dificuldades com este código, estou começando estudar PIC agora. Tentei simular no Proteus e deu erro. No código tem que coloar alguma coisa para ele iniciar?

    ResponderExcluir
  4. Olá Thiago!
    Estou com um problema ao compilar o programa do cronometro, o que utiliza o PIC 16F628A.
    Estou tentando aprender na raça, como sempre fiz, "programar em C" e para isso, estou usando o Compilador da MikroE (MikroC PRO v 6.0.0).
    O que está acontecendo é o seguinte:
    Copiei e colei o programa que aqui programa este que está logo acima e ao clicar em build aparece o seguinte erro: Line 0 Menssage357 (main function is not defined main function is not defined)

    Se o main está definido na linha 77, porque está dando este erro?

    Agradeço desde já, se puder me tirar essa dúvida.

    Valeu!

    Jairo Piran.

    ResponderExcluir
    Respostas
    1. Olá Jairo,
      isso acontece porque o arquivo-fonte por alguma razão não foi adicionado ao projeto. Faça o seguinte:
      Clique no menu Projeto -> Add File To Project... e adicione o arquivo.

      Abraços,
      Tiago.

      Excluir
    2. Valeu mesmo Tiago.
      Com a dica consegui compilar, porém não está simulando no Proteus, simplesmente no LCD não aparece nada, saberia me dizer o que acontece?
      fiz um vídeo da minha tela e te enviei, dá uma olhada aí no seu e-mail.

      Excluir
  5. Montei o circuito porem o display aparece apenas iluminado sem dígitos.A ligação foi cuidadosamente verificada.Usei osc.interno 4M.O que pode estarocorrendo?

    ResponderExcluir
    Respostas
    1. Cara, estou tendo o mesmo problema hoje, e não faço a mínima ideia do que pode estar errado.

      Excluir
  6. Boa noite, primeiro queria dar os parabéns, pelo magnifico trabalho aqui mostrado, criei o projeto pelo código aqui mostrado fiz a simulação no proteus e funcionou beleza, tudo certinho na simulação do proteus, gostaria que me ajudasse na seguinte forma, e se eu quisesse que o cronometro começasse a contar apenas enquanto eu pressiono o botão RB0/INT, e quando eu soltar o cronometro parasse, pergunto como eu poderia fazer, desde ja fico grato pelo exelente trabalho.

    ResponderExcluir
  7. Fiz o teste no protoboard funcionou perfeitamente, depois criei uma pci ao qual inclui duas switches, uma que vai a porta RB0/INT e outra a RB7 ao qual funciona perfeitamente pelo projeto apresentado, sou um especialista em pci e eh a primeira vez que monto um circuito baseado no seu projeto, eh pela primeira vez que executei um projeto baseado em projeto aqui exposto e é gratificante que funcione perfeitamente, fico aqui agradecido e parabenizo a vc por te lo apresentado aqui. Fico soh na espera de ver o desafio a que te propus de fazer com que o cronometro dispare somente enquanto a switche que aciona RB0/INT esteja pressionada, obrigado.

    ResponderExcluir
  8. Eu compilei testei de boa no Proteus, tudo perfeito mas ao testar na Protoboard o display acende todos os caracteres da primeira linha e fica só nisso.
    Fuses configurei assim:
    Oscilador- HS (usei um cristal de 4MHZ)
    Watchdog- disabled
    Power-up Timer - Disabled
    MCLR - Enabled
    Todos os outros fuses desabilitados.
    Alguém sabe o que posso estar fazendo errado?

    ResponderExcluir
  9. Boa noite, estou usando o pic18f4520, porem quanto a isso, é so procurar os registradores equivalentes ao do 16f628a, estou precisando contar o tempo que um botão fica pressionado, é para um botão de reset, porem so vai resetar se apertar por 5 segundos, então preciso lançar um cronometro tipo ao desse post, porem continuar verificando se o botão continua pressionado, caso contrario zera o cronometro, e se ficar pressionado por 5 segundos, ele zera o contador. Pode me ajudar?

    ResponderExcluir