Arduino e contador hexa – bastidores. Parte 4.

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;
}

Last updated by at .

Deixe um comentário