Répondre à la discussion
Affichage des résultats 1 à 9 sur 9

PIC 16F877A et MicroC



  1. #1
    mitantsoa

    PIC 16F877A et MicroC

    Bonjour,
    quelqu'un peut me résoudre ce problème s'il vous plait
    " IRP bit must be set manually for indirect access to 'value' variable __Lib_CMath.c"
    Merci!

    -----


  2. Publicité
  3. #2
    antek

    Re : PIC 16F877A et MicroC

    Quel problème ?
    Tu connais la fonction du bit IRP ?
    Le Diable a inventé l'Administration afin que les Hommes perdent tout espoir à jamais.

  4. #3
    mitantsoa

    Re : PIC 16F877A et MicroC

    malheureusement,je ne la connait pas vraiment.

  5. #4
    Chtulhu

    Re : PIC 16F877A et MicroC

    IRP est un bit de sélection de bank pour l'adressage indirect.
    IRP=0 -> bank 0,1
    IRP=1 -> bank 2,3

    MikroC ne gère pas automatiquement cela sur les vieux PIC.
    D'où le message de le faire à la main, ça n'a rien de très compliqué si vous savez coder et que vous avez lu la doc de votre µC.

    Il faudrait quand même poster votre code si vous voulez de l'aide...
    Ou sinon vous passez en PIC18 et vous n'aurez plus ce problème.

  6. #5
    adipie

    Re : PIC 16F877A et MicroC

    Bonjour,
    Ce que dit Mikroe (traduction) :
    Vous avez un problème de banque de mémoire. IRP est le bit de sélection de banque utilisé pour le traitement indirect.
    adressage.Notre compilateur n'est pas capable de définir le bit IRP.

    IRP = 0 -> Banque 0,1
    IRP = 1 -> Banque 2,3

    Donc, vous devez le faire manuellement. Aussi, vous pouvez utiliser la directive 'absolue' et
    move variable aux banques de mémoire 0 et 1 (directive absolue spécifie l'adresse de départ en RAM pour la variable.
    Si la variable est multi-octets, les octets les plus élevés seront stockés à la suite
    Emplacements).

    Au lieu de cela, PIC16F vous pouvez toujours utiliser PIC18F.
    De cette façon, vous n'aurez aucun problème avec les banques de mémoire.

  7. A voir en vidéo sur Futura
  8. #6
    antek

    Re : PIC 16F877A et MicroC

    Citation Envoyé par mitantsoa Voir le message
    malheureusement,je ne la connait pas vraiment.
    Il faut donc lire la doc !
    Le Diable a inventé l'Administration afin que les Hommes perdent tout espoir à jamais.

  9. Publicité
  10. #7
    mitantsoa

    Re : PIC 16F877A et MicroC

    Voici le code
    Code:
        sbit LCD_RS at RB0_bit;
        sbit LCD_EN at RB1_bit;
        sbit LCD_D4 at RB2_bit;
        sbit LCD_D5 at RB3_bit;
        sbit LCD_D6 at RB4_bit;
        sbit LCD_D7 at RB5_bit;
    
        sbit LCD_RS_Direction at TRISB0_bit;
        sbit LCD_EN_Direction at TRISB1_bit;
        sbit LCD_D4_Direction at TRISB2_bit;
        sbit LCD_D5_Direction at TRISB3_bit;
        sbit LCD_D6_Direction at TRISB4_bit;
        sbit LCD_D7_Direction at TRISB5_bit;
    
    
    void Float2String (float x, unsigned char *str,char precision)
        {
        // converts a floating point number to an ascii string
        // version limitée à 5 decimales maximum
        // x is stored into str, which should be at least 30 chars long
         int ie, i, k, ndig;
         double y;
         if (precision>=5) precision=5; else precision++;
         ndig = precision;
    
         ie = 0;
        // if x negative, write minus and reverse
         if ( x < 0.00000)
          {
           *str++ = '-';
            x = -x;
          }
        // put x in range 1 <= x < 10
         if (x > 0.000000)
          while (x < 1.000000)
           {
            x *= 10.000; // a la place de =*
            ie--;
           }
          while (x >= 10.0000)
           {
             x = x/10.0000;
             ie++;
           }
        // in f format, number of digits is related to size
         ndig += ie; // a la place de =+
        //round. x is between 1 and 10 and ndig will be printed to
        // right of decimal point so rounding is ...
         for (y = i = 1; i < ndig; i++)
             y = y/10.0000;
             x += y/2.0000;
         if (x >= 10.0000) {x = 1.0000; ie++;}
           if (ie<0)
            {
             *str++ = '0';
             *str++ = '.';
             if (ndig < 0)
               ie = ie-ndig;
             for (i = -1; i > ie; i--)
               *str++ = '0';
            }
         for (i=0; i < ndig; i++)
           {
            k = x;
            *str++ = k + '0';
            if (i == ie )
            *str++ = '.';
            x -= (y=k);
            x *= 10.0000;
          }
        *str = '\0';
        }
       // fin de FloatToString
       
      
    void main()
        {
             float entree=0.00,Vc,tempo=0.00;
             char sortie[50];
             //char maxi[50];
            float nbr=0.0, a= 3.2;
             float Vs=0.0, expo= 1.0;
             int i, aff=0;
             float gain= 21.0,Gd=0.0671;
    
             Lcd_Init();
             Lcd_Cmd(_LCD_CLEAR);               // Clear display
             Lcd_Cmd(_LCD_CURSOR_OFF);
    
             Adc_init();
    
             TRISA  = 0xFF;  // programmtion du PORTA en entrée
             TRISD  = 0xFF;
             TRISB  = 0;         // programmtion du PORTB en sortie
    
             OPTION_REG.NOT_RBPU = 0;
    
           do
             {
              ADCON1=0x80;
    
                 a = (float)ADC_Read(0)*5.0/(1024.0*Gd);   // Get 10-bit results of AD conversion in RA0
                 Vc = (float)ADC_Read(2)*5.0/1024.0;        // Get 10-bit results of AD conversion in RA1
    
                  Vs= a;
                      nbr = ((Vs/gain) - 2.034)*6.38607;
                      expo =  exp(nbr);
                        entree= 285.71428 * expo;
    
    // fin pour W/m2
    
                 if ((Vc>= 0) && (Vc<= 1.2))
                    {
                      if (aff!= 1)
                        {
                          Lcd_Cmd(_LCD_CLEAR);
                          tempo= 0;
                          aff =1;
                        }
                    entree = (entree * entree /377);
                      if (tempo<entree)
                        tempo= entree;
                        Float2String (tempo,sortie,4);
                        Lcd_Out(2, 1, sortie);
                      entree = (entree *1.0000);
                        Float2String (entree,sortie,4);
                        Lcd_Out(1, 1, sortie);
                        Lcd_Out(1, 10, "W/m2");
    
                               if(entree >= 0.09549)
                                  Lcd_Out(2, 10, "FORT");
                                if(entree<0.09549 && entree>0.029999)
                                  Lcd_Out(2, 10, "MOYEN");
                                if(entree <=0.029999)
                                  Lcd_Out(2, 10, "FAIBLE");
                    }
    
    // fin pour W/m2
                 if ((Vc> 1.2) && (Vc< 2.8))
                    {
                      if (aff!= 2)
                        {
                          Lcd_Cmd(_LCD_CLEAR);
                          tempo= 0;
                          aff =2;
                        }
                         //F1= 0.0001;
                    entree = entree *1.0000;
                      if (tempo<entree)
                        tempo= entree;
                        Float2String (tempo,sortie,4);
                        Lcd_Out(2, 1, sortie);
                      entree = entree *1.0000;
                        Float2String (entree,sortie,4);
                        Lcd_Out(1, 1, sortie);
                        Lcd_Out(1, 10, "V/m");
    
                                if(entree >= 6)
                                  Lcd_Out(2, 10, "FORT");
                                if(entree<6 && entree>3.363)
                                  Lcd_Out(2, 10, "MOYEN");
                                if(entree <=3.363)
                                  Lcd_Out(2, 10, "FAIBLE");
                    }       
    // fin pour V/m
    
                  if ((Vc>=2.9) && (Vc < 5))
                    {
                       if (aff!= 3)
                       {
                         Lcd_Cmd(_LCD_CLEAR);
                         tempo =0;
                         aff =3;
                       }
                       entree= entree*1.0/377;
    
                       if (tempo<entree)
                         tempo= entree;
                         Float2String (tempo,sortie,4);
                         Lcd_Out(2, 1, sortie);
                         entree = 1.0* entree;
    
                         Float2String (entree,sortie,4);
                         Lcd_Out(1, 1, sortie);
                         Lcd_Out(1, 12,"A/m" );
    
                               if(entree >= 0.015915)
                                 Lcd_Out(2, 10, "FORT");
                               if(entree<0.015915 && entree>0.00892)
                                 Lcd_Out(2, 10, "MOYEN");
                               if(entree <=0.00892)
                                 Lcd_Out(2, 10, "FAIBLE");
                    }
                                      
          Delay_ms(1000) ;
               }
               while(1);
          }

  11. #8
    Chtulhu

    Re : PIC 16F877A et MicroC

    Vous pouvez dans un premier temps essayer de limiter les textes placées en RAM en les stockant en dur et passer par une fonction pour les appeler en RAM uniquement lorsque le texte appelé est utilisé.

    Code:
    const char txt1[]    = "      FORT      ";
    const char txt2[]    = "     MOYEN    "; 
    const char txt3[]    = "     FAIBLE     ";
    const char txt4[]    = "      V/m        ";
    const char txt5[]    = "      A/m        ";
    
    char msg[17]; 
    
    // extrait un texte pour le mettre en RAM
    char * Copy_ConstToRam(char * dest_ram, const char * src)
          {
          char * r ;
          r = dest_ram;
             for(;*dest_ram++ = *src++;);
         return r;
    }
    Usage:

    Code:
    Lcd_Out(1,1,Copy_ConstToRam(msg,txt1));
    A tester.

    L'usage des float est très gourmand en ressource RAM pour ce petit PIC, il serait bon de travailler le plus possible avec des int et d'utiliser les divisions par décalage de 2^n et placer le point décimal lors du formatage de l'affichage vers le display.

  12. #9
    Chtulhu

    Re : PIC 16F877A et MicroC

    Sinon j'ai testé cette version de votre programme sous MiKroE v7.5.0 qui compile correctement.
    J'ai apporté la modification suivante:

    -> remplacement de votre fonction Float2String par la librairie du compilateur FloatToString

    Code:
        sbit LCD_RS at RB0_bit;
        sbit LCD_EN at RB1_bit;
        sbit LCD_D4 at RB2_bit;
        sbit LCD_D5 at RB3_bit;
        sbit LCD_D6 at RB4_bit;
        sbit LCD_D7 at RB5_bit;
    
        sbit LCD_RS_Direction at TRISB0_bit;
        sbit LCD_EN_Direction at TRISB1_bit;
        sbit LCD_D4_Direction at TRISB2_bit;
        sbit LCD_D5_Direction at TRISB3_bit;
        sbit LCD_D6_Direction at TRISB4_bit;
        sbit LCD_D7_Direction at TRISB5_bit;
    
    
    
    
    void main()
        {
             float entree=0.00,Vc,tempo=0.00;
             char sortie[50];
             //char maxi[50];
            float nbr=0.0, a= 3.2;
             float Vs=0.0, expo= 1.0;
             int i, aff=0;
             float gain= 21.0,Gd=0.0671;
    
             Lcd_Init();
             Lcd_Cmd(_LCD_CLEAR);               // Clear display
             Lcd_Cmd(_LCD_CURSOR_OFF);
    
             Adc_init();
    
             TRISA  = 0xFF;  // programmtion du PORTA en entrée
             TRISD  = 0xFF;
             TRISB  = 0;         // programmtion du PORTB en sortie
    
             OPTION_REG.NOT_RBPU = 0;
    
           do
             {
              ADCON1=0x80;
    
                 a = ADC_Read(0)*5.0/(1024.0*Gd);   // Get 10-bit results of AD conversion in RA0
                 Vc = ADC_Read(2)*5.0/1024.0;        // Get 10-bit results of AD conversion in RA1
    
                  Vs= a;
                      nbr = ((Vs/gain) - 2.034)*6.38607;
                      expo =  exp(nbr);
                        entree= 285.71428 * expo;
    
    // fin pour W/m2
    
                 if ((Vc>= 0) && (Vc<= 1.2))
                    {
                      if (aff!= 1)
                        {
                          Lcd_Cmd(_LCD_CLEAR);
                          tempo= 0;
                          aff =1;
                        }
                    entree = (entree * entree /377);
                      if (tempo<entree)
                        tempo= entree;
                        FloatToStr (tempo,sortie);
                        Lcd_Out(2, 1, sortie);
                      entree = (entree *1.0000);
                        FloatToStr (entree,sortie);
                        Lcd_Out(1, 1, sortie);
                        Lcd_Out(1, 10, "W/m2");
    
                               if(entree >= 0.09549)
                                  Lcd_Out(2, 10, "FORT");
                                if(entree<0.09549 && entree>0.029999)
                                  Lcd_Out(2, 10, "MOYEN");
                                if(entree <=0.029999)
                                  Lcd_Out(2, 10, "FAIBLE");
                    }
    
    // fin pour W/m2
                 if ((Vc>= 1.2) && (Vc<= 2.8))
                    {
                      if (aff!= 2)
                        {
                          Lcd_Cmd(_LCD_CLEAR);
                          tempo= 0;
                          aff =2;
                        }
                         //F1= 0.0001;
                    entree = entree *1.0000;
                      if (tempo<entree)
                        tempo= entree;
                        FloatToStr (tempo,sortie);
                        Lcd_Out(2, 1, sortie);
                      entree = entree *1.0000;
                        FloatToStr (entree,sortie);
                        Lcd_Out(1, 1, sortie);
                        Lcd_Out(1, 10, "V/m");
    
                                if(entree >= 6)
                                  Lcd_Out(2, 10, "FORT");
                                if(entree<6 && entree>3.363)
                                  Lcd_Out(2, 10, "MOYEN");
                                if(entree <=3.363)
                                  Lcd_Out(2, 10, "FAIBLE");
                    }
    // fin pour V/m
    
                  if ((Vc>=2.9) && (Vc <= 5.0))
                    {
                       if (aff!= 3)
                       {
                         Lcd_Cmd(_LCD_CLEAR);
                         tempo =0;
                         aff =3;
                       }
                       entree= entree*1.0/377.0;
    
                       if (tempo<entree)
                         tempo= entree;
                         FloatToStr (tempo,sortie);
                         Lcd_Out(2, 1, sortie);
                         entree = 1.0* entree;
    
                         FloatToStr (entree,sortie);
                         Lcd_Out(1, 1, sortie);
                         Lcd_Out(1, 12,"A/m" );
    
                               if(entree >= 0.015915)
                                 Lcd_Out(2, 10, "FORT");
                               if(entree<0.015915 && entree>0.00892)
                                 Lcd_Out(2, 10, "MOYEN");
                               if(entree <=0.00892)
                                 Lcd_Out(2, 10, "FAIBLE");
                    }
    
          Delay_ms(1000) ;
               }
               while(1);
          }
    En apportant la modification décrite en #8 on améliore la situation en RAM de 14%:

    message_compilateur.JPG

    Code:
        sbit LCD_RS at RB0_bit;
        sbit LCD_EN at RB1_bit;
        sbit LCD_D4 at RB2_bit;
        sbit LCD_D5 at RB3_bit;
        sbit LCD_D6 at RB4_bit;
        sbit LCD_D7 at RB5_bit;
    
        sbit LCD_RS_Direction at TRISB0_bit;
        sbit LCD_EN_Direction at TRISB1_bit;
        sbit LCD_D4_Direction at TRISB2_bit;
        sbit LCD_D5_Direction at TRISB3_bit;
        sbit LCD_D6_Direction at TRISB4_bit;
        sbit LCD_D7_Direction at TRISB5_bit;
    char txt[6];
    
    const char txt1[]    = "FORT";
    const char txt2[]    = "MOYEN";
    const char txt3[]    = "FAIBLE";
    const char txt4[]    = "V/m";
    const char txt5[]    = "A/m";
    const char txt6[]    = "W/m2";
    
    char msg[17];
    
    // extrait un texte pour le mettre en RAM
    char * Copy_ConstToRam(char * dest_ram, const char * src)
          {
          char * r ;
          r = dest_ram;
             for(;*dest_ram++ = *src++;);
         return r;
    }
    
    
    void main()
        {
             float entree=0.00,Vc,tempo=0.00;
             char sortie[50];
             //char maxi[50];
            float nbr=0.0, a= 3.2;
             float Vs=0.0, expo= 1.0;
             int i, aff=0;
             float gain= 21.0,Gd=0.0671;
    
             Lcd_Init();
             Lcd_Cmd(_LCD_CLEAR);               // Clear display
             Lcd_Cmd(_LCD_CURSOR_OFF);
    
             Adc_init();
    
             TRISA  = 0xFF;  // programmtion du PORTA en entrée
             TRISD  = 0xFF;
             TRISB  = 0;         // programmtion du PORTB en sortie
    
             OPTION_REG.NOT_RBPU = 0;
    
           do
             {
              ADCON1=0x80;
    
                 a = ADC_Read(0)*5.0/(1024.0*Gd);   // Get 10-bit results of AD conversion in RA0
                 Vc = ADC_Read(2)*5.0/1024.0;        // Get 10-bit results of AD conversion in RA1
    
                  Vs= a;
                      nbr = ((Vs/gain) - 2.034)*6.38607;
                      expo =  exp(nbr);
                        entree= 285.71428 * expo;
    
    // fin pour W/m2
    
                 if ((Vc>= 0) && (Vc<= 1.2))
                    {
                      if (aff!= 1)
                        {
                          Lcd_Cmd(_LCD_CLEAR);
                          tempo= 0;
                          aff =1;
                        }
                    entree = (entree * entree /377);
                      if (tempo<entree)
                        tempo= entree;
                        FloatToStr (tempo,sortie);
                        Lcd_Out(2, 1, sortie);
                      entree = (entree *1.0000);
                        FloatToStr (entree,sortie);
                        Lcd_Out(1, 1, sortie);
    
                        Lcd_Out(1,10,Copy_ConstToRam(msg,txt6)); //W/m²
    
                               if(entree >= 0.09549)
    
                                  Lcd_Out(2, 10,Copy_ConstToRam(msg,txt1)); //FORT
                                if(entree<0.09549 && entree>0.029999)
    
                                  Lcd_Out(2,10,Copy_ConstToRam(msg,txt2)); //MOYEN
                                if(entree <=0.029999)
    
                                  Lcd_Out(2,10,Copy_ConstToRam(msg,txt3)); //FAIBLE
                    }
    
    // fin pour W/m2
                 if ((Vc>= 1.2) && (Vc<= 2.8))
                    {
                      if (aff!= 2)
                        {
                          Lcd_Cmd(_LCD_CLEAR);
                          tempo= 0;
                          aff =2;
                        }
                         //F1= 0.0001;
                    entree = entree *1.0000;
                      if (tempo<entree)
                        tempo= entree;
                        FloatToStr (tempo,sortie);
                        Lcd_Out(2, 1, sortie);
                      entree = entree *1.0000;
                        FloatToStr (entree,sortie);
                        Lcd_Out(1, 1, sortie);
    
                        Lcd_Out(1,10,Copy_ConstToRam(msg,txt4));
    
                                if(entree >= 6)
    
                                   Lcd_Out(2, 10,Copy_ConstToRam(msg,txt1)); //FORT
                                if(entree<6 && entree>3.363)
    
                                  Lcd_Out(2,10,Copy_ConstToRam(msg,txt2)); //MOYEN
                                if(entree <=3.363)
    
                                  Lcd_Out(2,10,Copy_ConstToRam(msg,txt3)); //FAIBLE
                    }
    // fin pour V/m
    
                  if ((Vc>=2.9) && (Vc <= 5.0))
                    {
                       if (aff!= 3)
                       {
                         Lcd_Cmd(_LCD_CLEAR);
                         tempo =0;
                         aff =3;
                       }
                       entree= entree*1.0/377.0;
    
                       if (tempo<entree)
                         tempo= entree;
                         FloatToStr (tempo,sortie);
                         Lcd_Out(2, 1, sortie);
                         entree = 1.0* entree;
    
                         FloatToStr (entree,sortie);
                         Lcd_Out(1, 1, sortie);
    
                         Lcd_Out(1,12,Copy_ConstToRam(msg,txt5));
                         
                               if(entree >= 0.015915)
    
                                 Lcd_Out(2, 10,Copy_ConstToRam(msg,txt1)); //FORT
                               if(entree<0.015915 && entree>0.00892)
    
                                 Lcd_Out(2,10,Copy_ConstToRam(msg,txt2)); //MOYEN
                               if(entree <=0.00892)
    
                                 Lcd_Out(2,10,Copy_ConstToRam(msg,txt3)); //FAIBLE
                    }
    
          Delay_ms(1000) ;
               }
               while(1);
          }
    Résultat de compilation:

    message_compilateur2.JPG

Sur le même thème :

Discussions similaires

  1. programme microc
    Par naoufalmek78 dans le forum Électronique
    Réponses: 2
    Dernier message: 10/06/2014, 17h26
  2. Choix du microC
    Par yassdu31 dans le forum Électronique
    Réponses: 4
    Dernier message: 18/04/2013, 14h46
  3. MicroC/OS (µC/OS) sur windows 7
    Par Damgot dans le forum Logiciel - Software - Open Source
    Réponses: 8
    Dernier message: 30/01/2011, 10h59
  4. microC
    Par rivaaa dans le forum Électronique
    Réponses: 2
    Dernier message: 27/04/2010, 11h26
  5. usart_read en microC
    Par rivaaa dans le forum Électronique
    Réponses: 1
    Dernier message: 25/04/2010, 00h40