/**************************************************************
   Schemat podłączeń programowanego układu

                 +----v----+
           MCLR [| 1     40|] 
                [| 2     39|] 
                [| 3     38|] 
                [| 4     37|] 
                [| 5     36|] 
                [| 6     35|] 
                [| 7     34|] 
                [| 8     33|] RB0/INT <- S1
                [| 9     32|] VDD
                [|10     31|] VSS
            VDD [|11     30|] 
            VSS [|12     29|] 
(20 MHz) / OSC1 [|13     28|]
         \ OSC2 [|14     27|]
                [|15     26|] 
                [|16     25|] 
                [|17     24|]
                [|18     23|] 
      D1 <- RD0 [|19     22|] 
      D2 <- RD1 [|20     21|] 
                 +---------+
                 PIC16F877A
***************************************************************/

#include <htc.h>

//oscylator 20 MHz (FOSC_HS)
//watchdog wyłączony (WDTE_OFF)
//wyłączone LVP (Low-Voltage ICSP Programming) (LVP_OFF)
__CONFIG(FOSC_HS & WDTE_OFF & LVP_OFF);

//zmienne globalne (muszą być widoczne w funkcji obsługi przerwania)
unsigned char licznik_D1, licznik_D2;

void main()
{
	TRISDbits.TRISD0 = 0;		//linia RD0 wyjściowa
	TRISDbits.TRISD1 = 0;		//linia RD1 wyjściowa
	PORTDbits.RD0 = 0;			//dioda D1 nie świeci
	PORTDbits.RD1 = 0;			//dioda D2 nie świeci

	//konfiguracja przerwania RB0/INT
	OPTION_REGbits.INTEDG = 0;	//reakcja na zbocze opadające
	INTCONbits.INTE = 1;		//włącz przerwanie RB0/INT

	//konfiguracja przerwania modułu Timer1
	TMR1H = 0x9E;				//TMR1 = 40536
	TMR1L = 0x58;				//(65536 - 40536)/5 * 25 = 125000
	//T1CONbits.T1CKPS1 = 0;	//brak preskalera
	//T1CONbits.T1CKPS0 = 0;	//brak preskalera
	PIE1bits.TMR1IE = 1;		//włącz przerwanie Timer1
	T1CONbits.TMR1ON = 1;		//włącz moduł Timer1

	licznik_D1 = 0;				//wyzerowanie licznika diody D1
	licznik_D2 = 0;				//wyzerowanie licznika diody D2
	INTCONbits.PEIE = 1;		//włączenie przerwań urządzeń peryferyjnych
	INTCONbits.GIE = 1;			//globalne włączenie przerwań

	for(;;)						//pętla nieskończona
	{
	}
}

static void interrupt
knowania_przerwania(void)
{
	if(PIR1bits.TMR1IF == 1)	//przerwanie modułu Timer1
	{
		//obsłuż diodę D1
		licznik_D1++;			//inkrementuj licznik
		if(licznik_D1>24)
		{
			PORTDbits.RD0 ^= 1;	//przełącz stan diody D1
			licznik_D1 = 0;		//wyzeruj licznik
		}
		//obsłuż diodę D2
		if(licznik_D2 > 0)
		{
			PORTDbits.RD1 = 1;	//zaświeć diodę D1
			licznik_D2--;		//dekrementuj licznik
		}else PORTDbits.RD1 = 0;//inaczej zgaś diodę D2
		//obsłuż moduł Timer1
		TMR1H = 0x9E;			//TMR1 = 40536
		TMR1L = 0x58;			//(65536 - 40536)/5 * 25 = 125000
		PIR1bits.TMR1IF = 0;	//wyczyść flagę przerwania
	}
	if(INTCONbits.INTF == 1)	//przerwanie RB0/INT 
	{				
		licznik_D2 = 200;		//zaświeć diodę D2 na czas 1 sekundy
		INTCONbits.INTF = 0;	//wyczyść flagę przerwania
	}
}

