Conta até 9999 minutos ou 999 segundos

Neste artigo o leitor aprenderá como montar um cronômetro capaz de contar até 999 minutos ou 999 segundos. O valor a ser contado é programável. Além disso, verá como é simples utilizar a interrupção externa do PIC16F628A, podendo assim incluir estas informações em sua "biblioteca" de consulta sobre microcontroladores.

 

Nota: O artigo saiu numa Eletrônica Total de 2004

 

 

O MICROCONTROLADOR PIC16F628A

Este microcontrolador não é nenhuma novidade para a maioria dos nossos leitores. Porém, para aqueles que não o conhecem, descreveremos agora suas principais características:

- Arquitetura HARVARD

- Memória de programa FLASH com 2 kbytes (reprogramável eletricamente)

- 224 bytes de RAM para dados

- 128 de EEPROM para dados

- 16 pinos de I/O com dreno de corrente na ordem de 20 mA

- Dois comparadores Analógicos

- Dois "timers" de 8 bits e um de 16 bits

- Um canal CCP (Capture, Compare and PWM)

- Um canal USART para comunicação RS-232 ou SPI

- Uma interrupção externa

- Várias opções para oscilador, inclusive interno a 4 MHz

- Watch Dog Timer (cão de guarda) interno

- Controle de "Power-on Reset" e "Power-up Timer"

- Proteção de código contra cópias

- Set de instruções reduzido (35 instruções)

- Encapsulamento DIP com 18 pinos

- Alimentação padrão TTL (5 VDC) - etc.

Para aqueles que desejam maiores informações sobre este microcontrolador, aconselhamos o "download" do "data sheet" no site do fabricante, www.microchip.com.

 

 

COMO FUNCIONA UMA INTERRUPÇÃO?

Nosso leitor sabe que todo microcontrolador precisa de um programa interno para sua operação. Este "programa" nada mais é que uma lista de instruções que o microcontrolador deverá executar. Cada instrução é inserida em um endereço de memória, uma após a outra (em sequência). Através de um registrador, geralmente chamado PC (Program Counter), que é incrementado a cada instrução executada, o microcontrolador sabe em qual posição de memória o programa está. Assim, o microcontrolador segue a seqüência de comandos a serem executados (veja a figura 1).

 


| Clique na imagem para ampliar |

 

 

Obs.: Durante o "reset" de um microcontrolador, o "PC" sempre "aponta" para a primeira posição de memória de programa. Porém, existem momentos em que precisamos "interromper” esta sequência de execução, pois teremos que tratar um processo que não pode esperar ou mesmo tem muito mais importância que todo o restante dos processos tratados durante a execução normal do programa. Isso é feito por uma INTERRUPÇÃO no microcontrolador. Sempre que tivermos uma interrupção, o microcontrolador salvará a posição atual do seu "PC" (endereço atual) e desviará para um endereço de memória fixo para o tratamento do "evento" (interrupção).

Todo microcontrolador possui uma série de interrupções possíveis: do tipo externa por alteração no estado em seus pinos de I/O e interna como USART, TIMER's, AD's, etc. Alguns tipos de microcontroladores possuem endereços diferentes na memória de programa para tratamento de cada uma das suas interrupções. Esse é o caso do 8051, por exemplo.

No microcontrolador PIC16F628A temos um único endereço para o tratamento das várias interrupções existentes. Este endereço (vetor de interrupções) fica na posição de memória 0004H. Ou seja, sempre que o PIC16F628A sofrer uma interrupção, qualquer que seja, o programa será desviado para o endereço 0004H na memória.

O leitor deve estar se perguntando: "Se todas as interrupções desviam para a mesma posição de memória, como o microcontrolador saberá qual interrupção deverá tratar?"

O microcontrolador PIC16F628A possui registradores específicos para "setar" suas interrupções. Sempre que uma interrupção ocorrer no microcontrolador, um bit de um registrador será "setado", antes do desvio. Assim, cabe ao programa analisar nos registradores qual bit foi "setado" e tratar a interrupção conforme a lógica desejada.

Isso pode parecer complicado, mas não é. Lembre-se que quando projetamos um circuito microcontrolado que deverá trabalhar com interrupções, sabemos exatamente quais as INT's que serão utilizadas. Nenhuma interrupção será feita "ao acaso". Ela sempre será "esperada" pelo programa!

