//**********************************************************************************************************************************
//Descrizione programma : modulatore pwm
//Scritto da : Andrea Cipriani
//Versione : 1.0
//Generatore di dente di sega su RC2 sfruttando il modulatore pwm. Occorre dimensionare un apposito filtro passa basso da
//connettere a RC2.

//**********************************************************************************************************************************
//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);
//


//Tipo di segnale (analogico o digitale) sui portx
#define ADMode 0b00000110;   //tutto in digitale

//Valore portx allo startup
#define ProgA 0b00000000
#define ProgB 0b00000011
#define ProgC 0b00000000
#define ProgD 0b00000000
#define ProgE 0b00000000

//Collegamenti a PORTA
//RA0 (OUT) --> NU
//RA1 (OUT) --> NU
//RA2 (OUT) --> NU
//RA3 (OUT) --> NU
//RA4 (OUT) --> NU
//RA5 (OUT) --> NU
#define TrisaInit 0x00;

//Colelgamenti a PORTB
//RB0 (INP) <-- UP
//RB1 (OUT) <-- DOWN
//RB2 (OUT) --> NU
//RB3 (OUT) --> NU
//RB4 (OUT) --> NU
//RB5 (OUT) --> NU
//RB6 (OUT) --> NU
//RB7 (OUT) --> NU
#define TrisbInit 0x03;

//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 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 TrisdInit 0x00;

//Colelgamenti a PORTE
//RE0 (OUT) --> NU
//RE1 (OUT) --> NU
//RE2 (OUT) --> NU
#define TriseInit 0x00;

//*********************************************************************************************************************************
//Simboli
#define UP RB0
#define DOWN RB1
//*********************************************************************************************************************************



//Variabili
unsigned int cnt;   

//*********************************************************************************************************************************
//Prototipi
void SystemInit    (void);
void Delay         (unsigned int Ritardo);
void PWM_Write     (unsigned int PWM);   //converte la variabile PWM nei registri CCP!CPN e CCPR1L






//*********************************************************************************************************************************
//Main
void main(void)
{
 SystemInit();
 
 for (;;)
 {
  for (cnt=0; cnt<1024; cnt++)
  {
   PWM_Write(cnt);
  }
  
 PWM_Write(0);

 } 

}


//*********************************************************************************************************************************
//Definizione funzioni

void SystemInit (void)
{
 //Tipi di segnali sui portx
 ADCON1 = ADMode;

 PORTA=ProgA;
 PORTB=ProgB;
 PORTC=ProgC;
 PORTD=ProgD;
 PORTE=ProgE;


 TRISA = TrisaInit;
 TRISB = TrisbInit;
 TRISC = TriscInit;
 TRISD = TrisdInit;
 TRISE = TriseInit;

 
 //Registro OPTION
 RBPU = 0;    //pull up su PORTB
 
 
 //Setaggio modulo PWM
 PR2 = 62;    //tPWM = (PR2 + 1)*4 * (Tclock * Prescaler)  fPWM = 1 Khz  
 T2CKPS1 = 1;   //prescaler 16
 T2CKPS0 = 1;   //prescaler 16
 CCPR1L = 0;    //valore iniziale PWM
 TMR2ON = 1;    //timer2 abilitato
 CCP1CON = 0b00001100;  //modo PWM
}

//routine di ritardo
void Delay (unsigned int Ritardo)
{
 unsigned int TimeDelay;
 for (TimeDelay=0; TimeDelay<Ritardo; TimeDelay++);
}

void PWM_Write (unsigned int PWM)
{
 CCP1CON = CCP1CON & 0b11001111; //pulisce CCP1x e CCP1y
 CCP1CON = CCP1CON | ((PWM*16) & 0b00110000);  //in CCP1CON i 2 bit meno significativi di PWM
 CCPR1L = PWM / 4; //il bit piu significativo di PWM in CCPR1L
}

