//*****************************************************************************
//Descrizione programma : multivibratore monostabile
//Scritto da : Andrea Cipriani
//Versione : 1.0
//Descrizione del funzionamento : Su RA0 viene generato un impulso monostabile della durata di 2 secondi
//a ogni volta che viene premuto il pulsante Start presente su RB0. Se viene premuto start si genera un
//interrupt request con il bit INTF a 1. In questo caso si pone  RA0=1 (avvia il monostabile), 
//INTF=0 (riarma il flag dell'interrupt su RB0), TMR0=0 (azzera il timer), T0IE = 1;(abilita l'interrput su 
//Timer0), T0IF = 0; (riarma il flag dell'interrupt sul Timer0). Il TIMER0 viene utilizzato con prescaler 
//impostato a 1:2. Dopo 102.4 uS il TIMER0 andra' in overflow e si generera' un rischista di interrupt su
//T0IF. Siccome devono passare 2 secondi occorrera' fare andare il TIMER0 in overflow per 3906 volte in
//quanto 2S / 102.4 uS = 19531.25 Per fare cio' si incrementa una variabile Count fino a 19531

//*****************************************************************************
//Dati di sistema
//Fclock : 20 Mhz
//Tclock : 50 nS
//Tistruzione : 200 nS


//INCLUDE files
#include <pic.h>

//*****************************************************************************
//Configurazione bit di programmazione
//Oscillatore : XT
//Watchdog : OFF
//Power Up Timer : ON
//Code Protect : ALL      //con icprog si ferma durante la verifica quindi metterlo off
//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);

//*****************************************************************************
//Simboli
#define Monostabile RA0
#define Start RB0


//*****************************************************************************
//Tipo di segnale (analogico o digitale) sui portx
#define ADMode 0x06;   //tutto in digitale

//Valore portx allo startup
#define PortValue 0

//Collegamenti a PORTA
//RA0 (OUT) --> Monostabile
//RA1 (OUT) --> NU
//RA2 (OUT) --> NU
//RA3 (OUT) --> NU
//RA4 (OUT) --> NU
//RA5 (OUT) --> NU
#define TrisaInit 0x00;

//Colelgamenti a PORTB
//RB0 (INP) <-- START
//RB1 (OUT) --> NU
//RB2 (OUT) --> NU
//RB3 (OUT) --> NU
//RB4 (OUT) --> NU
//RB5 (OUT) --> NU
//RB6 (OUT) --> NU
//RB7 (OUT) --> NU
#define TrisbInit 0x01;

//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;

unsigned int Count;


//*****************************************************************************
//Main
void main(void)
{
 SystemInit();
 for (;;)
 {
 }
 
}


//*****************************************************************************
//Definizione funzioni

void SystemInit (void)
{
 //Tipi di segnali sui portx
 ADCON1 = ADMode;

 //Direzione e valori iniziali dei portx
 
 PORTA=PortValue;
 PORTB=PortValue;
 PORTC=PortValue;
 PORTD=PortValue;
 PORTE=PortValue;

 TRISA = TrisaInit;
 TRISB = TrisbInit;
 TRISC = TriscInit;
 TRISD = TrisdInit;
 TRISE = TriseInit;

 RBPU=0;    //pull up su PORTB
 
 //Registro INTCON
 GIE = 1;      //abilita globalmente gli interrupt
 INTE = 1;    //abilita interrupt su RB0
 T0IE = 0;    //disabilita l'interrupt per il Timer0

 //Registro OPTION
 INTEDG = 0;   //interrupt su fronte di discesa
 T0CS = 0;     //clock interno 
 PSA = 0;      //prescaler al timer0
 PS2 = 0;      //divide per  2
 PS1 = 0;      //   "      "    "
 PS0 = 0;      //   "      "    "
}


//routine di interrupt
void interrupt MonostabileISR (void)
{
 //chi ha generato l'interrupt ?
 if (INTF)  //RB0
 {
  RA0=1;    //avvia il monostabile
  INTF=0;   //riarma il flag dell'interrupt su RB0
  TMR0=0;   //azzera il timer
  Count=0;  //azzera count
  T0IE = 1; //abilita l'interrput su Timer0
  T0IF = 0; //riarma il flag dell'interrupt sul Timer0
 }

 if (T0IF)  //timer0
 {
   if (Count==19531)   //se e' passato 1 secondo
   {
    RA0 = 0;   //blocca il monostabile
    T0IF = 0;  //riarma il flag dell'interrupt sul Timer0
    T0IE = 1;  //disabilita l'interrupt sul Timer0
   }
   else    //se non e' passato 1 secondo
   {
    Count++;  //incrementa conteggio degli interrupt
    TMR0=0;  //azzera TMR0
    T0IF=0;
   }

   
 }
}



