Bico64/Exemples de programmes

Début de la boite de navigation du chapitre

Ci-dessous, quelques exemples de programmes qui vont en se complexifiant. Pour faciliter, vous pouvez copier le programme et le coller dans ConTEXT.

Exemples de programmes
Icône de la faculté
Chapitre no 4
Leçon : Bico64
Chap. préc. :Installer l'environnement de développement
Chap. suiv. :Liens utiles
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Bico64 : Exemples de programmes
Bico64/Exemples de programmes
 », n'a pu être restituée correctement ci-dessus.

Bien que les programmes soient de plus en plus compliqués, pour un débutant débutant, il est peut être plus simple de copier le 2e programme et de ne modifier que la procédure loop()

Affichage d'une image fixe (AfficheImageFixe.c)

modifier

Comme premier petit programme voici de quoi afficher une image fixe.

 

À ce stade, vous aurez forcément plein de questions sur la syntaxe du C. Le mieux est de se référer à un des nombreux cours se trouvant sur le net

  //------------------------------------------------------------------------------------------
  // Programme de démonstration qui affiche une image sur le Bico64
  //------------------------------------------------------------------------------------------
  #define __16F887
  #include <pic16f887.h>
  //------------------------------------------------------------------------------------------
  // Configuration du PIC 16F884 selon Bico64
  //------------------------------------------------------------------------------------------
  __code __at _CONFIG1 unsigned int Config1 =
     _INTOSCIO  // I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
   & _WDT_OFF   // pas de Watch Dog
   & _PWRTE_ON  // on attend un peu au démarrage
   & _MCLRE_ON  // RE3/MCLR pin function is MCLR
   & _CP_OFF    // Program memory code protection is disabled
   & _CPD_OFF   // Data memory code protection is disabled
   & _BOR_OFF   // BOR Disabled
   & _IESO_OFF  // Internal/External Switchover mode is disabled
   & _FCMEN_OFF // Fail-Safe Clock Monitor is disabled
   & _LVP_OFF   // RB3 pin is digital I/O, HV on MCLR must be used for programming
   & _DEBUG_OFF;// In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins
  __code __at _CONFIG2 unsigned int Config2 =
     _WRT_OFF // No prog memmory write protection
   & _BOR21V;  // Brown-Out Reset at 2.1V

  typedef unsigned char byte;
 
  // on donne des noms significatifs aux PORTs utilisés
  #define PLIGNE PORTB
  #define PVERT  PORTC
  #define PROUGE PORTD
 
  //----------------------------------------------------------------------------------------
  void Setup(void) {
    // Initialisation
    TRISB = 0x00;       // PortB est en sortie
    TRISC = 0x00;       // PortC est en sortie
    TRISD = 0x00;       // PortD est en sortie
    TRISA = 0xFF;       // PortA est en entrée
  }

  byte image[16] = {
    //  Vert      Rouge          PLIGNE
    0b11111111,0b00000000,      // D0
    0b11111110,0b00000000,      // D1
    0b11111100,0b00000000,      // D2
    0b11111000,0b00000000,      // D3
    0b11110000,0b00000001,      // D4
    0b11100000,0b00000011,      // D5
    0b11000000,0b00000111,      // D6
    0b10000000,0b00001111,      // D7
  };

  void EffacerImage(void) {
    // efface l’ensemble de l'image
    short i;
    for (i=0;i<16;i++){
      image[i] = 0;
    }
  }

  //----------------------------------------------------------------------------------------
  void AfficherImage(byte temps) {
    // affiche l'image
    // le paramètre temps permet de régler le temps que va prendre cette procedure
    // en répétant n fois l'affichage. C'est un moyen primaire de faire aller
    // plus ou moins vite l’affichage dans les procédure qui appelle AfficherImage.
    // temps =1 ==> env 5ms pour afficher
    // L'image affichée se trouve dans le tableau mémoire "image"
     int i,n;
     byte ligne;
     byte *p;                       //p pointe sur le premier byte du tableau image
 
     for (n=0;n<temps;n++){
       p = &image[0];
       ligne = 0b11111110;          // dans Ligne, on aura la ligne active à 0; on décalera le 0 pour chaque ligne
       while (ligne != 0b11111111){ // tant qu’il reste un 0, on n'a pas terminé de balayer l'image
         PLIGNE = 0b11111111;       // pour éviter de voir des petits "phantomes" de la ligne précédente
                                    // on ne sélectionne aucune ligne
         PVERT  = *p++;             // on met les bits pour la couleur Rouge
         PROUGE = *p++;             // on met les bits pour la couleur Verte
         PLIGNE = ligne;            // on met la ligne (le bon bit à 0)
         ligne = (ligne << 1) +1 ;  // on décale le bit à 0 de un bit, comme cela met D0 à 0, on
                                    // force D0 à 1 pour n'avoir qu'un bit à 0 (ligne active)
         for (i=0;i<50;i++) {};     // on attend un peu pour avoir le temps de voir cette ligne
       }
     }
  }

  //-------------------------------------------------------------
  // La boucle: on ne fait qu'afficher l'image
  //-------------------------------------------------------------
  void Loop(void) {
    AfficherImage(1);
    image[0]++;      // on modifie l'image pour voir à quelle vitesse va l'affichage
  }

  //-------------------------------------------------------------
  // Programme principal (là où le PIC va démarrer)
  //-------------------------------------------------------------
  void main(void) {
    Setup();
    while(1) {
      Loop();
    }
  }

