/* ************************************************************************
*             Exercice d'affichage multiplexé sur une matrice             *
*             de 8x8 LEDs.          PIC16F876A                            *
*             - Anodes communes sur le portB et Cathodes sur PortC        *
*                     FB Aka Hearty Mai 2010                              *
**************************************************************************/

//*****************
//Déclaration des variables
int scroll,n,i,rafraichir,vitesse,scroll1,tic,value,count;

// Tableau de caractères sur 8 bits installés en ROM
const unsigned short ASCII[] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code pour char
        0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00,  // Code pour char !
        0x00, 0x00, 0x06, 0x08, 0x00, 0x06, 0x08, 0x00,  // Code pour char "
        0x00, 0x24, 0x7E, 0x24, 0x24, 0x7E, 0x24, 0x00,  // Code pour char #
        0x00, 0x26, 0x49, 0x49, 0xFF, 0x49, 0x32, 0x00,  // Code pour char $
        0x00, 0x46, 0x26, 0x10, 0x08, 0x64, 0x62, 0x00,  // Code pour char %
        0x00, 0x70, 0x8E, 0x89, 0x99, 0x76, 0xC0, 0x00,  // Code pour char &
        0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code pour char '
        0x00, 0x7E, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code pour char (
        0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x7E, 0x00,  // Code pour char )
        0x00, 0x00, 0x0A, 0x04, 0x0A, 0x00, 0x00, 0x00,  // Code pour char *
        0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00,  // Code pour char +
        0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00,  // Code pour char ,
        0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00,  // Code pour char -
        0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00,  // Code pour char .
        0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,  // Code pour char /
        0x00, 0x7E, 0xC1, 0xB1, 0x8D, 0x83, 0x7E, 0x00,  // Code pour char 0
        0x00, 0x04, 0x02, 0x01, 0xFF, 0x00, 0x00, 0x00,  // Code pour char 1
        0x00, 0xE6, 0x91, 0x91, 0x89, 0x89, 0x86, 0x00,  // Code pour char 2
        0x00, 0x42, 0x81, 0x89, 0x89, 0x89, 0x76, 0x00,  // Code pour char 3
        0x00, 0x30, 0x28, 0x24, 0x22, 0xFF, 0x20, 0x00,  // Code pour char 4
        0x00, 0x4F, 0x89, 0x89, 0x89, 0x89, 0x71, 0x00,  // Code pour char 5
        0x00, 0x7E, 0x89, 0x89, 0x89, 0x89, 0x72, 0x00,  // Code pour char 6
        0x00, 0x01, 0x01, 0xF1, 0x09, 0x05, 0x03, 0x00,  // Code pour char 7
        0x00, 0x76, 0x89, 0x89, 0x89, 0x89, 0x76, 0x00,  // Code pour char 8
        0x00, 0x4E, 0x91, 0x91, 0x91, 0x91, 0x7E, 0x00,  // Code pour char 9
        0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00,  // Code pour char :
        0x00, 0x00, 0x80, 0x68, 0x00, 0x00, 0x00, 0x00,  // Code pour char ;
        0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00,  // Code pour char <
        0x00, 0x00, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00,  // Code pour char =
        0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 0x00,  // Code pour char >
        0x00, 0x06, 0x01, 0xB1, 0x09, 0x09, 0x06, 0x00,  // Code pour char ?
        0x00, 0x7E, 0x99, 0xA5, 0xA5, 0xB9, 0x5E, 0x00,  // Code pour char @
        0x00, 0xE0, 0x1C, 0x13, 0x13, 0x1C, 0xE0, 0x00,  // Code pour char A
        0x00, 0xFF, 0x89, 0x89, 0x89, 0x8E, 0x70, 0x00,  // Code pour char B
        0x00, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x42, 0x00,  // Code pour char C
        0x00, 0xFF, 0x81, 0x81, 0x81, 0x42, 0x3C, 0x00,  // Code pour char D
        0x00, 0xFF, 0x89, 0x89, 0x89, 0x81, 0x81, 0x00,  // Code pour char E
        0x00, 0xFF, 0x09, 0x09, 0x09, 0x01, 0x01, 0x00,  // Code pour char F
        0x00, 0x7E, 0x81, 0x91, 0x91, 0x51, 0xF2, 0x00,  // Code pour char G
        0x00, 0xFF, 0x08, 0x08, 0x08, 0x08, 0xFF, 0x00,  // Code pour char H
        0x00, 0x00, 0x81, 0xFF, 0x81, 0x00, 0x00, 0x00,  // Code pour char I
        0x00, 0x60, 0x80, 0x80, 0x80, 0x80, 0x7F, 0x00,  // Code pour char J
        0x00, 0xFF, 0x08, 0x18, 0x24, 0x42, 0x81, 0x00,  // Code pour char K
        0x00, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,  // Code pour char L
        0x00, 0xFF, 0x02, 0x0C, 0x0C, 0x02, 0xFF, 0x00,  // Code pour char M
        0x00, 0xFF, 0x03, 0x0C, 0x30, 0xC0, 0xFF, 0x00,  // Code pour char N
        0x00, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x00,  // Code pour char O
        0x00, 0xFF, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00,  // Code pour char P
        0x00, 0x7E, 0x81, 0x81, 0xA1, 0x41, 0xBE, 0x00,  // Code pour char Q
        0x00, 0xFF, 0x09, 0x09, 0x09, 0x39, 0xC6, 0x00,  // Code pour char R
        0x00, 0x46, 0x89, 0x89, 0x89, 0x89, 0x72, 0x00,  // Code pour char S
        0x00, 0x00, 0x01, 0x01, 0xFF, 0x01, 0x01, 0x00,  // Code pour char T
        0x00, 0x7F, 0x80, 0x80, 0x80, 0x80, 0x7F, 0x00,  // Code pour char U
        0x00, 0x0F, 0x30, 0xC0, 0xC0, 0x30, 0x0F, 0x00,  // Code pour char V
        0x00, 0x7F, 0x80, 0x70, 0x70, 0x80, 0x7F, 0x00,  // Code pour char W
        0x00, 0xC3, 0x24, 0x18, 0x18, 0x24, 0xC3, 0x00,  // Code pour char X
        0x00, 0x07, 0x08, 0xF0, 0xF0, 0x08, 0x07, 0x00,  // Code pour char Y
        0x00, 0xC1, 0xA1, 0x91, 0x89, 0x85, 0x83, 0x00,  // Code pour char Z
        0x00, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code pour char [
        0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00,  // Code pour char BackSlash
        0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xFF, 0x00,  // Code pour char ]
        0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x00, 0x00,  // Code pour char ^
        0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,  // Code pour char _
        0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,  // Code pour char `
        0x00, 0x00, 0x20, 0x54, 0x54, 0x78, 0x00, 0x00,  // Code pour char a
        0x00, 0x00, 0x7E, 0x48, 0x48, 0x30, 0x00, 0x00,  // Code pour char b
        0x00, 0x00, 0x38, 0x44, 0x44, 0x28, 0x00, 0x00,  // Code pour char c
        0x00, 0x00, 0x30, 0x48, 0x48, 0x7E, 0x00, 0x00,  // Code pour char d
        0x00, 0x00, 0x38, 0x54, 0x54, 0x58, 0x00, 0x00,  // Code pour char e
        0x00, 0x00, 0x7C, 0x0A, 0x0A, 0x02, 0x00, 0x00,  // Code pour char f
        0x00, 0x00, 0x18, 0xA4, 0xA8, 0x7C, 0x00, 0x00,  // Code pour char g
        0x00, 0x00, 0x7E, 0x08, 0x08, 0x70, 0x00, 0x00,  // Code pour char h
        0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x00,  // Code pour char i
        0x00, 0x00, 0x80, 0x80, 0x7A, 0x00, 0x00, 0x00,  // Code pour char j
        0x00, 0x00, 0x7E, 0x10, 0x28, 0x40, 0x00, 0x00,  // Code pour char k
        0x00, 0x00, 0x00, 0x7E, 0x40, 0x00, 0x00, 0x00,  // Code pour char l
        0x00, 0x7C, 0x08, 0x04, 0x78, 0x04, 0x78, 0x00,  // Code pour char m
        0x00, 0x00, 0x7C, 0x08, 0x04, 0x78, 0x00, 0x00,  // Code pour char n
        0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00,  // Code pour char o
        0x00, 0x00, 0xFC, 0x28, 0x24, 0x18, 0x00, 0x00,  // Code pour char p
        0x00, 0x00, 0x18, 0x24, 0x28, 0xFC, 0x00, 0x00,  // Code pour char q
        0x00, 0x00, 0x7C, 0x08, 0x04, 0x08, 0x00, 0x00,  // Code pour char r
        0x00, 0x00, 0x08, 0x54, 0x54, 0x20, 0x00, 0x00,  // Code pour char s
        0x00, 0x00, 0x3E, 0x48, 0x40, 0x00, 0x00, 0x00,  // Code pour char t
        0x00, 0x00, 0x3C, 0x40, 0x40, 0x3C, 0x00, 0x00,  // Code pour char u
        0x00, 0x00, 0x1C, 0x60, 0x60, 0x1C, 0x00, 0x00,  // Code pour char v
        0x00, 0x3C, 0x40, 0x70, 0x70, 0x40, 0x3C, 0x00,  // Code pour char w
        0x00, 0x00, 0x6C, 0x10, 0x10, 0x6C, 0x00, 0x00,  // Code pour char x
        0x00, 0x00, 0x0C, 0x90, 0x90, 0x7C, 0x00, 0x00,  // Code pour char y
        0x00, 0x00, 0x64, 0x54, 0x54, 0x4C, 0x00, 0x00,  // Code pour char z
        0x00, 0x00, 0x08, 0x76, 0x81, 0x00, 0x00, 0x00,  // Code pour char {
        0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,  // Code pour char |
        0x00, 0x00, 0x00, 0x81, 0x76, 0x08, 0x00, 0x00,  // Code pour char }
        0x00, 0x00, 0x10, 0x08, 0x10, 0x08, 0x00, 0x00   // Code pour char ~
        };
//******************
//Interruption
void interrupt() {
  rafraichir++;
  vitesse++;
  tic++;
  
  TMR0   = 0;                 // Valeur décimale préchargée à soustraire à 256
//******************
//Désactive l'interruption TMR0   (0xA0 = active)
  INTCON = 0x20;              // Set T0IE, clear T0IF (Met à 1 le bit TMROIE , Efface(0) le Flag TMROIF de débordement d'interruption)
                 }

//******************
// Fonction Scrolling avant
//Le tableau comporte 760 octets, dont 8 sont affichés par la variable i
// il reste donc 752 octets a extraire au fur et à mesure
// on a donc pour afficher un caractère PORTB= ASCII[8+752] au debut.
// on part donc de la fin du tableau et le chiffre 752 est décrémenté
// à chaque itération par la variable scroll--
void avant(){
     if(rafraichir==40)                        // 50  ou 40  ou 300
                   {
                    if(vitesse==600)           //450 ou 600
                      {
                      vitesse=0;
                      scroll--;
                      }
                   if(i>=8){
                      i=0;
                        }
                        //PORTB = 0;
                        PORTB =~ASCII[i+scroll];
                        PORTC=1<<i;
                        n=~n;
                        PORTA.F5=1<<i;
                        //delay_ms(1);
                        i++;
                        rafraichir=0;
                  if(scroll<=0)
                    {
                        scroll=753;
                    }

                }

}
//****************
// Fonction scrolling arrière
// voir fonction avant mais en inverse,
//on commence par le début donc 8 (extrait par i du tableau)
// puis on incrémente scroll++ en partant de 0
//( ou plutot i+0 puis i+1 etc.. sachant que i max est 8)
void arriere(){
                  if(rafraichir==40)
                   {
                      if(vitesse==600)
                        {
                        vitesse=0;
                        scroll1++;
                        }
                      if(i>=8)
                        {
                        i=0;
                        }
                        //PORTB = 0;
                      PORTB =~ASCII[i+scroll1];// inverser la sortie pour la simulation
                      PORTC=1<<i;
                      PORTA.F5=1<<i;
                      //delay_ms(5);
                      i++;
                      rafraichir=0;
                      if(scroll1>=753)
                        {
                        scroll1=0;
                        }
                    }
              }

//*****************
// Programme principal
void main(){
//PORTA.F4=0;
INTCON=0xA0;                      // Activer l'interruption TMR0
OPTION_REG = 0x00;                // Assigner prescaler sur TMR0  valeur 2   = 000
rafraichir=0;                     // Variable de vitesse de rafraichissement d'un caractère ( vitesse d'affichage des 8 octets d'un caractère du tableau)
vitesse=0;                        // vitesse de défilement des caractères
scroll=752;                       // compteur de caractères pour le scrolling avant
scroll1=0;                        // idem pour l'arrière
TMR0=0;
i=0;                              // compteur de 0 à7 pour extraire 8 octets d'un caractère du tableau
n=0;                              // incrémentation du scroll (extrait un octet +1 à chaque itération)
ADCON0=0;                         // ADC désactivé
TRISA=1;                          // PORTA configuré en Entrée
TRISB=0;                          // PORTB configuré en sortie
TRISC=0;                          // PORTC configuré en sortie
PORTA=0;                          // mise à zéro des ports A
PORTB=0;                          // mise à zéro des ports B
PORTC=0;                          // mise à zéro des ports C
//*****************
//boucle infinie
      while(1)
          {

              arriere();        // Appel de la fonction Arrière




         // avant();             // Appel de la fonction Avant
           }

}


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