//**********************************************************************************************************************************
//Descrizione programma : genera su RA0 un onda quadra con periodo di 2 mS (f = 500 Hz)
//Descrizione del funzionamento : Per ottenere un onda quadra con periodo pari a 2 mS e' possibile
//utilizzare il TIMER1, precaricandolo con un valore opportuno e mandando in toggle lo stato di
//RA0 ogni volta che il TIMER1 si resetta.
//Il TIMER1 puo' essere resettato, tra le altre cose, anche da un evento speciale che avviene se
//si verifica un match fra i registri CCPR1H:CCPR1L di CCP1 e TMR1H:TMR1L di TMR1. In questo modo
//si verifica un reset di TMR1 e una richiesta di interrupt (CCP1IF a 1) a patto che tale interrupt 
//sia stato abilitato con il bit CCP1IE. 

//**********************************************************************************************************************************
//Dati di sistema
//Fclock         : 4 MHz
//Tclock         : 250 nS
//Tistruzione    : 1 uS

//INCLUDE files
#include <pic.h>

//*********************************************************************************************************************************
//Configurazione bit di programmazione
//Oscillatore : XT
//Watchdog : OFF
//Power Up Timer : ON
//Code Protect : ALL
//Brown Out Detect : ON
//Low Voltage Program : Disable
//Data EE Protect : OFF
//Flash Program Write : Disable
//Background Debug : Disable

//0b 0000 0101 0100 0001
__CONFIG(0x0D41);
//


//*********************************************************************************************************************************
//Prototipi
void SystemInit (void);
void CCP1Period (unsigned int);

//*********************************************************************************************************************************
//Simboli
#define Segnale RA0


//*********************************************************************************************************************************
//Tipo di segnale (analogico o digitale) sui PORTx
#define ADMode 0x06;   //tutto in digitale

//Configurazione modulo CCP1
#define CCP1CONInit 0b00001011  //compare mode, trigger special event

//Collegamenti a PORTA
//RA0 (OUT) --> LED0
//RA1 (OUT) --> NU
//RA2 (OUT) --> NU
//RA3 (OUT) --> NU
//RA4 (OUT) --> NU
//RA5 (OUT) --> NU
#define PortAInit 0x00;
#define TrisAInit 0x00;

//Colelgamenti a PORTB
//RB0 (OUT) --> NU
//RB1 (OUT) --> NU
//RB2 (OUT) --> NU
//RB3 (OUT) --> NU
//RB4 (OUT) --> NU
//RB5 (OUT) --> NU
//RB6 (OUT) --> NU
//RB7 (OUT) --> NU
#define PortBInit 0x00;
#define TrisBInit 0x00;

//Colelgamenti a PORTC
//RC0 (OUT) --> NU
//RC1 (OUT) --> NU
//RC2 (OUT) --> NU
//RC3 (OUT) --> NU
//RC4 (OUT) --> NU
//RC5 (OUT) --> NU
//RC6 (OUT) --> NU
//RC7 (OUT) --> NU
#define PortCInit 0x00;
#define TrisCInit 0x00;

//Colelgamenti a PORTD
//RD0 (OUT) --> NU
//RD1 (OUT) --> NU
//RD2 (OUT) --> NU
//RD3 (OUT) --> NU
//RD4 (OUT) --> NU
//RD5 (OUT) --> NU
//RD6 (OUT) --> NU
//RD7 (OUT) --> NU
#define PortDInit 0x00;
#define TrisDInit 0x00;

//Colelgamenti a PORTE
//RE0 (OUT) --> NU
//RE1 (OUT) --> NU
//RE2 (OUT) --> NU
#define PortEInit 0x00;
#define TrisEInit 0x00;


//*********************************************************************************************************************************
//Main
void main(void)
{
 SystemInit();
 CCP1Period(500);
 for (;;)
 {
 }
 
}


//*********************************************************************************************************************************
//Definizione funzioni

void SystemInit (void)
{
 //Tipi di segnali sui portx
 ADCON1 = ADMode;

 //Inizializzazione PORTx
 PORTA = PortAInit;
 PORTB = PortBInit;
 PORTC = PortCInit;
 PORTD = PortDInit;
 PORTE = PortEInit;


 //Direzione PORTx
 TRISA = TrisAInit;
 TRISB = TrisBInit;
 TRISC = TrisCInit;
 TRISD = TrisDInit;
 TRISE = TrisEInit;

 //Registro INTCON
 GIE    = 1;  //abilita globalmente gli interrupt
 PEIE   = 1;  //abilita l'interrupt per le periferiche
 CCP1IE = 1;  //abilita l'interrupt per il module CCP1

 //Registro OPTION
 T1CKPS1 = 0; //prescaler 1:1
 T1CKPS0 = 0; //    "      "
 T1OSCEN = 0; //oscillatore esterno disabilitato
 TMR1CS  = 0; //clock interno
 TMR1ON  = 1; //timer avviato

 //Registro CCP1CON
 CCP1CON = CCP1CONInit;  //CCP1 genera flag di interrupt (CCP1IF) e resetta TMR1 
}


//scrittura del periodo in CCP1
void CCP1Period (unsigned int Periodo)
{
 CCPR1H = Periodo >> 8;   //ms byte
 CCPR1L = Periodo;        //ls byte, Periodo entra negli 8 bit di CCPR1L e taglia gli 8 bit sopra
}

//routine di interrupt
void interrupt CCP1InterruptService (void)
{
 CCP1IF = 0;    //interrupt CCP1 riarmato
 Segnale = !Segnale; //toggle del segnale
 
}



