Estoy ejecutando un Microchip dsPIC30F6012a. Tengo este chip en varios PCB, todos ejecutando el mismo software, y observo el mismo problema en todos ellos. Esto implica un problema sistémico, no un problema de producción excepcional. El problema también es reproducible, lo que implica que debería poder matarlo si sé dónde buscar. Pero todavía tengo dificultades sorprendentes para depurar la aplicación.
La placa en prueba acepta 24V, que se reduce a 5V a través de un V7805. El chip se ejecuta en su oscilador interno, con un PLL 16x, dando una velocidad de operación de ~ 29.5 MIPS. El código relevante en este tablero es esencialmente muy simple: despierte, lea datos de EEPROM, luego ingrese un bucle infinito. Interrumpa cada milisegundo, observe algunos datos ambientales y escriba un valor actualizado en la EEPROM. Hay otras cosas en marcha, pero el problema sigue ocurriendo incluso si el código no relacionado está comentado, por lo que puedo estar razonablemente seguro de que no es relevante para el problema en cuestión.
En uso general, el 95% del tiempo la placa se despierta con el valor correcto en la memoria y continúa con su negocio. El otro 5% del tiempo, sin embargo, se despierta con un valor incorrecto. Específicamente, se despierta con una versión bit-volteada de los datos que se supone que tiene. Es un largo de cuatro bytes sin firmar que estoy viendo, y tanto la palabra superior como la inferior del texto largo se pueden voltear. Por ejemplo, 10 se convierte en 2 ^ 16-10, que luego se convierte en 2 ^ 32-10. Puedo reproducir el fallo al ciclar manualmente el poder varias docenas de veces, pero eso no es muy consistente, y mi interruptor se desgasta.
Para reproducir el problema de una manera controlada, construí una segunda placa que impulsa el suministro de 24 V a la placa bajo prueba. (Otro dsPIC que maneja un optoacoplador Darlington). La placa del comprobador apaga los 24V durante 1.5 segundos (el tiempo suficiente para que el riel de 5V caiga a 0 y permanezca allí por un segundo), luego enciende los 24V durante un tiempo configurable . Con un tiempo de funcionamiento de aproximadamente 520 mS, puedo reproducir esta falla de EEPROM dentro de cinco ciclos de energía, cada vez.
El riel de 5V se está comportando razonablemente. Se establece en 5V dentro de 1 mS de encendido, con quizás .4V de rebasamiento, asumiendo que puedo confiar en mi alcance. Al apagar, decae exponencialmente a 0V, alcanzando 1V dentro de 50 mS. No tengo advertencias de compilación que parezcan relevantes, solo variables no utilizadas y nuevas líneas faltantes al final de los archivos.
He intentado varias cosas:
- Habilitar / deshabilitar MCLR
- Habilitar / deshabilitar el WDT
- Habilitar / deshabilitar la protección de código
- Habilitar / deshabilitar / cambiar el voltaje de detección de caída de tensión
- Habilitar / deshabilitar / cambiar el temporizador de encendido
- Diferentes configuraciones de PLL en el oscilador interno principal
- Conectar / desconectar mi programador PICkit 3
- Agregar 470 uF de capacitancia al riel de 5V
- Agregar / eliminar .1 uF a través del pullup de 4.7k en mi pin MCLR
- Deshabilitar todas las interrupciones en el código y no dejar más que actualizaciones de EEPROM en el ciclo principal
- Agregar una demora de 1.5 segundos a mi rutina de inicio antes de comenzar a leer EEPROM
También escribí un código de prueba separado que no hace nada más que escribir valores continuamente en la EEPROM y luego leerlos nuevamente, asegurándome de que el valor no haya cambiado. Decenas de miles de iteraciones no dieron errores. Todo lo que puedo concluir es que algo va mal con la lectura o escritura de EEPROM, específicamente en el encendido / apagado.
He estado usando las mismas bibliotecas EEPROM desde 2007. He visto fallos ocasionales, pero nada reproducible. El código relevante se puede encontrar aquí:
enlace
enlace
enlace
enlace
He visto errores de EEPROM antes en otras aplicaciones, pero siempre como fallos puntuales, nada tan reproducible o consistente.
¿Alguien tiene alguna idea de lo que está pasando? Me estoy quedando sin cosas para probar.