Estoy trabajando con PIC24EP256GP204. La frecuencia de la CPU es de 64 MHz. Estoy generando dos pulsos PWM para el sensor CCD TCD1304AP y dos pulsos PWM para WM8253 ADC AFE.
Mi problema radica en los pulsos PWM para ADC, ya que tengo que usar ISR para recuperar datos.
Necesito sincronizar Vsmp (determina el punto de muestreo y la frecuencia) y el reloj maestro de ADC para que pueda leer la salida de 16 bits de ADC (que está disponible en formato multiplexado de 4 bits). Estoy generando una onda cuadrada de frecuencia de 3 MHz para el reloj maestro de ADC y una onda cuadrada de 500 KHz para Vsmp. He verificado las formas de onda con un osciloscopio digital.
Pero para sincronizar y leer la salida de ADC AFE, necesito ejecutar algún código en ISR de Vsmp y reloj maestro de ADC. Si acabo de borrar las banderas de interrupción en los ISR respectivos, entonces todo funciona perfectamente. Sin embargo, incluso unas pocas líneas de código en lenguaje de programación C hacen que el PIC24EP se cuelgue. No pude publicar todo mi código base ya que es enorme. He publicado el código ISRs. Por favor, eche un vistazo:
volatile bool vsmp_failing_edge = false;
// VSMP ISR
void __attribute__((__interrupt__, no_auto_psv)) _OC3Interrupt(void)
{
vsmp_failing_edge = true;
IFS1bits.OC3IF = 0;
}
// ADC ISR
void __attribute__((__interrupt__, no_auto_psv)) _OC4Interrupt(void)
{
/*
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop(); Nop();
*/
if (vsmp_failing_edge) {
// oc_disable(OC_CHANNEL_4);
vsmp_failing_edge = false;
}
IFS1bits.OC4IF = 0;
}
El ISR _OC4 se asigna al reloj maestro de ADC que se ejecuta a 3 MHz y el ISR _OC3 se asigna a Vsmp que se ejecuta a 500 KHz. La salida de ADC está disponible en algunos otros pines en formato multiplexado de 4 bits.
ISR _OC3 se ejecuta en el borde descendente del pin Vsmp. En la interrupción, estoy poniendo una bandera. Después de 16.5 ciclos de reloj maestro, tengo que leer 4 pines externos en el flanco descendente de los pulsos del reloj maestro. Tengo que leer cuatro lados consecutivos del reloj maestro para obtener datos completos.
Comente mi enfoque o sugiera mejores enfoques para el sensor y el ADC.
También pensé en usar la interrupción de cambio de pin en el pin de salida de pulso del reloj maestro y alguna interrupción del temporizador para recuperar los datos. Sin embargo, no he implementado ese enfoque porque no estoy seguro de si PIC24EP puede manejar la generación de formas de onda y sincronizarse a la frecuencia que yo quiera.
EDITAR:
Si observa el código de _O4 ISR, puede encontrar 60 instrucciones Nop () junto con la línea IFS1bits.OC4IF = 0;
que hará que se cuelgue el PIC. He agregado Nop()
de instrucciones para verificar el número de ciclos de instrucción necesarios para hacer que se cuelgue.
Las instrucciones Nop()
están comentadas. Sin ellos, solo la condición if
y la línea IFS1bits.OC4IF = 0;
harán que el PIC se cuelgue. Por lo tanto, puede concluir que las instrucciones Nop () son equivalentes a solo if
parte del ISR en términos de tiempo de ejecución.