TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Medusa en 07 de Julio de 2021, 22:19:21
-
Hola a todos, estoy usando el pic18f4620 y el compilador ccs V4.074, tengo una variable que lo leo desde un array cuyo valor es -77, cuando uso esta variable a hacer una operación de multiplicación y suma obtengo como resultado 50, pero cuando hago la misma operación pero en lugar de usar la variable uso una constante de valor -77 el resultado que obtengo es 18, por que?, cual es mi error?
Aquí esta mi código:
#include <18F4620.h>
#fuses HS,WDT32768,PROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar
int8 myCSQValue;
signed int8 myRSSIValue8;
signed int16 myRSSIValue16;
int16 myRSSIValuex;
char Buffer_ValRSSI[5];
signed int8 valueRSSI[]={-113,-110,-109,-107,-105,-103,-101,-99,-97,-95,-93,-91,-89,-87,-85,-83,-81,-79,-77,-75,-73,-71,-69,-67,-65,-63,-61,-59,-57,-55,-53};
void main(){
myCSQValue = 18;
myRSSIValue8 = valueRSSI[myCSQValue];
myRSSIValue16 = ((4*(myRSSIValue8)) + 452)*0.125; // Using a variable
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);
myRSSIValue16 = ((4*(-77)) + 452)*0.125; // Using a constant
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);
while (TRUE);
}
-
Hola a todos, estoy usando el pic18f4620 y el compilador ccs V4.074, tengo una variable que lo leo desde un array cuyo valor es -77, cuando uso esta variable a hacer una operación de multiplicación y suma obtengo como resultado 50, pero cuando hago la misma operación pero en lugar de usar la variable uso una constante de valor -77 el resultado que obtengo es 18, por que?, cual es mi error?
....
Overflow.
Cuando hacés (4*(myRSSIValue8)) con -77 el resultado correcto es -308, pero como el valor temporal es de 8 bits, se pierde el 9no bit y te queda -52 , luego (-52+452)*.125 = 50
En cambio cuando usas una constante, el compilador evalúa la expresión y asigna directamente 18 a myRSSIValue8
Lo que tenés que hacer es ayudar al compilador escribiendo una expresión equivalente que evite overflow, no confiar en compilaciones milagrosas.
#include <18F4620.h>
#fuses HS,WDT32768,PROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar
int8 myCSQValue;
signed int8 myRSSIValue8;
signed int16 myRSSIValue16;
int16 myRSSIValuex;
char Buffer_ValRSSI[5];
signed char valueRSSI[]={-113,-110,-109,-107,-105,-103,-101,-99,-97,-95,-93,-91,-89,-87,-85,-83,-81,-79,-77,-75,-73,-71,-69,-67,-65,-63,-61,-59,-57,-55,-53};
void main(){
myCSQValue = 18;
myRSSIValue8 = valueRSSI[myCSQValue];
myRSSIValue16 = ((4*(myRSSIValue8)) + 452)*0.125; // Using a variable
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);
myRSSIValue16 = ((4*(-77)) + 452)*0.125; // Using a constant
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);
//***************************************************************************
myRSSIValue16 = (myRSSIValue8 + 113)/2 ; // Using common sense
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);
//***************************************************************************
while (TRUE);
}
Otra opción es forzar a que un resultado temporal de determinado tipo.
Como ser escribiendo: myRSSIValue16 = ((4L*(myRSSIValue8)) + 452)*0.125;
Pero eso es 3 veces mas lento que: myRSSIValue16 = (myRSSIValue8 + 113)/2 ;
-
Eduardo2, Gracias, excelente explicación ((:-))