Interesante lo de la #zeroram ¡Habra que investigar su funcionamiento!
Con respecto a la EEPROM voy a implementar un sistema dentro de la rutina de WriteByte con un bucle que escrito en pseudocódigo sería así:
recibo el byte a escribir;
inicializo un contador;
_escribir:
incremento el contador;
si el contador es mayor que numero_maximo_de_reintentos goto _salir_error;
escribo el byte;
leo el byte;
si no es igual al recibido goto _escribir;
goto _salir_ok
_salir_error:
devuelvo -1;
_salir_ok;
devuelvo 0;
Con esto me aseguro que por lo menos he escrito correctamente y que el error no está en el origen, que he escrito mal, sino que el valor ha cambiado a posteriori.
Otra técnica que esta sí que ya utilizo:
El escribir la EEPROM requiere un tiempo que en relación a la velocidad de funcionamiento del PIC es un tiempo realmente largo, del orden de algunos milisegundos, tiene que direccionar, poner el dato, y darle a la EEPROM un pico de tensión para fijarlo y esperar a que se estabilice. Un error muy común es no darle tiempo al PIC a que realice una buena escritura, un valor muy normal que yo utilizaba antes era el de 5 ms colocando un delay_ms(5) tras escribir el byte y siempre me quedaba la duda razonable de si era demasiado corto, o de si estaba desperdiciando tiempo esperando mas de la cuenta.
Ahora he cambiado de estrategia al saber que hay una interrupción que se dispara cuando se ha completado un ciclo correcto de escritura, #int_eeprom. Esta interrupción es absoluta, independiente del tiempo que necesite el PIC para escribir correctamente, se dispara cuando ha terminado y punto. Así que lo que hago es:
Habilito la interrupción int_eeprom
Pongo un flag a 1;
Escribo el byte en la EEPROM;
Espero a que el flag vuelva a 0;
Deshabilito la interrupción int_eeprom
Regreso de la rutina de escritura de un byte.
En la interrupción int_eeprom pongo el flag a 0;
Con esto me aseguro de que el PIC tiene el tiempo suficiente y necesario para escribir su byte, ni más ni menos tiempo del que realmente necesite.
La implementacion de esto en CCS C es:
#int_eeprom
/** \brief Interrupción por : Fin escritura EEPROM interna.
*
*/
void interrupt_service_rutine_eeprom(void) {
flag_Writing_INTERNAL_EEPROM=0;
}
...
void writeByteINTEEPROM(int8 memAddress, int8 data){
flag_Writing_INTERNAL_EEPROM=1;
enable_interrupts(int_eeprom);
write_eeprom (memAddress, data);
while(flag_Writing_INTERNAL_EEPROM==1){/*Wait for write finish*/}
disable_interrupts(int_eeprom);
}
A este código es al que le voy a poner lo del principio del post para asegurarme que he escrito correctamente.