Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Timer com PIC16F628A e Display de 7 Segmentos.
/*
Timer com PIC16F628A e Display de 7 Segmentos.
Autor: Tiago Melo
Blog: Microcontrolandos
Compilador: MikroC PRO PIC
Bibliotecas:
*/
//Botões
sbit BotaoAjustar at RA0_bit;
sbit BotaoStartPause at RA1_bit;
sbit BotaoSegMin at RA2_bit;
sbit BotaoAjustar_Direction at TRISA0_bit;
sbit BotaoStartPause_Direction at TRISA1_bit;
sbit BotaoSegMin_Direction at TRISA2_bit;
//Display
char SaidaDisplay at PORTB;
char SaidaDisplay_Direction at TRISB;
sbit Display1 at RA6_bit;
sbit Display2 at RA7_bit;
sbit Display1_Direction at TRISA6_bit;
sbit Display2_Direction at TRISA7_bit;
//Buzzer.
sbit Buzzer at RA3_bit;
sbit Buzzer_Direction at TRISA3_bit;
//Algumas flags.
char flags = 0;
//Indica que o timer foi iniciado(1) ou pausado(0).
sbit iniciou at flags.B0;
//Indica que o tempo esgotou.
sbit tempoEsgotado at flags.B1;
//Flags que guardam o estado atual dos botões.
sbit ajustarFlag at flags.B2;
sbit startPauseFlag at flags.B3;
sbit segMinFlag at flags.B4;
//Contador.
unsigned contador = 0;
//armazena os segundos e minutos (0 até 59).
signed char segundos = 0;
signed char minutos = 0;
//Números para o display de 7 segmentos Catodo comum.
char numeros[10] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111};
//Aponta para o contador atual selecionado pelo botão Seg/Min.
char * valorAtual = &segundos;
//A interrupção ocorrerá a cada 1ms.
void interrupt() {
//Reinicia o contador do timer0.
TMR0 = 6;
if(iniciou) {
//Incrementa o contador.
contador++;
//Se o contador = 1000, completou 1s.
if(contador >= 1000) {
contador = 0;
//Decrementa os segundos.
segundos--;
//Tempo Esgotado.
if(segundos == 0 && minutos == 0) {
iniciou = 0;
//Ativa o buzzer.
tempoEsgotado = 1;
Buzzer = 1;
}
//Ultrapassou o valor mínimo.
else if(segundos < 0) {
segundos = 59;
//Decrementa os minutos.
minutos--;
//Se chegar no minuto 0, automaticamente exibir os segundos.
if(minutos == 0) {
valorAtual = &segundos;
} else if(minutos < 0) {
minutos = 0;
}
}
}
}
//Limpa a flag de interrupção.
INTCON.T0IF = 0;
}
void main() {
//Configura os pinos dos botões como entrada.
BotaoAjustar_Direction = 1;
BotaoStartPause_Direction = 1;
BotaoSegMin_Direction = 1;
//Configura os pinos de saída para o display.
SaidaDisplay_Direction = 0;
SaidaDisplay = 0;
Display1_Direction = 0;
Display2_Direction = 0;
Display1 = 0;
Display2 = 0;
//Desabilita os comparadores anlógicos.
CMCON = 7;
//Buzzer.
Buzzer_Direction = 0;
Buzzer = 0;
//Configura timer0 (prescaler 1:4)
OPTION_REG = 0b00000001;
//tempo = 4 / 4000000us * 4(prescaler) * 250(256 - 6) = 1000us = 1ms
TMR0 = 6;
INTCON.GIE = 1; //habilita interrupcap global
INTCON.T0IE = 1; //habilita interrupcao do timer0
while(1) {
//O Botão foi pressionado.
if(!ajustarFlag && BotaoAjustar) {
//Salva seu estado.
ajustarFlag = 1;
}
//O Botão foi pressionado.
if(!startPauseFlag && BotaoStartPause) {
//Salva seu estado.
startPauseFlag = 1;
}
//O Botão foi pressionado.
if(!segMinFlag && BotaoSegMin) {
//Salva seu estado.
segMinFlag = 1;
}
//Ajuste.
if(ajustarFlag && !BotaoAjustar) {
//Salva seu estado.
ajustarFlag = 0;
//Incrementa o valor atual.
(*valorAtual)++;
//Reseta o contador.
contador = 0;
}
if(startPauseFlag && !BotaoStartPause) {
//Salva seu estado.
startPauseFlag = 0;
//O Buzzer esta tocando...
if(tempoEsgotado) {
tempoEsgotado = 0;
Buzzer = 0;
} else {
//Alterna entre iniciou ou pausou.
iniciou = !iniciou;
}
}
//Segundos ou Minutos.
if(segMinFlag && !BotaoSegMin) {
//Salva seu estado.
segMinFlag = 0;
//Se o valor atual aponta para segundos,
//alterá-lo para minutos. Caso contário,
//alterá-lo para segundos.
if(valorAtual == &segundos) valorAtual = &minutos;
else valorAtual = &segundos;
}
//Exibir os digitos.
{
//Valor a ser exibido em cada dígito do display.
char valorExibido = *valorAtual;
char digito1 = valorExibido / 10;
char digito2 = valorExibido % 10;
//Limpa o display.
SaidaDisplay = 0;
//Habilitar o display 1.
Display1 = 0;
Display2 = 1;
//Exibe o número no display.
SaidaDisplay = numeros[digito1];
//Atraso entre a exibição de um digito e outro.
Delay_ms(1);
//Limpa o display.
SaidaDisplay = 0;
//Habilita o display 2.
Display1 = 1;
Display2 = 0;
//Exibe o número no display.
SaidaDisplay = numeros[digito2];
//Se estiver exibindo os minutos, o ponto decimal será exibido.
if(valorAtual == &minutos) {
SaidaDisplay.B7 = 1;
}
//Atraso entre a exibição de um digito e outro.
Delay_ms(1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.