Fork me on GitHub

24/12/12

Projeto 18: Timer com PIC16F877A

Timer com PIC16F877A



Trata-se de um Timer/Temporizador que pode ser usado para desligar/ligar alguma carga depois de um certo tempo, e pode ser ajustado entre alguns segundos até 59 horas e 59 minutos.


Funcionamento: o botão MS<->HM é usado para alterar entre contagem de minutos:segundos ou horas:minutos. Quando ajustado para minutos:segundos o botão SEG/MIN ajustará os segundos e o botão MIN/HRS ajustará os minutos. Quando ajustado para horas:minutos os botões sitados anteriormente ajustará os minutos e as horas respectivamente.

O botão START/PAUSE como o nome já diz, faz a inicialização do tempo e a pausa do tempo. o botão RESET desliga o alarme e zera o display.

Observe que há dois leds, um verde e um azul. O Led Verde ficará permanentemente acesso quando a contagem está em andamento. Quando está pausado ou o tempo foi finalizado, o led ficará piscando. O Led Azul ficará acesso se a opção de horas:minutos for ativada. Caso contrário ficará apagada.

Foi utilizado quatro displays de 7 segmentos CC( Catodo Comum). Na montagem do circuito, cada pino do display deve ser conectado a um resistor de 220 Ohm.

No projeto eu utilizei um decodificador BCD/7 Segmentos, o CI 4511. Ao invés disso, poderia também ter utilizado as 7 saídas da PORTB. Ao utilizar o CI 4511 acaba utilizando apenas 4 pinos. Fica a critério de vocês, caros leitores.

Você pode substituir o alarme e acionar um relê para poder desligar aparelhos eletrônicos como rádio, tv, som.

Cálculo do tempo:
t = ciclo de máquina * prescaler * contagem;
t = ( 4/4) * 4 * (255 - 135);
t = 1 * 4 * 100 = 400us;
400us * Factor = 400 * 2500 = 1s ou 400 * 150000 = 1min.

DOWNLOAD
Firmware: Timer.hex;
Arquivo de Simulação no Proteus: Timer.DSN;
Arquivo-Fonte:Timer.asm;

CóDIGO-FONTE:
//VARIAVEIS
long cnt,Factor;
short minutos,segundos;
char m1,m2,s1,s2;
bit start,oldstate1,oldstate2,oldstate3,oldstate4;

//ROTINA DE INTERRPÇÃO
void interrupt(){
if(INTCON.TMR0IF){
TMR0 = 155;
cnt++;
INTCON.TMR0If=0;
}
}