Para isso habilitamos o microcontrolador para "receber" as INT's desejadas, e desabilitamos as que não são! Desta maneira, saberemos quais os bits de cada registrador devem ser analisados.

Obs.: Após a execução de uma interrupção, o programa deve prever um "retorno da interrupção". Geralmente, ele é dado por uma instrução específica para tal. Isto é muito importante! Após o retorno, o valor do "PC" será: endereço do PC antes da interrupção mais um.

 

 

A INTERRUPÇÃO EXTERNA NO PIC16F628A

No microcontrolador PIC16F628A, a interrupção externa é feita através do pino "6" (RB0). Neste caso o pino é configurado como entrada do tipo "Schmitt Trigger". A detecção da interrupção pode ser feita na borda (edge) de subida ou descida do pulso. Observe a figura 2.

 


 

 

 

Para usar a interrupção através do pino RBO é necessário:

- no registrador INTCON (endereço OBH - banco O), "setar" os bits:

- GIE (Global Interrupt Enable)

- INTE (External Interrupt Enable)

- no registrador OPTION_REG (endereço 81H - banco 1), "setar" ou "resetar" o bit:

- INTEDG (Interrupt Edge Select Bit)

1 - Para disparo na borda de subida

0 - Para disparo na borda de descida

Após o "setup" do microcontrolador, quando uma interrupção ocorrer através do pino RBO, o programa será desviado para o vetor de interrupção no endereço 0004H, conforme dito anteriormente. Para saber se realmente se trata de uma interrupção externa, o programa deverá:

-no registrador INTCON (endereço OBH — banco O), "analisar" o bit:

- INTF (External Interrupt Flag Bit)

- se "1", houve uma interrupção externa

- se "0", não houve uma interrupção externa.

Obs.: Após o tratamento da interrupção, é necessário "zerar manualmente" o bit INTF.

 

Nota: Quando falamos em "setar" e "resetar" estamos nos referindo a lógica digital. "Setar" deve ser interpretado como fazer igual a "1" lógico, e consequentemente "resetar" quer dizer fazer igual a "O" lógico".

 

O leitor também deve compreender que o tratamento de uma interrupção funciona como se tivéssemos um "segundo" programa interno ao microcontrolador. O "evento" é muitas vezes tratado segundo suas próprias regras. Porém, estamos trabalhando com os mesmos registradores do microcontrolador. Sendo assim, sempre que o programa "entrar" na sub-rotina de tratamento de interrupções, é necessário salvar estes registradores importantes como:

- registrador de trabalho (no caso do PIC, registrador "W")

- registrador de estado (no caso do PIC, registrador "STATUS")

- registrador PC ou parte dele (no caso do PIC, apenas o PCLATH).

Fazendo isso, podemos antes de retornar da interrupção, restaurar os valores anteriores, mantendo assim todos os registradores exatamente como estavam antes da interrupção.

Mais à frente, quando detalharmos a operação do programa, o leitor poderá compreender melhor a configuração e o uso da interrupção externa no PIC16F628A.

 

 

O CIRCUITO

Agora que vimos a teoria necessária sobre interrupções no PIC, vamos à prática! Na figura 3 o leitor tem o circuito do Cronômetro "999". Cl1 é o microcontrolador PIC16F628A. Conectado ao mesmo temos três chaves: S1, S2 e S3. S1 permite reiniciar o microcontrolador, S2 programa o tempo e S3 configura a contagem em minutos ou segundos.

O LED D1 pisca numa frequência de 1 Hz se a contagem for em minutos e 0,5 Hz se a mesma for em segundos. O buzzer BZ1 emitirá um sinal tipo "beep-beep" numa frequência próxima a 1 kHz no final da contagem.

O leitor notará que o pino RBO foi ligado, através de R18 (15 kΩ), a um dos pontos de saída do transformador (secundário).

Apesar de termos um sinal senoidal no pino RBO, este quando configurado para receber a interrupção externa assume uma entrada do tipo "Schmitt Trigger".

Toda porta lógica tem tempos de transição bem definidos. Quando um sinal aplicado à entrada de uma porta lógica tem tempos de transição menores aos valores mínimos permitidos (cada família lógica tem seus próprios valores), verifica-se em sua saída algumas oscilações à medida que o sinal de entrada passa pelo intervalo de "indeterminação".

 


| Clique na imagem para ampliar |

 

 