Quelques explications:

  • la configuration du PIC: dans un premier temps inutile de comprendre: c’est comme cela qu’il faut le configurer pour le Bico64. Par contre pour les curieux (ou ceux qui veulent faire autre chose que le Bico64, on trouve les registres de config au § 14.1 et 14.2 du databook[1]. Cette section est indispensable, sans quoi le PIC sera configuré n’importe comment et risque de ne pas démarrer ou faire n’importe quoi.
  • Un programme c démarre toujours dans la procédure main: Celle-ci ne fait pas grand-chose: elle appelle une fois Setup() puis elle appelle toujours la procédure Loop()
  • Setup configure les Ports du PIC pour lui dire ce qui est des entrées et ce qui est des sorties (un bit à 0 dans TRISx = sortie).
  • Loop ne fait que d'appeler AfficherImage qui fait le travail de scanner le tableau Image et de le mettre sur les leds

Affichage d'images variables

modifier

Le programme suivant permet de mettre plusieurs images et possède quelques effets comme des spirales. Ceci permet d’avoir un programme principal plus ludique puisqu'on peut enchainer plusieurs figures.

  //------------------------------------------------------------------------------------------
  // Programme de démonstration qui affiche une image sur le Bico64
  //------------------------------------------------------------------------------------------

 
  #define __16F887
  #include <pic16f887.h>
 
  //------------------------------------------------------------------------------------------
  // Configuration du PIC 16F884 selon Bico64
  //------------------------------------------------------------------------------------------
  __code __at _CONFIG1 unsigned int Config1 =
     _INTOSCIO  // I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
   & _WDT_OFF   // pas de Watch Dog
   & _PWRTE_ON  // on attend un peu au démarrage
   & _MCLRE_ON  // RE3/MCLR pin function is MCLR
   & _CP_OFF    // Program memory code protection is disabled
   & _CPD_OFF   // Data memory code protection is disabled
   & _BOR_OFF   // BOR Disabled
   & _IESO_OFF  // Internal/External Switchover mode is disabled
   & _FCMEN_OFF // Fail-Safe Clock Monitor is disabled
   & _LVP_OFF   // RB3 pin is digital I/O, HV on MCLR must be used for programming
   & _DEBUG_OFF;// In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins
 
  __code __at _CONFIG2 unsigned int Config2 =
     _WRT_OFF // No prog memmory write protection
   & _BOR21V;  // Brown-Out Reset at 2.1V

  //-------------------------------------------------------------
  // Initialisation
  //-------------------------------------------------------------
  // on donne des noms significatifs aux PORTs utilisés
  #define byte unsigned char
  #define PLIGNE PORTB
  #define PVERT  PORTC
  #define PROUGE PORTD

  void Setup(void) {
    TRISB = 0x00;       // PortB est en sortie
    TRISC = 0x00;       // PortC est en sortie
    TRISD = 0x00;       // PortD est en sortie
    TRISA = 0xFF;       // PortA est en entrée
  }

  byte image[16];

  __code byte coeur[16] = {
    //  Vert      Rouge          PLIGNE
    0b11111111,0b00000000,      // D0
    0b10011001,0b01100110,      // D1
    0b00000000,0b11111111,      // D2
    0b00000000,0b11111111,      // D3
    0b10000001,0b01111110,      // D4
    0b11000011,0b00111100,      // D5
    0b11100111,0b00011000,      // D6
    0b11111111,0b00000000,      // D7
  };
  __code byte pique[16] = {
    //  Vert      Rouge
    0b00011000,0b00011000,
    0b00111100,0b00111100,
    0b01111110,0b01111110,
    0b11111111,0b11111111,
    0b11111111,0b11111111,
    0b01011010,0b01011010,
    0b00011000,0b00011000,
    0b00111100,0b00111100,
  };
  __code byte rouge[16] = {
    //  Vert      Rouge
    0b00000000,0b11111111,
    0b00000000,0b11111111,
    0b00000000,0b11111111,
    0b00000000,0b11111111,
    0b00000000,0b11111111,
    0b00000000,0b11111111,
    0b00000000,0b11111111,
    0b00000000,0b11111111,
  };
  __code byte noir[16] = {
    //  Vert      Rouge
    0b00000000,0b00000000,
    0b00000000,0b00000000,
    0b00000000,0b00000000,
    0b00000000,0b00000000,
    0b00000000,0b00000000,
    0b00000000,0b00000000,
    0b00000000,0b00000000,
    0b00000000,0b00000000,
  };

  void CopierImage(byte *newImage){
    short i;
    for (i=0;i<16;i++){
      image[i] = *newImage;
      newImage++;
    }
  }

  void EffacerImage(void) {
    short i;
    for (i=0;i<16;i++){
      image[i] = 0;
    }
  }


  #define NOIR  0
  #define VERT  1
  #define ROUGE 2
  #define JAUNE 3

  void MettrePixel(short col,short ligne, byte couleur){
    byte BitCol = 0b00000001 << col;
 
    if (couleur & VERT) {
      image[ligne*2] = image[ligne*2] | BitCol;
    }
    else {
      image[ligne*2] = image[ligne*2] & ~BitCol;
    };
    if (couleur & ROUGE) {
      image[ligne*2+1] = image[ligne*2+1] | BitCol;
    }
    else {
      image[ligne*2+1] = image[ligne*2+1] & ~BitCol;
    }
  }

  void AfficherImage(byte temps) {
     int i,n;
     byte ligne;
     byte *p;                       //p pointe sur le premier byte du tableau image
 
     for (n=0;n<temps;n++){
       p = &image[0];
       ligne = 0b11111110;          // dans Ligne, on aura la ligne active à 0; on décalera le 0 pour chaque ligne
       while (ligne != 0b11111111){ // tant qu’il reste un 0, on n'a pas terminé de balayer l'image
         PLIGNE = 0b11111111;       // pour éviter de voir des petits "phantomes" de la ligne précédente
                                    // on ne sélectionne aucune ligne
         PVERT  = *p++;             // on met les bits pour la couleur Rouge
         PROUGE = *p++;             // on met les bits pour la couleur Verte
         PLIGNE = ligne;            // on met la ligne (le bon bit à 0)
         ligne = (ligne << 1) +1 ;  // on décale le bit à 0 de un bit, comme cela met D0 à 0, on
                                    // force D0 à 1 pour n'avoir qu'un bit à 0 (ligne active)
         for (i=0;i<50;i++) {};     // on attend un peu pour avoir le temps de voir cette ligne
       }
     }
  }


  void AfficherSpirale(byte couleur,byte temps){
  //-------------------------------------------------------------
  // On affiche une spirale qui tourne de manière anti-horaire de
  // l'exterieur vers l'intérieur. D'une couleur donnée
  //-------------------------------------------------------------
    short c=0,l=0;
    short rangee;
 
    for (rangee=0;rangee<=3;rangee++) {
      for (c=rangee;c<=7-rangee;c++){
        MettrePixel(c,l,couleur);
        AfficherImage(temps);
      }
      c--;
      for (l=rangee+1;l<=7-rangee;l++){
        MettrePixel(c,l,couleur);
        AfficherImage(temps);
      }
      l--;
      for (c=7-1-rangee;c>=rangee;c--){
        MettrePixel(c,l,couleur);
        AfficherImage(temps);
      }
      c++;
      for (l=7-1-rangee;l>=rangee+1;l--){
        MettrePixel(c,l,couleur);
        AfficherImage(temps);
      }
      l++;
    }
  }

  void AfficherBalayageGauche(byte couleur,byte temps){
  //-------------------------------------------------------------
  // On balaie de droite à gauche avec une couleur donnée
  //-------------------------------------------------------------
    short c=0,l=0;
    for (c=0;c<=7;c++){
      for (l=0;l<=7;l++){
         MettrePixel(c,l,couleur);
         AfficherImage(temps);
      }
    }
  }

  void AfficherBalayageDroite(byte couleur,byte temps){
  //-------------------------------------------------------------
  // On balaie de droite à gauche avec une couleur donnée
  //-------------------------------------------------------------
    short c=0,l=0;
    for (c=7;c>=0;c--){
      for (l=0;l<8;l++){
         MettrePixel(c,l,couleur);
         AfficherImage(temps);
      }
    }
  }

/*
==== Pour les débutants: commencez par modifier ce bout de programme  ====
.*/
  void Loop(void) {
  //-------------------------------------------------------------
  // La boucle principale:
  //-------------------------------------------------------------
    int i;
    byte l;
 
    EffacerImage();
    AfficherSpirale(VERT,20);
    AfficherSpirale(JAUNE,20);
    AfficherSpirale(ROUGE,20);
    
    for (i=10; i<10; i++){
      CopierImage(&noir[0]);
      AfficherImage(25);
      CopierImage(&rouge[0]);
      AfficherImage(25);
    }
 
    for (l=2;l<=16;l+=2){
      CopierImage(&coeur[l]);
      AfficherImage(20);
    }
    AfficherImage(100);
    for (i=0;i<5;i++){
      AfficherBalayageGauche(VERT,i);
      AfficherBalayageDroite(ROUGE,i);
    }
    AfficherSpirale(VERT,50);
    AfficherSpirale(ROUGE,10);
    AfficherSpirale(JAUNE,5);
    AfficherSpirale(NOIR,1);
  }

  //-------------------------------------------------------------
  // Programme principal (là où le PIC va démarrer)
  //-------------------------------------------------------------
  void main(void) {
    Setup();
    while(1) {
      Loop();
    }
  }

Affichage d'images variables, avec utilisation d'un timer

modifier

Ce programme ressemble au précédent, mais fait usage d'un timer

 //------------------------------------------------------------------------------------------
 // Programme de démonstration qui affiche une image sur le Bico64
 //------------------------------------------------------------------------------------------


 #define __16F887
 #include <pic16f887.h>

 //------------------------------------------------------------------------------------------
 // Configuration du PIC 16F884 selon Bico64
 //------------------------------------------------------------------------------------------
 __code __at _CONFIG1 unsigned int Config1 =
    _INTOSCIO  // I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
  & _WDT_OFF   // pas de Watch Dog
  & _PWRTE_ON  // on attend un peu au démarrage
  & _MCLRE_ON  // RE3/MCLR pin function is MCLR
  & _CP_OFF    // Program memory code protection is disabled
  & _CPD_OFF   // Data memory code protection is disabled
  & _BOR_OFF   // BOR Disabled
  & _IESO_OFF  // Internal/External Switchover mode is disabled
  & _FCMEN_OFF // Fail-Safe Clock Monitor is disabled
  & _LVP_OFF   // RB3 pin is digital I/O, HV on MCLR must be used for programming
  & _DEBUG_OFF;// In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins

 __code __at _CONFIG2 unsigned int Config2 =
    _WRT_OFF // No prog memmory write protection
  & _BOR21V;  // Brown-Out Reset at 2.1V

 //-------------------------------------------------------------
 // Initialisation
 //-------------------------------------------------------------
 // on donne des noms significatifs aux PORTs utilisés
 #define byte unsigned char
 #define PLIGNE PORTB
 #define PVERT  PORTC
 #define PROUGE PORTD

 void Setup(void) {
   TRISB = 0x00;       // PortB est en sortie
   TRISC = 0x00;       // PortC est en sortie
   TRISD = 0x00;       // PortD est en sortie
   TRISA = 0xFF;       // PortA est en entrée

   OPTION_REG = 0b11000000; //1   Pas de pull-up pour le portB,
                            //1   interrupt rising edge of INT
                            //0   Timer0 utilise l'internal instruction clock
                            //0   incrément low-to-high de T0CKI (innutile dans ce cas)
                            //0   Prescaler utilisé pour le timer0
                            //000 Prescaler divise par 2  (==> 8Mhz / 4 /2 = un incrément toutes les 1us
   TMR0 = 0;
   T0IF = 0;
 }

 byte image[16];

 __code byte coeur[16] = {
   //  Vert      Rouge          PLIGNE
   0b11111111,0b00000000,      // D0
   0b10011001,0b01100110,      // D1
   0b00000000,0b11111111,      // D2
   0b00000000,0b11111111,      // D3
   0b10000001,0b01111110,      // D4
   0b11000011,0b00111100,      // D5
   0b11100111,0b00011000,      // D6
   0b11111111,0b00000000,      // D7
 };
 __code byte pique[16] = {
   //  Vert      Rouge
   0b00011000,0b00011000,
   0b00111100,0b00111100,
   0b01111110,0b01111110,
   0b11111111,0b11111111,
   0b11111111,0b11111111,
   0b01011010,0b01011010,
   0b00011000,0b00011000,
   0b00111100,0b00111100,
 };
 __code byte rouge[16] = {
   //  Vert      Rouge
   0b00000000,0b11111111,
   0b00000000,0b11111111,
   0b00000000,0b11111111,
   0b00000000,0b11111111,
   0b00000000,0b11111111,
   0b00000000,0b11111111,
   0b00000000,0b11111111,
   0b00000000,0b11111111,
 };
 __code byte noir[16] = {
   //  Vert      Rouge
   0b00000000,0b00000000,
   0b00000000,0b00000000,
   0b00000000,0b00000000,
   0b00000000,0b00000000,
   0b00000000,0b00000000,
   0b00000000,0b00000000,
   0b00000000,0b00000000,
   0b00000000,0b00000000,
 };

 void CopierImage(byte *newImage){
   byte i;
   for (i=0;i<16;i++){
     image[i] = *newImage;
     newImage++;
   }
 }

 void EffacerImage(void) {
   byte i;
   for (i=0;i<16;i++){
     image[i] = 0;
   }
 }


 #define NOIR  0
 #define VERT  1
 #define ROUGE 2
 #define JAUNE 3

 void MettrePixel(byte col,byte ligne, byte couleur){
   byte BitCol = 0b00000001 << col;

   if (couleur & VERT) {
     image[ligne*2] = image[ligne*2] | BitCol;
   }
   else {
     image[ligne*2] = image[ligne*2] & ~BitCol;
   };
   if (couleur & ROUGE) {
     image[ligne*2+1] = image[ligne*2+1] | BitCol;
   }
   else {
     image[ligne*2+1] = image[ligne*2+1] & ~BitCol;
   }
 }

 void AfficherImage(int temps) {
 //-------------------------------------------------------------
 // On affiche l'image "temps" fois si temps vaut 1,
 // la procedure AfficherImage dure 1ms
 // donc si on écrit AfficherImage(1000) cela prendra 1s
 //-------------------------------------------------------------
    int n;
    byte ligne;
    byte *p;                       //p pointe sur le premier byte du tableau image

    for (n=0;n<temps;n+=2){
      p = &image[0];
      ligne = 0b11111110;          // dans Ligne, on aura la ligne active à 0; on décalera le 0 pour chaque ligne
      while (ligne != 0b11111111){ // tant qu’il reste un 0, on n'a pas terminé de balayer l'image
        while (T0IF==0){
        };          // attend que le timer0 soit arrivé au bout

        TMR0 = 6;                 // on remet le timer à 250us : -250 = 6 sur un byte; le compteur comptera de 6 à 256
        T0IF = 0;
        PLIGNE = 0b11111111;       // pour éviter de voir des petits "phantomes" de la ligne précédente
                                   // on ne sélectionne aucune ligne
        PVERT  = *p++;             // on met les bits pour la couleur Rouge
        PROUGE = *p++;             // on met les bits pour la couleur Verte
        PLIGNE = ligne;            // on met la ligne (le bon bit à 0)
        ligne = (ligne << 1) +1 ;  // on décale le bit à 0 de un bit, comme cela met D0 à 0, on
                                   // force D0 à 1 pour n'avoir qu'un bit à 0 (ligne active)
      }
    }
 }


 void AfficherSpirale(byte couleur,byte temps){
 //-------------------------------------------------------------
 // On affiche une spirale qui tourne de manière anti-horaire de
 // l'exterieur vers l'intérieur. D'une couleur donnée
 // Temps est le nombre de fois 1ms pour afficher un point:
 // comme il y a 64 Led, AffichierSpirale(100) met 640ms pour faire la spirale
 //-------------------------------------------------------------
   short c=0,l=0;
   byte rangee;

   for (rangee=0;rangee<=3;rangee++) {
     for (c=rangee;c<=7-rangee;c++){
       MettrePixel(c,l,couleur);
       AfficherImage(temps);
     }
     c--;
     for (l=rangee+1;l<=7-rangee;l++){
       MettrePixel(c,l,couleur);
       AfficherImage(temps);
     }
     l--;
     for (c=7-1-rangee;c>=rangee;c--){
       MettrePixel(c,l,couleur);
       AfficherImage(temps);
     }
     c++;
     for (l=7-1-rangee;l>=rangee+1;l--){
       MettrePixel(c,l,couleur);
       AfficherImage(temps);
     }
     l++;
   }
 }

 void AfficherBalayageGauche(byte couleur,byte temps){
 //-------------------------------------------------------------
 // On balaie de droite à gauche avec une couleur donnée
 // Temps est le nombre de fois 1ms pour afficher un point:
 // comme il y a 64 Led, AffichierSpirale(100) met 640ms pour faire le balayage
 //-------------------------------------------------------------
   short c=0,l=0;
   for (c=0;c<=7;c++){
     for (l=0;l<=7;l++){
        MettrePixel(c,l,couleur);
        AfficherImage(temps);
     }
   }
 }

 void AfficherBalayageDroite(byte couleur,byte temps){
 //-------------------------------------------------------------
 // On balaie de droite à gauche avec une couleur donnée
 // Temps est le nombre de fois 1ms pour afficher un point:
 // comme il y a 64 Led, AffichierSpirale(100) met 640ms pour faire le balayage
 //-------------------------------------------------------------
   short c=0,l=0;
   for (c=7;c>=0;c--){
     for (l=0;l<8;l++){
        MettrePixel(c,l,couleur);
        AfficherImage(temps);
     }
   }
 }

/*
Pour les débutants: commencez par modifier ce bout de programme
.*/
 void Loop(void) {
 //-------------------------------------------------------------
 // La boucle principale
 //-------------------------------------------------------------
   int i;
   byte l;

   EffacerImage();
   AfficherSpirale(VERT,1);
   AfficherSpirale(JAUNE,2);
   AfficherSpirale(ROUGE,3);
  
   for (i=0; i<10; i++){
     CopierImage(&noir[0]);
     AfficherImage(25);
     CopierImage(&rouge[0]);
     AfficherImage(25);
   }

   for (l=2;l<=16;l+=2){
     CopierImage(&coeur[l]);
     AfficherImage(20);
   }
   AfficherImage(100);
   for (i=0;i<5;i++){
     AfficherBalayageGauche(VERT,i);
     AfficherBalayageDroite(ROUGE,i);
   }
   AfficherSpirale(VERT,50);
   AfficherSpirale(ROUGE,10);
   AfficherSpirale(JAUNE,5);
   AfficherSpirale(NOIR,1);
 }

 //-------------------------------------------------------------
 // Programme principal (là où le PIC va démarrer)
 //-------------------------------------------------------------
 void main(void) {
   Setup();
   while(1) {
     Loop();
   }
 }