La verdad es que este compilador de CCS me tiene un poquito harto.
Desde luego no es un compilador ANSI C.
Ahora tengo que acabar ya lo que estoy con él, pero creo que probaré el de Hitech a ver si es un compilador más estándar.
Ahora parece que me funciona con punteros de 8 bits, aunque estoy con las espaldas abiertas, pues en cuanto toque un poco el código seguro que vuelve a las andadas.
El código lo único que hace es recorrerse un buffer en el que están almacenados los comandos para ir interpretándolos.
Cuando tiene que leer un número en hexadecimal, llama a unas funciones que hacen la converisón (Hex2Int8 y Hex2Int16 según sea un entero de 8 bits o de 16 el que se espera leer).
Las funciones para la conversión son las siguientes:
//Convertir un caracter hexadecimal (0-9 y A-F) en su correspondiente
//valor numérico, de 0 15 (un nibble de 4 bits almacenado en la posición más baja
//del byte devuelto.
//Si el caracter pasado no es hexadecimal la función devuelve 0xFF (255).
//Los caracteres han de estar en mayúsculas.
int8 Hex2Nibble(char c)
{
if( (c >= 'A') && (c<='F') ) {
return 10+c- 'A';
} else if ( (c >= '0') && (c <= '9') ) {
return c- '0';
}
return 0xFF;
}
int8 Hex2Int8(byte *c,int &err)
{
int8 n, valor;
n= Hex2Nibble(*c);
err= (n==0xFF);
if( err ) return 0xFF;
valor = n<<4;
c++;
n= Hex2Nibble(*c);
err= (n==0xFF);
if( err ) return 0xFF;
return valor|n;
}
int16 Hex2Int16(byte *c,int &err)
{
int8 n;
int16 valor;
n= Hex2Nibble(*c);
err= (n==0xFF);
if( err ) return 0xFFFF;
valor = n<<12;
c++;
n= Hex2Nibble(*c);
err= (n==0xFF);
if( err ) return 0xFFFF;
valor |= n<<8;
c++;
n= Hex2Nibble(*c);
err= (n==0xFF);
if( err ) return 0xFFFF;
valor |= n<<4;
c++;
n= Hex2Nibble(*c);
err= (n==0xFF);
if( err ) return 0xFFFF;
return valor|n;
}
En la subrutina de procesar los comandos, tengo puesto un código como el siguiente:
Variable global:
char comando[16];
Subrutina:
................
char * pos;
pos= comando;
//Leer el ID de la estación, si se produce un error al leerlo, ignorar el comando recibido.
id= Hex2Int8(pos,err);
.............
Al pasar pos a la función, el valor de pos cambia. Ya no parece ser un número de 16 bits, si no de 8.
Cuando incremento el puntero, resulta que en vez de pasar al caracter siguiente se va a otra parte de la memoria fuera de la cadena de comandos.
En alguna de las pruebas pos valía 0x002A antes de llamar a la subrutina.
Nada más entrar, c tomaba el valor 0x2A, el *c contenía el caracter adecuado, con lo que la primera parte del número se leía bien.
Al incrementar el puntero, pasaba a tomar el valor 0x01 en vez de 0x2B y por supuesto *c ya no tenía el valor adecuado, si no un caracter cualquiera.
Lo raro rarísimo es que unas veces me pasaba y otras no.
He probado con punteros de 16 bits (#device *=16) pero entonces parece que siempre funciona mal.
Con punteros de 8 bits, unas veces va bien, pero cuando añado código por otros lados (que no tienen nada que ver con estas subrutinas) a veces deja de funcionar.