Last active
March 22, 2023 05:24
-
-
Save tiagohm/99c4e758ba328177654ac045b814499a to your computer and use it in GitHub Desktop.
Timer com PIC16F628A e Display de 7 Segmentos.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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
Amigo você tem o esquema de ligações?