El cambio de reloj se bloquea al volver a la fuente original

2

Actualmente estoy trabajando en un proyecto en el que el reloj necesita cambiar entre el Oscilador primario con PLL (POSCPLL) al FRC y luego volver.

He inicializado el reloj como PRIPLL utilizando los bits de configuración:

#pragma config FNOSC = PRIPLL
#pragma config POSCMOD = HS
#pragma config FPLLMUL = MUL_20
#pragma config FPLLIDIV = DIV_2
#pragma config FPLLODIV = DIV_1
#pragma config FPBDIV = DIV_1
#pragma config FCKSM = CSECME

que establece el OSCCON en 0x01453360 y da una señal de reloj de 80MHz. Luego uso esta función para cambiar al FRC:

INTDisableInterrupts();
//Execute the System unlock sequence
SYSKEY = 0xAA996655;
SYSKEY = 0x556699AA;

OSCCONbits.NOSC = 000;
OSCConfig(OSC_FRC, 0, 0, OSC_FRC_POST_1);
mOSCSetPBDIV(OSC_PB_DIV_1);
//Initiate the clock switch
OSCCONbits.OSWEN = 1;
//Lock SYSKEY
SYSKEY = 0x33333333;
int k = 0;
//Wait until OSWEN = 0 and switch is complete
while (OSCCONbits.OSWEN == 1){
    k++;
}
//Re-enable interrupts
INTEnableInterrupts();
SYSTEMConfig(GetStandbySystemClock(), SYS_CFG_ALL);

Para volver al POSC PLL, uso la misma estructura pero cambia el valor de NOSC a 011; y actualiza el OSCConfig a

OSCConfig(OSC_POSC_PLL, OSC_PLL_MULT_20, OSC_PLL_POST_1, 0); 

Que coincide con la secuencia en los bits de configuración pragma. Sin embargo, cuando lo ejecuto en el PIC32MX, el depurador en un PICKIT3 no puede superar la función con estos bits de configuración, sin embargo, permitirá que se establezca a la mitad de la velocidad (OSC_PLL_POST_2).

Sin embargo, si el depurador está en pausa, se puede ver que OSCCON es el mismo, pero cuando se reanuda, el software se reinicia.

Si alguien me pudiera decir si me he perdido un bit de configuración para poder volver al reloj inicial o si hay una mejor manera de hacerlo, ¡estaría extremadamente agradecido!

Información adicional: PIC32MX775F256L, Tablero personalizado, Cristal de 8MHz (FOXSDLF / 080-20), El cristal se conecta al OSC1 y OSC2 (pin 63 y pin 64), condensadores de carga 22pF

Gracias de antemano

EDIT Ahora también he intentado configurar la nueva fuente de reloj sin usar la función OSCConfig y, en su lugar, usar los valores fijos.

OSCCONbits.NOSC = 0b011;
OSCCONbits.PLLODIV = 0b000;
OSCCONbits.PLLMULT = 0b101;
OSCCONbits.PBDIV = 0b00;

Cuando PLLODIV es 0b000, sucede lo mismo. Sin embargo, cuando se establece en 0b001, funciona y el sistema es de media velocidad, ya que está dividido por dos

EDIT 2

Ahora he intentado cambiar entre los relojes sin usar los bits de configuración #pragma He eliminado

#pragma config FPLLMUL = MUL_20
#pragma config FPLLODIV = DIV_1
#pragma config FNOSC = PRIPLL
#pragma config FPBDIV = DIV_1

Utilizo las mismas funciones para configurar el reloj en primer lugar y obtener el resultado deseado sin problemas. Entonces cambio al reloj FRC, de nuevo sin problemas. Solo cuando intento volver al reloj original, encuentro un problema. Tampoco ayuda si primero cambio al mismo reloj con diferentes parámetros antes de volver a los correctos a través del FRC. Pero funcionará si primero cambio el reloj con diferentes parámetros, luego el correcto a través del FRC en el inicio.

Ahora tengo el código aislado para evitar que cualquier otro código afecte el cambio del reloj y aún no haya diferencia.

    
pregunta Matt Winstanley

1 respuesta

2

Si pretendías establecer esos bits como binarios, necesitas cambiar esto:

OSCCONbits.NOSC = 000;

a esto:

OSCCONbits.NOSC = 0b000;

También donde hayas establecido NOSC back, debería configurarse en 0b011 no solo en 011 .

Un prefijo de "0" en realidad hace que el valor sea octal en el compilador XC32 (como lo señala @Lundin en los comentarios), que es decimal 9, que == 0b1001, por lo que este es ciertamente un problema que necesita solución.

También, en la PIC32 Peripheral Library Guide dice:

"En general, cuando se cambia a una frecuencia de reloj de CPU más alta, el divisor de Bus Periférico debe configurarse en el nuevo valor más bajo antes de cambiar la frecuencia de la CPU"

Por lo tanto, cuando suba / baje la velocidad, debe usar el orden apropiado de las siguientes llamadas:

OSCConfig(OSC_FRC, 0, 0, OSC_FRC_POST_1);
mOSCSetPBDIV(OSC_PB_DIV_1);
    
respondido por el Roger Rowland

Lea otras preguntas en las etiquetas