/**************************************************************
   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|] 
           D1 <- 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);

int wypelnienie = 512;

void main()
{
	ADCON1 = 0x06;			//wyłączenie linii analogowych 
                    		//(wszystkie linie cyfrowe)

	///////////////////////////////////////////////////////
	//Konfiguracja PWM
	//1. Ustawienie okresu poprzez załadowanie rejestru PR2
	PR2 = 255;				//PR2 = 0xFF (okres = 0x4000*TOSC)
	//2. Ustawienie wypełnienia poprzez załadowanie CCPR1L:CCP1CON<5:4>
	CCPR1L = 0x80;			//CCPR1L:CCP1CON<5:4> = 0x200
	CCP1CONbits.CCP1X = 0;	//(wypełnienie = 0x2000*TOSC)
	CCP1CONbits.CCP1Y = 0;
	//3. Linia RC2/CCP1 wyjściowa
 	TRISCbits.TRISC2 = 0;	
	//4. Ustawienie preskalera TMR2 i włączenie modułu Timer2
	T2CONbits.T2CKPS1 = 1;	//Preskaler = 16
	T2CONbits.TMR2ON = 1;	//Włącz moduł Timer2
	//5. Włączenie modułu CCP1 w trybie PWM
  	CCP1CONbits.CCP1M3 = 1; //tryb PWM
	CCP1CONbits.CCP1M2 = 1;	//tryb PWM

	//konfiguracja linii przycisków
	TRISDbits.TRISD1 = 1;	//linia RD1 z przyciskiem S1 wyjściowa
	TRISDbits.TRISD2 = 1;	//linia RD2 z przyciskiem S2 wyjściowa	

	for(;;)						//pętla nieskończona
	{
		//sprawdź przycisk S1
		if(PORTDbits.RD1 == 0)
		{
			wypelnienie -= 100;	//zmniejsz wypełnienie
			if(wypelnienie < 0) wypelnienie = 0;
			//kopiuj wartość wypełnienia
			CCPR1L = (unsigned char)(wypelnienie>>2); 
			if(wypelnienie&0x02) CCP1CONbits.CCP1X = 1;
			else CCP1CONbits.CCP1X = 0;
			if(wypelnienie&0x01) CCP1CONbits.CCP1Y = 1;
			else CCP1CONbits.CCP1Y = 0;
			__delay_ms(150);		//czekaj do czasu ustabilizowania impulsu
		}
		//sprawdź przycisk S2
		if(PORTDbits.RD2 == 0)
		{
			wypelnienie += 100;	//zwiększ wypełnienie
			if(wypelnienie > 1023) wypelnienie = 1023;
			//kopiuj wartość wypełnienia
			CCPR1L = (unsigned char)(wypelnienie>>2);
			if(wypelnienie&0x02) CCP1CONbits.CCP1X = 1;
			else CCP1CONbits.CCP1X = 0;
			if(wypelnienie&0x01) CCP1CONbits.CCP1Y = 1;
			else CCP1CONbits.CCP1Y = 0;
			__delay_ms(150);		//czekaj do czasu ustabilizowania impulsu
		}
	}
}

