Estoy desarrollando un PIC16F1936 utilizando el IDL MPLAB X con el compilador XC8. Me han asignado este proyecto en el que necesito "actualizar" el software de una PCB para que pueda interactuar con una herramienta externa a través de un enlace RS232.
Tengo el enlace en funcionamiento y también he comprobado que la fecha de transmisión es correcta. El problema que tengo es con una función específica que calibra los puntos de ajuste para la PCB. No puedo decir mucho sobre cuál es la función exacta de la PCB, así que lo siento por no publicar todo. Además, he heredado mucho de este código en este proyecto, como el código que estoy a punto de mostrarle.
Entonces, la función de calibración funciona así: se llama una vez que la herramienta envía el comando relevante a la PCB. Después de esto (según el comando enviado), la función leerá el valor del valor sumado de 40 valores del ADC y lo guardará en la EEPROM. ¡Aquí es donde realmente se desordena! La calibración funciona perfectamente bien cuando tengo que poner a cero el PCB, el problema surge cuando tengo que configurar MAX. Oh! Y el código es idéntico, aparte de la dirección EEPROM ...
Aquí está el código para la calibración:
if (zero == 1)
{
WR = 1; // Set EEPROM_WRITE flag
EEPROM_WRITE(0x05,(AN1_sum >> 0x08)); // load MSbyte of AN1_sum into NV memory location 1
EEPROM_WRITE(0x06,(AN1_sum & 0xff)); // load LSbyte of AN1_sum into NV memory location 2
EEPROM_WRITE(0x07,(AN4_sum >> 0x08)); // load MSbyte of AN4_sum into NV memory location 3
EEPROM_WRITE(0x08,(AN4_sum & 0xff)); // load LSbyte of AN4_sum into NV memory location 4
zero1 = AN1_sum; // update volatile memory for zero1
zero4 = AN4_sum; // update volatile memory for zero4
WR = 1; //Set EEPROM_WRITE flag
EEPROM_WRITE(0x09, 2); //Write 2 to the EEPORM
while(WR){ //Loop till WR flag is reset by EEPROM CONTROLLER
MAL = 1; //Light MAL until WR is reset
}
for(KILLTIME = 0; KILLTIME <= 200000; KILLTIME++);
RESET();
for(KILLTIME = 0; KILLTIME <= 200000; KILLTIME++);
}
else if (MAX == 1)
{
WR = 1; //Set EEPROM_WRITE flag
EEPROM_WRITE(0x01,(AN1_sum >> 0x08)); // load MSbyte of AN1_sum into NV memory location 5
EEPROM_WRITE(0x02,(AN1_sum & 0xff)); // load LSbyte of AN1_sum into NV memory location 6
WR = 1; //Set EEPROM_WRITE flag
EEPROM_WRITE(0x03,(AN4_sum >> 0x08)); // load MSbyte of AN4_sum into NV memory location 7
EEPROM_WRITE(0x04,(AN4_sum & 0xff)); // load LSbyte of AN4_sum into NV memory location 8
MAX1 = AN1_sum; // update volatile memory for MAX1
MAX4 = AN4_sum; // update volatile memory for MAX4
WR = 1; //Set EEPROM_WRITE flag
EEPROM_WRITE(0x9, 3); //Write 3 to the EEPROM
while(WR){ //Loop till WR flag is reset by EEPROM CONTROLLER
MAL = 1; //Light MAL until WR is reset
}
for(KILLTIME = 0; KILLTIME <= 200000; KILLTIME++);
RESET();
for(KILLTIME = 0; KILLTIME <= 200000; KILLTIME++);
}
Después del reinicio, la PCB se reinicia y pasa por este proceso de inicialización:
MAX1 = EEPROM_READ(0x01);
MAX1 = (MAX1 << 8) + EEPROM_READ(0x02);
MAX4 = EEPROM_READ(0x03);
MAX4 = (MAX4 << 8) + EEPROM_READ(0x04);
zero1 = EEPROM_READ(0x05);
zero1 = (zero1 << 8) + EEPROM_READ(0x06);
zero4 = EEPROM_READ(0x07);
zero4 = (zero4 << 8) + EEPROM_READ(0x08);
Suficientemente simple ¿verdad? Este es solo el tiempo en el código donde se configuran MAX y cero.
No tengo idea de por qué esto no funciona. MAX debería ser el valor que AN1 y AN4 tengan en el momento de la ejecución. He cambiado las direcciones de la EEPROM y he cambiado el nombre de las variables para asegurarme de que MAX y ZERO no se sobrescriban en ninguna otra parte del código. Sin resultado. MAX solo quiere ser el valor correcto cuando digo MAX1 = x y MAX 4 = y. No puede ser algo con los valores de AN1 y AN4, ya que funcionan bien para TARE sin importar cuál sea su valor.
¿Alguna idea?
Solo para agregar, he probado las siguientes soluciones:
-
Cambié las direcciones EEPROM de manera que MAX las escriba en las direcciones. Quiero decir que MAX ahora se escribe en 0x05-0x08 y ZERO se escribe en 0x01-0x05. Todavía tengo el mismo problema. El valor del sensor se escribe correctamente en CERO pero no en MAX.
-
He jugado un poco con la bandera WR colocando más y eliminándolos por completo. NO HAY CAMBIO.
-
He intentado almacenar los valores de AN1_sum y AN4_sum en una variable temporal tan pronto como se inicia la función de calibración y, en su lugar, he utilizado esas variables.
-
He intentado revertir los roles de ZERO y MAX. Con esto quiero decir que establezco CERO en el punto de ajuste máximo y MAX en el mínimo. Encontré que CERO establece con precisión y el valor que tiene puede afectar el valor de MAX. Por ejemplo, primero establecí la aplicación 45 en ambos canales y luego configuré el MAX. Después de la calibración, MAX tenía un valor de 26. Luego apliqué 198 a ambos canales y configuré CERO. ¡CERO mantuvo un valor final de 198, mientras que MAX cambió a 48!
Hace tiempo que sé que MAX es el culpable, pero no sé por qué o cómo está sucediendo esto. He revisado el resto del código y he comprobado si MAX está siendo afectado de alguna manera, pero no lo está.