Uma porta lógica do tipo "Schmitt Trigger" é projetada para aceitar sinais cuja transição é lenta e fornecer uma saída livre de qualquer tipo de oscilação. Esta saída geralmente é muito rápida, com tempos de transição em torno de 10 ns, e é independente das características do sinal de entrada. Desta forma, podemos usar o sinal da frequência da rede elétrica (60 Hz) para realizar a contagem do tempo necessário, de forma muito precisa. Analisando a figura 4, o leitor poderá entender melhor o que foi dito com a comparação dos comportamentos de uma porta inversora comum e uma inversora com entrada Schmitt Trigger.

 


 

 

 

Os displaysDISP1, DISP2 e DISP3 são do tipo "sete segmentos com catodo comum". Note que todos os segmentos, de "a" a "g" são conectados entre si, pois os displays são controlados por varredura, através do chaveamento de Q1 a Q3.

O transformador T1 da fonte deve, necessariamente, ser de 12 V. Não utilize valores maiores, pois o resistor R18 foi dimensionado considerando este valor. Os diodos D2 e D3 formam a etapa de retificação da nossa fonte e os capacitores C2, C3, C4 e C5 os capacitores de filtro. Cl2 é um regulador de voltagem para 5VDC (tensão requerida pelo PIC). O LED D4 serve para indicar a presença da tensão de saída no regulador.

 

 

MONTAGEM

Na figura 5 oferecemos ao leitor nossa sugestão para o lay-out da placa de circuito impresso. Note que temos duas placas separadas. Uma para o cronômetro e outra para a fonte. Isso foi feito para facilitar a instalação do conjunto em um gabinete.

 


| Clique na imagem para ampliar |

 

 

Tenha cuidado ao soldar os componentes polarizados como capacitores eletrolíticos, diodos, transistores, LEDs, reguladores e outros. Use um soquete para Cl1. O regulador de tensão Cl2 necessita de um radiador de calor. Este pode ser do tipo pequeno, para encapsulamento TO-220.

Observe que a placa do cronômetro possui alguns "jumpers". Estes podem ser feitos com pequenos pedaços de fio fino ou ainda com a sobra das "pernas" cortadas de resistores, diodos e outros já soldados a placa. Os displays também merecem atenção ao serem soldados à placa. Qualquer inversão e os valores mostrados não farão sentido algum. O "ponto" do display fica voltado para o lado dos botões S1 e S2. O leitor também poderá utilizar soquetes para os displays, adaptados de soquetes para Cls.

As chaves S1 e S2 são chaves do tipo "push button" mini para circuito impresso. O leitor também poderá utilizar em sua montagem chaves tipo "aéreas" (para fixação no gabinete), ligados com fio à placa. A chave S3 é do tipo "H-H" para circuito impresso ou "aérea". A escolha aqui também é livre.

O "buzzer" (beep) também pode ser soldado a placa ou ligado à mesma através de fio (no caso da instalação em um gabinete). Um detalhe importante sobre o mesmo é o seu tipo. No mercado é possível encontrar basicamente dois tipos: com e sem oscilador interno. O utilizado no projeto deve ser do tipo "sem oscilador interno", pois a oscilação de 1 kHz é feita pelo microcontrolador através do pino RA3.

 

 

O PROGRAMA

Não entraremos em detalhes sobre a gravação do microcontrolador neste artigo. Julgamos que o leitor que se propôs a montar este circuito tem a experiência necessária com microcontroladores e conhece as operações envolvidas no processo de gravação deles. Para os leitores sem experiência no assunto, aconselhamos a leitura do artigo "Microcontroladores PIC — Dicas para montagens de sucesso" do autor Márcio José Soares, publicado na edição n° 98.

O código-fonte do programa "CRONOMETRO_999.ASM" pode ser retirado em nosso site na seção "downloads". Junto ao código-fonte o leitor também encontrará o arquivo "CRONOMETRO_999.HEX" para ser gravado no PIC.

Aconselhamos ao leitor fazer o "download" do código-fonte do programa, para análise e também compreensão do que será dito a seguir.

O programa foi ricamente comentado para facilitar ao máximo sua compreensão. O programa inicia com o "setup" para os pinos de I/O (entrada e saída) através do comando TRISAB. Note que os endereços de "reset" (0000H) e o vetor de interrupções (0004H) foram previamente definidos. No endereço de "reset" existe um desvio para o "label" config_pic. Assim, o programa não permite que o PIC execute a sub-rotina de interrupção, sem que a mesma realmente tenha ocorrido (desvio condicional).

