/**************************************************************
        Schemat podłączeń programowanego układu
                       +----v----+
                 MCLR [| 1     28|] AVDD
                      [| 2     27|] AVSS
                      [| 3     26|] RB15 -> DB4        
                      [| 4     25|] RB14 -> DB5
                      [| 5     24|] RB13 -> DB6
        2D120X -> AN4 [| 6     23|] RB12 -> DB7
                      [| 7     22|] RB11 -> RS
                  VSS [| 8     21|] RB10 -> EN
       (8 MHz) / OSC1 [| 9     20|] VCAP/VDDCORE
               \ OSC2 [|10     19|] VSS
                      [|11     18|] 
                      [|12     17|] 
                  VDD [|13     16|] 
                      [|14     15|] 
                       +---------+
                    dsPIC33FJ128GP802
***************************************************************/
#include "p33fxxxx.h"
//definiujemy szybkość oscylatora dla funkcji __delay_
#define FCY 40000000UL 
//biblioteka z funkcjami __delay_us i __delay_ms
#include <libpic30.h>
#include <stdlib.h>
#include <string.h>

//////////////////////////////////////
#define TRIS_RS_LCD   TRISBbits.TRISB11
#define TRIS_EN_LCD   TRISBbits.TRISB10
#define TRIS_DB4_LCD  TRISBbits.TRISB15
#define TRIS_DB5_LCD  TRISBbits.TRISB14
#define TRIS_DB6_LCD  TRISBbits.TRISB13
#define TRIS_DB7_LCD  TRISBbits.TRISB12

#define RS_LCD   LATBbits.LATB11
#define EN_LCD   LATBbits.LATB10
#define DB4_LCD  LATBbits.LATB15
#define DB5_LCD  LATBbits.LATB14
#define DB6_LCD  LATBbits.LATB13
#define DB7_LCD  LATBbits.LATB12

#include "lcd.h"
//////////////////////////////////////

/**************************************************************/
//Ustawienie bitów konfiguracyjnych
//FNOSC_PRIPLL	- zewnętrzny oscylator z PLL
_FOSCSEL(FNOSC_PRIPLL);

//FCKSM_CSDCMD	- wyłączona możliwość przełączania źródeł zegara
//OSCIOFNC_OFF	- OSC2 jest wyjściem zegarowym
//POSCMD_XT	- oscylator XT
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);

//FWDTEN_OFF	- watchdog może być wyłączony przez użytkownika w programie		
_FWDT(FWDTEN_OFF);
/**************************************************************/

//tablice znakowe dla funkcji LCD
char napis1[] = "Dane z czujnika:";	//16 znaków
char napis2[] = "                ";	//16 znaków
char tablica[16];

int main()
{
	int wynikADC;
////////////////////////////////////////////////////////////////////////////////
	//Ustawienia PLL: Fosc = (((Fin/PLLPRE)*PLLDIV)/PLLPOST)
	//przy spełnionych warunkach:
	//1.  0,8 MHz >= (Fin/PLLPRE)                    <= 8,0 MHz
	//2.  100 MHz >= ((Fin/PLLPRE)*PLLDIV)           <= 200 MHz
	//3. 12,5 MHz >= (((Fin/PLLPRE)*PLLDIV)/PLLPOST) <= 80,0 MHz
  
	//nasza konfiguracja
	//1. 8,00 MHz/2 = 4,00 MHz		(N1 = 2)
	//2. 4,00 MHz*40 = 160,00 MHz	(M = 40)
	//3. 160,00 MHz/2 = 80,00 MHz	(N2 = 2)
////////////////////////////////////////////////////////////////////////////////
	//1. CLKDIVbits.PLLPRE = N1 - 2
	CLKDIVbits.PLLPRE = 0;
	//2. PLLFBDbits.PLLDIV = M - 2
	PLLFBDbits.PLLDIV = 38;
	//3. CLKDIVbits.PLLPOST - (00 = 2)(01 = 4)(10 = zarezerwowane)(11 = 8)
	CLKDIVbits.PLLPOST = 0;
////////////////////////////////////////////////////////////////////////////////
	RCONbits.SWDTEN = 0;		//wyłączenie timera Watchdog
	while(OSCCONbits.COSC != 0x03);//zaczekaj na ustawienie bitów COSC
	while(OSCCONbits.LOCK != 1);	//zaczekaj na ustabilizowanie PLL
////////////////////////////////////////////////////////////////////////////////
// konfiguracja I/O
	AD1PCFGL = 0xFFFF;		//wszystkie linie cyfrowe 
	AD1PCFGLbits.PCFG4 = 0;	//prócz analogowego AN4              

/////////////////////////////////////////////////////
// uruchomienie wyświetlacza LCD//////////////////////
	WlaczLCD();			//inicjalizacja wyświetlacza LCD
	WyswietlLCD(napis1, 16);	//wyświetl napis "Dane z czujnika:"

/////////////////////////////////////////////////////
//konfiguracja modułu ADC
	AD1CON1bits.SSRC = 7;		//czas próbkowania sterowany modułem, 
					//konwersja uruchamiana automatycznie
	AD1CON1bits.AD12B = 1;		//dane 12-bitowe
	AD1CHS0bits.CH0SA = 4;		//wejście analogowe AN4
	AD1CON3bits.SAMC = 0x1F;	//czas próbkowania = 31 TAD
	AD1CON3bits.ADCS = 2;		//czas TAD = 3 TCY
	AD1CON2bits.VCFG = 0;		//napięcie odniesienia AVDD, AVSS
	AD1CON1bits.ADON = 1;		//włącz przetwornik

////////////////////////////////////////////////////////////////////////////////
// nieskończona pętla
	for(;;)                            
	{
		AD1CON1bits.SAMP = 1;	//włącz próbkowanie
		//czekaj na koniec konwersji 
		//(uruchomiona automatycznie po skończeniu próbkowania)
		while (!AD1CON1bits.DONE);
		wynikADC = ADC1BUF0;	//odczytaj wynik

		utoa(tablica, wynikADC, 10);
		UstawKursorLCD(2, 1);	//wiersz 2 kolumna 1
		WyswietlLCD(napis2, 4);
		UstawKursorLCD(2, 1);	//wiersz 2 kolumna 1
		WyswietlLCD(tablica, strlen(tablica));	
		__delay_ms(500);
	}
}
