Ce post est en parralelle avec la section ASM sur la gestion LCD 4x20 , mais en I2C
il est destiné à faire apparaitre de futurs problemes lié à la complexité progressive d'un programme...où des effets de bords commencent à se manifester.
debordement de page , de bank ...
.. en plus des erreurs humaines !Pour l'instant, en asm, l'ecriture en dur à des adresses bien precises et CONNUES donnent (
En C , on fait confiance au compilateur ... Suite au rajout de cette fonction dansun programme existant ( pourtant succint!) :
Code : Tout sélectionner
// convert int ADC value to a string with 3 decimal => 0.000 to 5.000
char * value_converter(unsigned int adc_value)
{
// declaration d'un pointeur sur char
char *p1; // with this additional pointer , OK sur terminal, OK sur LCD
char T[8]; // local variable table de characteres
// char *p1; // with this additional pointer ,OK sur terminal , BAD sur LCD
long vout ;
unsigned int va;
p1=&T[0]; // initialise la valeur du pointeur
vout= (long)adc_value * 5000 >>10;
value = (unsigned int) vout;
T[0] = va/1000+48; //Add 48 to get the ASCII character
T[1]='.' ;
T[2] = ( va/100)%10+48;
T[3] = (va/10)%10 +48;
T[4] = ( va %10) +48;
T[5]=0;
return p1; // OK .. but BAD with return &T[0]; or return T;
}
... usage
txt=&TEXTE[0];
*(txt)=0;
txt=value_converter(EA0); // return a pointer
strcat(txt," V");
UART1_Write_Text(txt); // OK on terminal
CRLF1();
LCD_putcmd(LCD_LINE4,1); // Bad on LCD if i don't use an additional char pointer inside value_converter(EA0);
LCD_puts(txt);
Delay_1sec();
et ensuite utiliser le pointeur resultant avec l'UART ou le LCD
je constate que le comportement differe suivant l'ordre d'initialisation du pointeur situé dans ma fonction!
j'ai ouvert un post la-dessus sur le forum MikroC.
En C traditionnel on pouvait gerer les Far_pointeurs ..(Turbo C2.00) et les manipuler facilement.
sous mikroC on ne sait pas trop comment c'est géré.
dans l'ASM généré par le compilo
Code : Tout sélectionner
_18F46k22_Big_LCD_4x20_I2C1_HW_2020_0722.c,694 :: char * value_converter(unsigned int adc_value)
char * value_converter(unsigned int adc_value)
{
char * p1; // with this additional pointer , OK sur LCD if declared first
char T[8]; // local variable
long vout ;
unsigned int value;
p1=&T[0];donne
;_18F46k22_Big_LCD_4x20_I2C1_HW_2020_0722.c,702 :: p1=&T[0];
MOVLW value_converter_T_L0+0
MOVWF value_converter_p1_L0+0
MOVLW hi_addr(value_converter_T_L0+0)
MOVWF value_converter_p1_L0+1
et le retour :
;_18F46k22_Big_LCD_4x20_I2C1_HW_2020_0722.c,711 :: return p1; // OK ;
MOVF value_converter_p1_L0+0, 0
MOVWF R0
MOVF value_converter_p1_L0+1, 0
MOVWF R1
;_18F46k22_Big_LCD_4x20_I2C1_HW_2020_0722.c,712 :: }
L_end_value_converter:
RETURN 0
déja , le Return 0
ne montre pas reellement que la fonction retourne un pointeur !
si ce n'est dans le contenu de R0 et R1 registre virtuels du compilateur


et ouais, il y a que ça de vrai, car on sait ce qu'on fait...
j'attends de voir des exemples un peu plus complexe en asm , pour voir si c'est toujours aussi facile ...