#define F_CPU 1000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#define co_ile_cykli_odswiezanie 5
#define okres_timer2 200

//wartosci są zadeklarowane dla wyswietlacza sterowanego stanem wysoki, zatem przy przypisaniu nalezy wartosci te zanegować
PROGMEM volatile char kody [16] = {0x3F,0x06,0x5B,0x4F, 0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};

volatile char znaki[4];

volatile uint8_t kolumna = 0;
volatile uint8_t ilosc_klikniec = 0;

volatile uint8_t maska_kolumn = 0x00;

ISR(TIMER0_COMP_vect)
{
		kolumna &= 0b00000011;				
		PORTC = 0x0F;							//zapobieganie jażeniu się segmentów, które nie powinny się świeć w danej sekwencji
		PORTA = znaki[kolumna];					//wyswietlanie na liniach segmentów zadanego znaku
		PORTC = (~(1<<kolumna)) | maska_kolumn;	//ustalenie na ktorej kolumnie wyswietlamy symbol oraz przesłonięcie maską wyłączającą segmenty
		kolumna++;				
}

ISR(TIMER2_COMP_vect)
{
	TCCR2 &= ~((1<<CS22) | (1<<CS20));		//wyłączenie TIMER2
	
	if( ~(PIND & (1<<PD2)) ){				//jeżeli przycisk nadal jest wciśnięty inkrementujemy ilość wciśniętych przycisków
		ilosc_klikniec++;	
		if(ilosc_klikniec < 5)				//jęzeli 
		{
			maska_kolumn |= (1<<(4-ilosc_klikniec));		//zrobic negacje tego chyba trzeba!!!!!!!!!!!!!!!!!!!!
		}else{
			GICR &= ~(1<<INT0);				//wyłączenie obsługi przerwania INT0 po osiągnięciu 4 kliknięć
		}					
	}
	GICR |= 1<<INT0;						//włączenie obsługi przerwania INT0						
	GIFR |= 1<<INTF0;						//wyczyszczenie flagi przerwania INT0	
}

ISR(INT0_vect)
{
	GICR &= ~(1<<INT0);					//wyłączenie obsługi przerwania INT0
	TCCR2 |= (1<<CS22) | (1<<CS20);		//ustalenie preskalera na wartosc 1024 i uruchomienie timer2
}

int main(void)
{
	//konfiguracja portów
	DDRA = 0xFF;
	PORTA = 0xFF;
	
	DDRC = 0x0F;
	PORTC = 0x0F;
	
	PORTD = (1<<PD2);	//ustawienie podciągania na lini D2 (INT0)
	
	//konfiguracja TIMER0
	TCNT0 = 0;
	OCR0 = co_ile_cykli_odswiezanie;
	TCCR0 |= 1<<WGM01;		//ustalenie pracy na CTC
	
	//konfiguracja timer2 
	TCNT2 = 0;
	OCR2 = okres_timer2;
	TCCR2 |= 1<<WGM21;	//tryb pracy CTC
	
	//Ustalenie wyświetlanych znaków
	znaki[0] = ~(pgm_read_word_near(kody+0));
	znaki[1] = ~(pgm_read_word_near(kody+10));	
	znaki[2] = ~(pgm_read_word_near(kody+7));
	znaki[3] = ~(pgm_read_word_near(kody+11));
	
	//konfiguracja przerwań
	TIMSK = (1<<OCIE0) | (1<<OCIE2);//Włączenie obsługi przerwań OC0 i OC2
	GICR |= 1<<INT0;				//włączenie obsługi przerwania INT0
	MCUCR |= 1<<ISC01;				//ustalenie wyzwalania przerwania INT0 na zbocze opadające
	sei();	
	
	TCCR0 |= (1<<CS02) 	;	//ustawienie preskalera na wartosc 256 i uruchomiene TIMER0

    while(1)
    {
		PORTB = maska_kolumn;
	}
}

© Wklejaj.pl