Logo após será configurada a interrupção externa. A mesma é habilitada através de "INTE", depois é selecionado o "Edge" (borda) através do bit INTEDG. Somente então o bit GIE (habilitação global das interrupções) será "setado". Temos a partir de agora, o PIC pronto para receber uma interrupção.

Neste momento a chave S2 é analisada. Se estiver desligada, a contagem será feita em minutos, e se ligada em segundos. A partir deste momento a chave não será mais analisada. Para mudar de minutos para segundos ou vice-versa é preciso, após alterar a posição da mesma, "resetar" o cronômetro através de S1.

Em seguida, o programa analisa a memória EEPROM (endereços 01 H, 02H e 03H). Se for a primeira vez que o programa é executado, o valor da contagem será "000" e neste caso a mesma não é iniciada e os displays informarão o valor "000". Se o programa (cronômetro) já foi utilizado uma vez, um valor estará presente na memória e a contagem será iniciada (regressivamente).

Durante a contagem a chave S2 é analisada. Se pressionada, a contagem para e o valor "000" é inserido no display e o processo é finalizado. Se a mesma continuar pressionada por 2 segundos, o display começará a ser incrementado na velocidade de três unidades por segundo (0,33 s). Isso permite configurar um novo valor para o tempo. Se a chave for "liberada" por um tempo superior a três segundos, o valor mostrado no display começará a piscar, informando que o mesmo foi gravado na EEPROM. Neste momento, para iniciar a contagem basta configurar S3 (minutos ou segundos) e "resetar" o cronômetro pressionando S1.

Durante todo este processo, as variáveis "DISP1", "DISP2" e "DISP3" são lidas e comparadas a uma tabela. Os valores resgatados desta tabela são inseridos no display através do método da varredura.

Note que analisamos somente o programa, sem falar da sub-rotina de interrupção. Como dito anteriormente, ela opera quase que independente do resto do programa. Sua função é apenas contar os pulsos recebidos da rede (60 por segundo) e decrementar as variáveis VAR1, VAR2 e VAR3 de acordo com o estabelecido em S3 (minutos ou segundos).

Na sub-rotina da interrupção os registradores W, STATUS e PCLATH são salvos antes de qualquer tratamento. Somente depois que o pulso é contado e os valores das variáveis alterados. Na saída da sub-rotina de tratamento da interrupção, os valores anteriores de W. STATUS e PCLATH são reestabelecidos. Quando o tempo chegar a "000", o buzzer será disparado e todo o processo será encerrado.

Obs.: O leitor notará no programa que em alguns pontos a interrupção é desabilitada para favorecer o processamento. Via de regra, costuma-se desabilitar a interrupção quando da entrada na sua sub-rotina de tratamento. A habilitação da interrupção é feita no último comando da sub-rotina, antes do retorno da mesma.

 

 

TESTE E USO

Após montar o circuito, faça uma revisão minuciosa em tudo. Não tenha pressa de ligar seu circuito. Antes perder alguns minutos checando tudo do que perder horas, (ou quem sabe dias!), tentando entender o porquê do circuito não funcionar!

Grave o programa descrito anteriormente no microcontrolador e insira este na placa. Ligue o conjunto. O valor "000" deve ser mostrado no display. Selecione em S3 a posição para segundos (S3 fechada). Pressione S2 até a marcação do tempo iniciar. Marque, por exemplo, 15 segundos (015). Solte S2 e aguarde o valor "015", demonstrado no display piscar. Neste momento, pressione S1. O sistema será "resetado" e logo em seguida a contagem será iniciada. Note que a mesma é do tipo "regressiva". Quando o tempo for igual a "000", o buzzer será ligado.

Agora repita a mesma operação com S3 aberta. A contagem será feita em minutos.

 

 

CONCLUSÃO

Neste artigo o leitor pôde ver como é bastante simples utilizar a interrupção externa do microcontrolador PIC16F628A, através de RBO (para outros microcontroladores da série, como o PIC16F877, a metodologia é a mesma) na construção de um cronômetro (contagem de tempo). Para os leitores que lidam com automação, o programa pode ser adaptado para contar eventos dando uma nova função ao "Cronômetro 999". Boa montagem e até a próxima!

 


| Clique na imagem para ampliar |