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

                      +----v----+
                MCLR [| 1     40|] 
                     [| 2     39|] 
                     [| 3     38|] RB5 -> DB4_LCD
                     [| 4     37|] RB4 -> DB5_LCD
                     [| 5     36|] RB3 -> DB6_LCD
                     [| 6     35|] RB2 -> DB7_LCD
                     [| 7     34|] RB1 -> RS_LCD
                     [| 8     33|] RB0 -> EN_LCD
                     [| 9     32|] VDD
                     [|10     31|] VSS
                 VDD [|11     30|] 
                 VSS [|12     29|] 
     (20 MHz) / OSC1 [|13     28|]
              \ OSC2 [|14     27|]
(32,768 kHz) / T1OSO [|15     26|] 
             \ T1OSI [|16     25|] 
      S1 -> RC2/CCP1 [|17     24|] 
                     [|18     23|] 
                     [|19     22|] 
                     [|20     21|] 
                      +---------+
                      PIC16F877A

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

//definiujemy szybkość oscylatora dla funkcji __delay_
#define _XTAL_FREQ 20000000
#include <htc.h>
#include <stdlib.h>
#include <string.h>
//////////////////////////////////////
#define TRIS_RS_LCD   TRISBbits.TRISB1
#define TRIS_EN_LCD   TRISBbits.TRISB0
#define TRIS_DB4_LCD  TRISBbits.TRISB5
#define TRIS_DB5_LCD  TRISBbits.TRISB4
#define TRIS_DB6_LCD  TRISBbits.TRISB3
#define TRIS_DB7_LCD  TRISBbits.TRISB2

#define RS_LCD   PORTBbits.RB1
#define EN_LCD   PORTBbits.RB0
#define DB4_LCD  PORTBbits.RB5
#define DB5_LCD  PORTBbits.RB4
#define DB6_LCD  PORTBbits.RB3
#define DB7_LCD  PORTBbits.RB2

#include "lcd.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);

char napis0[] = "Wcisnij przycisk";	//16 znaków
char napis1[] = "Wynik:";			//6 znaków
char napis2[6] = {32,32,32,32,32};	//5 znaków (bufor czyszczący)
char napisw[6];						//bufor wyniku
unsigned int wynik = 0;				//zmienna przechowująca wynik
unsigned char przel;				//flaga pomiaru
//ś
const char nowy_znak[8] = {0b00000, 0b00100, 0b01110, 0b10000,
                           0b01110, 0b00001, 0b11110, 0b00000};


void main()
{
	ADCON1 = 0x06;						//wyłączenie linii analogowych 
                    					//(wszystkie linie cyfrowe)
	WlaczLCD();							//inicjalizacja wyświetlacza LCD
	Zapisz_nowy_znakLCD(nowy_znak, 0);	//koduj nowy znak (ś)
	napis0[3] = 0;						//przypisanie kodu nowego znaku
	CzyscLCD();							//reset wyświetlacza
	WyswietlLCD(napis0, 16);			//wyświetl napis "Wciśnij przycisk"
	UstawKursorLCD(2, 1);				//wiersz 2 kolumna 1
	WyswietlLCD(napis1, 6);				//wyświetl napis "Wynik"

 	TRISCbits.TRISC2 = 1;				//linia RC2/CCP1 wejściowa
	//konfiguracja modułu Timer1
	PIE1bits.TMR1IE = 0;		//wyłącz przerwanie Timer1
	T1CONbits.T1OSCEN = 1;		//włącz oscylator dla Timer1
	T1CONbits.T1SYNC = 1;		//wyłącz synchronizację zewn. oscylatora
	T1CONbits.TMR1CS = 1;		//zewnętrzne źródło taktujące
	T1CONbits.TMR1ON = 1;		//włącz moduł Timer1

	for(;;)									//pętla nieskończona
	{	
		utoa(napisw, wynik, 10);			//konwersja wyniku w napis
		CzyscLCD();							//reset wyświetlacza
		UstawKursorLCD(2, 1);				//wiersz 2 kolumna 1
		WyswietlLCD(napis1, 6);				//wyświetl napis "Wynik"
		UstawKursorLCD(2, 8);				//wiersz 2 kolumna 8
		WyswietlLCD(napisw, strlen(napisw));//wyświetl wynik
		__delay_ms(500);					//zaczekaj na ustabilizowanie przycisku
		UstawKursorLCD(1, 1);				//wiersz 1 kolumna 1
		WyswietlLCD(napis0, 16);			//wyświetl napis "Wciśnij przycisk"
		przel = 0;							//wyzeruj flagę pomiaru 
											//(inkrementowana w funkcji obsługi przerwania)
  		CCP1CON = 0x04; 					//konfiguracja modułu CCP
                  							//(tryb Capture, zbocze opadające)
  		PIE1bits.CCP1IE = 1;				//włącz przerwanie modułu CCP1
  		PIR1bits.CCP1IF = 0;				//wyzeruj flagę przerwania
  		INTCON = 0xC0;  					//włącz obsługę przerwań

		while(przel<2);						//zaczekaj na wykonanie pomiaru
		INTCON = 0x00;  					//wyłącz obsługę przerwań
	}
}

static void interrupt
knowania_przerwania(void)
{
	//wyzerowanie rejestru TMR1
  	TMR1H = 0x00;
  	TMR1L = 0x00;

	if (PIR1bits.CCP1IF)		//przerwanie CCP
  	{
   		if(przel == 0)
   		{
    		CCP1CON = 0x05;		//konfiguracja modułu CCP (tryb Capture, zbocze narastające)
    		przel++;			//inkrementacja przełącznika
    		PIR1bits.CCP1IF = 0;//wyzeruj flagę przerwania (zezwól na nowe przerwanie)
    	}
    	else if(przel == 1)
    	{
     		wynik = CCPR1;		//kopiuj wynik
     		przel++;			//inkrementacja przełącznika
			PIE1bits.CCP1IE = 0;//wyłącz przerwanie modułu CCP1
     		PIR1bits.CCP1IF = 0;//wyzeruj flagę przerwania (zezwól na nowe przerwanie)
    	}
	}
}
