/*********************************************************************************************************
*     Tachymètre (compte-tour) numérique à base de capteur à effet Hall                                  *
*     Quartz 20Mhz         PIC 16F876A                                                                   *
*     fusibles par defaut -                                                                              *
*     MikroC Pro 3.8                                                                                     *
*                                                                                                        *
*     Formule de calcul du timer0 :                                                                      *
*     Temps=(256-valeur Décimale chargée TMR0) * 4 * (prescaler OPTION_REG) * 1/Oscillateur en Hz        *
*     Ce qui donne:                                                                                      *
*     T=(256-0)*4*64*(1/20000000)= 0,0032768  >> pour avoir 0,999424 seconde  à multiplier par cnt=305   *
*     0,999424 étant pour ce quartz  la valeur la plus proche de 1 seconde avec le timer0                *
*                                                                                                        *
*     Le capteur Hall connecté sur RB0 déclenche une interruption à chaque passage de l'aimant           *
*                                                                                                        *
*     FB Aka Hearty Octobre 2011    ->> HeartyGFX.blogspot.com <<-                                       *
*********************************************************************************************************/



// Configuration des ports sur le LCD
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D4 at RB4_bit;
// Orientation des ports
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB4_bit;


//Déclaration des variables
unsigned int temp,Compteur,cnt,tour ;
unsigned char rotation_brute;
unsigned short int seconde,sequence;
void Affiche_Compteur (void);

//******************************************************************************
//Interruption
void interrupt() {
                 cnt++;
                  TMR0   = 0;                          // Valeur décimale préchargée à soustraire à 256



                 if(INTCON.INTF==1){                   // Si une interruption du port B0 est détectée
                                    tour++;            // incrémenter la variable de tour
                                    }                  // fin if
                 INTCON = 0x20;                        // Initialisation du registre timer et interruption
                 if(cnt==305){                         // lorsque l'on compte 1 seconde (voir commentaire entête)
                            compteur= tour*60;         // Multiplier le nombre de tour/seconde par 60 (pour tour/min)
                            cnt=0;                     // RAZ variable cnt
                            tour=0;
                            INTCON.INTE = 1;           // Activer RB0/INT interruption
                            seconde++;
                  }                                    // Fin if

   }       //fin interruption

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


void Affiche_Compteur (void){           // fonction d'affichage de nombre sur plusieurs digits

unsigned int temp;
unsigned char rotation_brute;

rotation_brute = (compteur/1000)+48;
temp = compteur % 1000;
Lcd_Chr(2, 4, rotation_brute);           // Afficher les milliers en ligne 2, 4-ieme colonne
rotation_brute = (temp/100)+48;
temp = temp % 100;
Lcd_Chr_Cp(rotation_brute);             // Afficher les centaines
rotation_brute = (temp/10)+48;
Lcd_Chr_Cp(rotation_brute);             // Afficher les dizaines
rotation_brute = (temp % 10)+48;
Lcd_Chr_Cp(rotation_brute);             // Afficher les unités

}



 //*****************************************************************************
 void main(){                       // Début du programme principal

  INTCON=0b10010000;                // activer detection interruption front montant RB0 avec INTE et GIE
  OPTION_REG = 0b11000101;          // Assigner prescaler sur TMR0  valeur 2   = 000
  TMR0=0;
  CMCON  |= 7;                      // Comparateur desactivé
  ADCON0=0;                         // ADC désactivé
  TRISA=1;                          // PORTA configuré en entrée
  TRISB=0b00000001;                 // PORTB configuré en sortie sauf port0
  TRISC=0;                          // PORTC configuré en sortie
  PORTA=0;
  PORTB=0;
  PORTC=0;
  compteur=0;
  temp=0;
  seconde=0;
  tour=0;

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

  Lcd_Init();                       //Initialiser le LCD
  Lcd_Cmd(_LCD_CLEAR);              // Effacer l'écran
  Lcd_Cmd(_LCD_CURSOR_OFF);         // Cacher le curseur
  Lcd_Out(1,4, "Tachymetre");       // Afficher le message
  Lcd_Out(2,9, "tr/mn ");           // Afficher le message

//boucle infinie
         while(1)

                 {

                  Affiche_Compteur();               // Fonction d'affichage sur LCD

                  }  //fin de while

  }  // fin de main