void main() {
//CONFIGURAÇÃO DOS REGISTROS
OPTION_REG=0b00000001;
INTCON.GIE=1;
INTCON.PEIE=1;
INTCON.TMR0IE=1;
TMR0=155;
TRISC=0b00011111;
TRISB=0;
TRISD=0;
PORTC=0;

//DEFINIÇÃO DE VALOR DAS VARIÁVEIS
segundos=0;
minutos=0;
Factor=2500;

//BIT DE STATUS
start=0;
oldstate1=0;
oldstate2=0;
oldstate3=0;
oldstate4=0;

while(1){
 if(cnt>=Factor){
  cnt=0;
        if(start){
        segundos--;
        if(segundos<0 dos="" else="" if="" minutos--="" minutos..........="" minutos="0;" oldstate1="0;" oldstate3="0;" oldstate4="0;" portc.f5="~PORTC.F5;" portc.f7="0;//BUZZER" segundos..............="" segundos="0;" start="0;"> HORAS-MINUTOS...
if(PORTC.F4){
 oldstate2=1;
}
if(!PORTC.F4 && oldstate2){
     if(Factor==2500){
      Factor=150000;
      PORTC.F6=1;
     }else if(Factor==150000){
      Factor=2500;
      PORTC.F6=0;
     }
     oldstate2=0;
}

//DIGITOS
m1 = minutos/10;
m2 = minutos%10;
s1 = segundos/10;
s2 = segundos%10;

//DISPLAY DE 7 SEGMENTOS
PORTD=0b00000111;
PORTB=s2;
delay_ms(1);
PORTD=0b00001011;
PORTB=s1;
delay_ms(1);
PORTD=0b00001101;
PORTB=m2;
delay_ms(1);
PORTD=0b00001110;
PORTB=m1;
delay_ms(1);
}
}

48 comentários:

  1. amigo como posso troca para o pic16f628A e tambem tira o CI 4511.
    obrigado.

    ResponderExcluir
    Respostas
    1. Ola! O pic16f628A possui apenas 16 pinos, e o projeto utilizará, caso você retire o CI 7511,no minimo 17 pinos. Aconselho você a utilizar o CI ou utilzar outro PIC com um numero maior de pinos.

      Para retirar o CI 7511 você terá que utilizar 7 pinos da PORTB.

      Excluir
  2. amigo obrigado pela resposta, mas se eu quiser colocar 2 display 7 segmentos pic16f628A da para fazer.
    Obrigado

    ResponderExcluir
    Respostas
    1. Com certeza, pois você irá utilizar somente dois pinos de seleção do display, ao invés dos 4 pinos(RD0,RD1,RD2,RD3).

      Irei postar um circuito de timer utilizando o pic16f628A.

      Excluir
  3. Tiago Henrique, Feliz Ano Novo Para Você e Toda sua Familia.
    Florisvaldo.

    ResponderExcluir
    Respostas
    1. Muito obrigado Florisvaldo, Também te desejo um Feliz Ano Novo!!!

      Excluir
  4. Boa noite Tiago.

    Gostaria de saber o que eu preciso mudar para aumentar o tempo para o dobro deste esquema

    Abraços kin

    ResponderExcluir
    Respostas
    1. Boa noite!
      Não entendi, vc quer que o tempo seja maior que 60 horas?

      Excluir
  5. Muito bom o projeto. To procurando um projeto tipo esse, mas é o com o PIC12F675, usando o timer1 , oscilador interno para contar exatas 168 horas e desligar um motor. Todo o hardware esta pronto, usando optoisolador e triac. Também já tenho um código pronto, mas não esta rodando com precisão. Você tem alguma dica para obter precisão ? Seria ideal usar um cristal de 32768Hz ??? Acho que tem como ligar um cristal para o timer1, mas não sei como fazer... se puder ajudar. Obrigado.

    ResponderExcluir
  6. ...qual variavel que tenho que salvar na eeprom para posterior leitura;caso tenho que armazenar o valor.Depois que ligar o pic novamente.

    ResponderExcluir
  7. OLA, parabens pelo site! Estou aprendendo muito. Como separo o comando start/pause(projeto timer), ou seja um botão para cada?

    ResponderExcluir
  8. Ola amigo porque quando eu gravo o arquivo no pic ele da erro 3f7a então eu ligo o pic e apenas a função start não funciona.

    ResponderExcluir
  9. Tem como exportar para ARES PCB o projeto to tendo dificuldade em alguns componentes que não encontra na biblioteca, como o display e os botões!

    ResponderExcluir
  10. olha Tiago não entendo a linha 45 do programa ao similar no mikroc xta a dar erro... esplca-me por favor Tiago preciso mesmo. Sou o Euritson Simon

    ResponderExcluir
    Respostas
    1. nessa linha 45, o Blogger cagou no codigo e exibiu errado...Agora nao sei qual o codigo que esta ali.

      Excluir
    2. Eu quero usar este projeto para acionamento de um motor o que faço Tiago...Euritson

      Excluir
  11. Olá amigo, poxa to quebrando a mente pra descobrir o que ta erado na linha 45 não tem jeito de compilar o cod.!! ajuda nos Tiago kkkkkkkk, Att: Pisetta..

    ResponderExcluir
  12. Boa noite Tiago tem como você me mandar o projeto completo?
    Att. Rodrigo
    E-Mail: chocotimer@gmail.com

    ResponderExcluir
  13. Boa noite amigo você não esta mais respondendo as perguntas? gostei muito do seu projeto, tenho pouco conhecimento neste formato de programa gostaria de saber se tem como você me passar o layout da placa deste projeto, desde já parabens pelos seus projetos.

    ResponderExcluir
  14. Olá Thiago eu copilei esse programa do projeto 18 timer com pic16f877a que você passo e apareceu um erro na linha 45 será que você pode me ajudar.

    if(segundos<0 dos="" else="" if="" minutos--="" minutos..........="" minutos="0;" oldstate1="0;" oldstate3="0;" oldstate4="0;" portc.f5="~PORTC.F5;" portc.f7="0;//BUZZER" segundos..............="" segundos="0;" start="0;"> HORAS-MINUTOS...

    ResponderExcluir
  15. Ola galera gostaria de saber se alguém já descobriu qual é o erro existente na linha 45 se souber da um salve vlw mesmo grato.

    ResponderExcluir
  16. //VARIAVEIS
    long cnt,Factor;
    short minutos,segundos;
    char m1,m2,s1,s2;
    bit start,oldstate1,oldstate2,oldstate3,oldstate4;

    //ROTINA DE INTERRPÇÃO
    void interrupt(){
    if(INTCON.TMR0IF){
    TMR0 = 155;
    cnt++;
    INTCON.TMR0If=0;
    }
    }

    void main() {
    //CONFIGURAÇÃO DOS REGISTROS
    OPTION_REG=0b00000001;
    INTCON.GIE=1;
    INTCON.PEIE=1;
    INTCON.TMR0IE=1;
    TMR0=155;
    TRISC=0b00011111;
    TRISB=0;
    TRISD=0;
    PORTC=0;

    //DEFINIÇÃO DE VALOR DAS VARIÁVEIS
    segundos=0;
    minutos=0;
    Factor=2500;

    //BIT DE STATUS
    start=0;
    oldstate1=0;
    oldstate2=0;
    oldstate3=0;
    oldstate4=0;

    while(1){
    if(cnt>=Factor){
    cnt=0;
    if(start){
    segundos--;
    if(segundos<0){
    segundos=59;
    minutos--;
    if(minutos<0){
    PORTC.F7=1;//BUZZER
    minutos=0;
    segundos=0;
    start=0;
    }
    }
    }
    }

    //........AJUSTE DOS SEGUNDOS..............
    if(PORTC.F0){
    oldstate3=1;
    }
    if(!PORTC.F0 && oldstate3){
    oldstate3=0;
    segundos++;
    if(segundos==60) segundos=0;
    }

    //.......AJUSTE DOS MINUTOS..........
    if(PORTC.F1){
    oldstate4=1;
    }
    if(!PORTC.F1 && oldstate4){
    oldstate4=0;
    minutos++;
    if(minutos==60) minutos=0;
    }




    //..........START/PAUSE............
    if(PORTC.F2){
    oldstate1=1;
    }
    if(!PORTC.F2 && oldstate1){
    oldstate1=0;
    start = ~start;
    }

    //.....SINALIZAÇÃO START/PAUSE.....
    if(start){
    PORTC.F5=1;
    }else{
    PORTC.F5= ~PORTC.F5;
    }

    //.............RESET..............
    if(PORTC.F3){
    segundos=0;
    minutos=0;
    start=0;
    PORTC.F7=0;//BUZZER
    }


    //..MINUTOS-SEGUNDOS <=> HORAS-MINUTOS...
    if(PORTC.F4){
    oldstate2=1;
    }
    if(!PORTC.F4 && oldstate2){
    if(Factor==2500){
    Factor=150000;
    PORTC.F6=1;
    }else if(Factor==150000){
    Factor=2500;
    PORTC.F6=0;
    }
    oldstate2=0;
    }

    //DIGITOS
    m1 = minutos/10;
    m2 = minutos%10;
    s1 = segundos/10;
    s2 = segundos%10;

    //DISPLAY DE 7 SEGMENTOS
    PORTD=0b00000111;
    PORTB=s2;
    delay_ms(1);
    PORTD=0b00001011;
    PORTB=s1;
    delay_ms(1);
    PORTD=0b00001101;
    PORTB=m2;
    delay_ms(1);
    PORTD=0b00001110;
    PORTB=m1;
    delay_ms(1);
    }
    }

    ResponderExcluir
  17. Sr. não consigo baixar o código , outra coisa como posso fazer um relógio desta rotina, e copilar no ccs
    desde-ja muito obrigado

    ResponderExcluir
  18. Olá amigo, como ficaria o projeto se o botão start/pausa fosse. Liga para o start e desliga para pause ( botão com retenção ). Pois o projeto atual usa um botão vai e volta ( sem retenção ).

    ResponderExcluir
  19. ola,como faço para inverter, emvez de ligar o buzz. ele desligar.gostaria de fazer quando o contador chegar em '0' ele desligar.teria como?

    ResponderExcluir
  20. Tiago , bom dia , meu amigo voce poderia me ajudar por favor , estou com um codigo fonte de um termostato ,e nao estou conseguindo compilar o codigo para gerar o arquivo .exe , sempre da um erro , vou enviar o codigo para seu e-mail ,nao sei como colocar aqui no blog ,se voce puder me ajudar e compilar o codigo para mim , lhe agradeço muito .

    ResponderExcluir
  21. Tiago, vc poderia fazer um projeto igual a esse usando uma tela ldc 16x2?
    ficarei muito grato

    ResponderExcluir

  22. Olá projeto muito bom , eu queria saber se você pode gravar em um pic 16F877 , e não um 16F877A pic , porque eu tenho o primeiro ?? , também me lança um registro de erro me diz que o código está protegido,saudações espero sua resposta , muito obrigado

    ResponderExcluir
  23. como adiciono um led piscando no intervalo de 500ms pra dividir os displays de minutos e segundos ?]
    no caso usarei 4 displays individuais, e queria colocar um led piscando no centro

    ResponderExcluir
  24. Percebi que a cada ciclo de um minuto o contador perde 3s e só começa a rodar de pois de 16 a 25 seg no proteus. sera que na placa com pic gravado tem essa perda de tempo. Grato amigo.

    ResponderExcluir
    Respostas
    1. BOA NOITE AMIGO, A MAIORIA DOS PROJETOS QUANDO COLOCAMOS PARA RODAR NO PROTEUS TEM PERDA, MAS NA PLACA RODA PERFEITAMENTE

      Excluir
  25. boa noite tem como postar um timer decrescente que quando acionado ligue um rele e delige ao final do tempo, mas esse ajuste tipo 30 segundos fique sempre programado sem precisar reajustar?

    ResponderExcluir
  26. boa noite tem como postar um timer decrescente que quando acionado ligue um rele e delige ao final do tempo, mas esse ajuste tipo 30 segundos fique sempre programado sem precisar reajustar?

    ResponderExcluir
  27. Colocar um cristal oscilador externo melhora?
    Aceito sugestões

    ResponderExcluir
  28. Obrigado vou testar. Adicionei mais um pic. Para incrementar ate 59 e depois da o start.

    ResponderExcluir
  29. Obrigado vou testar. Adicionei mais um pic. Para incrementar ate 59 e depois da o start.

    ResponderExcluir

Postagens Relacionadas!!