Corrupción de datos de eeprom durante un corte de energía

Recientemente encontré un problema con la eeprom de un PIC16F877A que se usa para controlar la velocidad de un motor de CC. Se supone que la unidad debe funcionar a la última velocidad establecida incluso si falla la alimentación. Pero el problema es que a veces (no siempre) después de un corte de energía, la velocidad establecida (que se lee de eeprom) no es la misma que la última velocidad establecida. Por lo general, cada vez que ocurre este problema, el valor se cambia al valor predeterminado de eeprom 255 (pero no siempre, algunos valores aleatorios también). cuales pueden ser las posibles causas?.

La potencia cae demasiado antes de que finalice la escritura.
¿Su controlador tiene detección de caída de tensión? Eso puede ayudar a prevenir esta situación.
@IgnacioVazquez-Abrams ha pensado en la caída del poder. Pero hay un estabilizador de voltaje que corta el suministro si la red cae por debajo de 170v. También me gustaría saber cómo hacer que el sistema sea independiente de los picos en la red eléctrica, ya que el voltaje de suministro más alto en el sistema es de solo 12v.
@jippie Tiene BOD y ya está habilitado.
No desea cortar el suministro, desea realizar un cierre ordenado. Incluyendo no escribir en EEPROM después de cierto punto.

Respuestas (1)

Supongamos que tiene algún tipo de regulador lineal que alimenta su PIC. Ese regulador probablemente tenga mucho espacio libre (digamos que tiene una entrada de 12 V y una salida de 3,3 V). El regulador funcionará bien a pesar de que la entrada sea solo de 8V, por ejemplo.

Debe elegir este punto de corte y alimentarlo a un comparador que produce una señal lógica llamada Power Good (PG). Esta señal se activará mucho antes de que el regulador deje de regular y se active la DBO.

Siempre que PG esté ausente, no debería estar haciendo ninguna escritura de EEPROM.

También debe almacenar el punto de ajuste con algún valor de verificación. Un esquema simple es usar el complemento a 1 de la velocidad. Por ejemplo, para una velocidad de 0x88, el complemento a 1 es 0x77. Cª:

typedef struct {
  uint8_t speed;
  uint8_t speed_complement;
} SetpointSlot;

Si una ranura de punto de ajuste tiene un valor de verificación no válido, simplemente ignórelo.

Debería almacenar un SetpointSlots incluso múltiple, al menos dos. Si su EEPROM está paginada, las ranuras no deben cruzar páginas y deben distribuirse en dos páginas (o más páginas si no caben todas en dos páginas). Con 2 puntos de ajuste, tendrá cada uno en su propia página, por ejemplo.

Al arrancar:

  1. Iterar las ranuras. Usa el primero válido que encuentres (donde speed == ~speed_complement).
  2. Si no se encuentran ranuras válidas, utilice el valor predeterminado.

Al almacenar un nuevo valor, haría lo siguiente:

  1. Recupere la ranura de punto de ajuste utilizada actualmente.
  2. Borre la siguiente ranura del punto de ajuste (la siguiente en forma rotativa, alternando páginas).
  3. Escriba allí el nuevo punto de ajuste.
  4. Verifique los valores escritos. Si son incorrectos, póngalos a cero para asegurarse de que seguirán siendo incorrectos, seleccione la siguiente ranura de punto de referencia y vaya a 1.
  5. Ponga a cero (no borre) la ranura del punto de referencia actual, pero solo si no es la misma ranura donde se almacenó el nuevo valor. Ese podría ser el caso si tuviera dos ranuras y una de ellas estuviera en un área "mala" de eeprom.