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

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

***************************************************************/

//definiujemy szybkość oscylatora dla funkcji __delay_
#define _XTAL_FREQ 20000000
#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);

unsigned int czas_impulsu = 7500;

void main()
{
	ADCON1 = 0x06;			//wyłączenie linii analogowych 
                    		//(wszystkie linie cyfrowe)
 	TRISCbits.TRISC2 = 0;	//linia RC2/CCP1 wyjściowa
	TRISDbits.TRISD1 = 1;	//linia RD1 z przyciskiem S1 wejściowa
	TRISDbits.TRISD2 = 1;	//linia RD2 z przyciskiem S2 wejściowa

	//konfiguracja modułu CCP1
  	CCP1CON = 0x0B; 		//(tryb Compare, Special Trigger Event)           							
  	PIE1bits.CCP1IE = 1;	//włącz przerwanie modułu CCP1
  	PIR1bits.CCP1IF = 0;	//wyzeruj flagę przerwania
	PORTCbits.RC2 = 0;		//impuls niski
	CCPR1 = 0xFFFF;			//czas wypełnienia = 13107 us

	//konfiguracja modułu Timer1
	PIE1bits.TMR1IE = 0;	//wyłącz przerwanie Timer1
	T1CONbits.TMR1ON = 1;	//włącz moduł Timer1
	TMR1 = 0;				//wyzeruj rejestr TMR1

	INTCON = 0xC0;  		//włącz obsługę przerwań

	for(;;)						//pętla nieskończona
	{
		//sprawdź przycisk S1
		if(PORTDbits.RD1 == 0)
		{
			czas_impulsu -= 10;	//zmniejsz kąt
			if(czas_impulsu < 3500) czas_impulsu = 3500;
			__delay_ms(50);		//czekaj do czasu ustabilizowania impulsu
		}
		//sprawdź przycisk S2
		if(PORTDbits.RD2 == 0)
		{
			czas_impulsu += 10;	//zwiększ kąt
			if(czas_impulsu > 11500) czas_impulsu = 11500;
			__delay_ms(50);		//czekaj do czasu ustabilizowania impulsu
		}
	}
}

static void interrupt
knowania_przerwania(void)
{
	if (PIR1bits.CCP1IF)			//przerwanie CCP1
  	{
   		if(PORTCbits.RC2 == 0)		//jeśli linia RC2/CCP1 była wyzerowana
   		{
			PORTCbits.RC2 = 1;		//ustaw linię RC2/CCP1
			CCPR1 = czas_impulsu;	//czas impulsu
    	}
    	else 						//jeśli linia RC2/CCP1 była ustawiona
    	{
			PORTCbits.RC2 = 0;		//wyzeruj linię RC2/CCP1
			CCPR1 = 0xFFFF;			//czas wypełnienia = 13107
    	}
		PIR1bits.CCP1IF = 0;		//wyzeruj flagę przerwania (zezwól na nowe przerwanie)
	}
}
