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!
-----
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!
Quel problème ?
Tu connais la fonction du bit IRP ?
L'électronique c'est comme le violon. Soit on joue juste, soit on joue tzigane . . .
malheureusement,je ne la connait pas vraiment.
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.
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.
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); }
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é.
Usage: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; }
A tester.Code:Lcd_Out(1,1,Copy_ConstToRam(msg,txt1));
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.
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
En apportant la modification décrite en #8 on améliore la situation en RAM de 14%: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); }
message_compilateur.JPG
Résultat de compilation: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); }
message_compilateur2.JPG