Se você curtir esse artigo, não esqueça de dar uns cliques nos anúncios para ver o que os anunciantes tem para te oferecer. Vou ficar muito contente.
O programa completo
/*
* ContadorHexa.c
*
* Created: 28/04/2019 19:40:15
* Author : Renato de Pierri
*/
#include <avr/io.h>;
#include <stdint.h>;
#include <avr/interrupt.h>;
void inicializaTimerContador ();
void inicializaTimerRefreshDisplay(uint8_t milliS);
void refreshDisplay();
int8_t decoder_4bit_7segment(int8_t input);
uint16_t Contador = 0;
// Rotina de interrupção que incrementa o contador
ISR(TIMER1_COMPA_vect, ISR_BLOCK){
Contador ++;
}
// Rotina de interrupcao que atualiza o display
ISR(TIMER0_COMPA_vect){
refreshDisplay();
}
// Inicializa o Timer1 para gerar uma interrupcao a cada meio segundo aproximadamente
void inicializaTimerContador(){
TCCR1A |= 0; // Habilitando Timer 1
TCCR1B |= (1 << WGM12); // Ajustando Timer/Counter1 para modo CTC "Clear Timer on Compare"
/*
*Ajustando o valor de comparacao do CTC
*para 10Hz (100mS) com clock de 16MHz e prescaler de 64
*/
OCR1A = 25000;
TIMSK1 |= (1 << OCIE1A); // Habilita interrupcao CTC
TCCR1B |= ((1 << CS10) | (1 << CS11)); // Iniciando o Timer/Counter1 @ F_CPU/64
sei(); // Habilita interrupcao global
}
// Inicializador do temporizador de refresh para atualizar o display a cada 30ms aproximadamente
void inicializaTimerRefreshDisplay(uint8_t milliS){
TCCR0A |= (1<<WGM01); // Ajusta o contador TC0 para operar no modo CTC "Clear Timer on Compare"
TCCR0B |= (1<<CS02) | (1<<CS00); // Ajusta o prescaler do contador de 8 bits TC0 para 1024
OCR0A = milliS;
TIMSK0 |= (1<<OCIE0A); // Gera interrupção quando o valor OCR0A bater com o valor do TCNT0
}
int main(void)
{
inicializaTimerContador();
inicializaTimerRefreshDisplay(2);
// Configura as portas do Arduino para saída (pinMode)
DDRB = (1<<DDB0) | (1<<DDB1) | (1<<DDB2) | (1<<DDB3);
DDRD = 0xFF;
while (1)
{
//fica em loop até que ocorra uma interrupcao
}
}
void refreshDisplay(){
int8_t controle = 0, seteSegmentos, display;
int8_t digito[5] = {0,0,0,0,0};
// Le o Contador e separa de 4 em 4 bits
digito[0] = Contador & 0x000F;
digito[1] = (Contador & 0x00F0) >> 4;
digito[2] = (Contador & 0x0F00) >> 8;
digito[3] = (Contador & 0xF000) >> 12;
display = 1;
while (controle <<= 4) {
// decodifica cada um dos 4 bits em sete segmentos
seteSegmentos = decoder_4bit_7segment(digito[controle]);
if (controle >= 1){
display = 2 * display;
}
PORTB = 0x00;
PORTD = 0xFF;
//Atualiza o dígito. display é o nr do dígito, seteSegmentos é o numero
PORTB = display;
PORTD = seteSegmentos;
controle ++;
}
controle = 0;
}
int8_t decoder_4bit_7segment(int8_t input){
/*
*Equação lógica montada com ajuda do Logisim (podia ser na mão).
*Ela é aplicada diretamente
*
*outA = ~iD ~iC ~iB iA + ~iD iC ~iB ~iA + iD ~iC iB iA + iD iC ~iB iA
*outB = ~iD iC ~iB iA + iC iB ~iA + iD iB iA + iD iC ~iA
*outC = ~iD ~iC iB ~iA + iD iC ~iA + iD iC iB
*outD = ~iD ~iC ~iB iA + ~iD iC ~iB ~iA + iC iB iA + iD ~iC iB ~iA
*outE = ~iD iA + ~iC ~iB iA + ~iD iC ~iB
*outF = ~iD ~iC iA + ~iD ~iC iB + ~iD iB iA + iD iC ~iB iA
*outG = ~iD ~iC ~iB + ~iD iC iB iA + iD iC ~iB ~iA
*
*~iA = iAnot, ~iB = iBnot ...
*/
int8_t iA, iB, iC, iD, iAnot, iBnot, iCnot, iDnot;
int8_t outA, outB, outC, outD, outE, outF, outG;
int8_t seteSegmentos = 0;
//Manipulando os bits para que fiquem todos na
//mesma posição e negados, conforme necessário
iA = input & 0x01;
iB = input & 0x02;
iC = input & 0x04;
iD = input & 0x08;
iB = iB >> 1;
iC = iC >> 2;
iD = iD >> 3;
iAnot = iA;
iBnot = iB;
iCnot = iC;
iDnot = iD;
iAnot ^= 1 << 0;
iBnot ^= 1 << 0;
iCnot ^= 1 << 0;
iDnot ^= 1 << 0;
/* Mandrakaria ativar! */
outA = ( iDnot & iCnot & iBnot & iA ) | ( iDnot & iC & iBnot & iAnot ) |
( iD & iCnot & iB & iA ) | ( iD & iC & iBnot & iA );
outB = ( iDnot & iC & iBnot & iA ) | ( iC & iB & iAnot ) |
( iD & iB & iA ) | ( iD & iC & iAnot );
outC = ( iDnot & iCnot & iB & iAnot ) | ( iD & iC & iAnot ) |
( iD & iC & iB );
outD = ( iDnot & iCnot & iBnot & iA ) | ( iDnot & iC & iBnot & iAnot ) |
( iC & iB & iA ) | ( iD & iCnot & iB & iAnot );
outE = ( iDnot & iA ) | ( iCnot & iBnot & iA ) |
( iDnot & iC & iBnot );
outF = ( iDnot & iCnot & iA ) | ( iDnot & iCnot & iB ) |
( iDnot & iB & iA ) | ( iD & iC & iBnot & iA );
outG = ( iDnot & iCnot & iBnot ) | ( iDnot & iC & iB & iA ) |
( iD & iC & iBnot & iAnot );
seteSegmentos = outA|(outB<<1)|(outC<<2)|(outD<<3)|(outE<<4)|(outF<<5)|(outG<<6);
/* Mandrakaria desativar! */
return seteSegmentos;
}