В настоящее время я работаю над проектом, в котором часы должны переключаться между первичным генератором с PLL (POSCPLL) на FRC и обратно.
Я инициализировал часы как PRIPLL, используя биты конфигурации:
#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
который устанавливает OSCCON на 0x01453360 и дает тактовый сигнал 80 МГц. Затем я использую эту функцию для переключения на 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);
Чтобы переключиться обратно на POSC PLL, я использую ту же структуру, но изменяю значение NOSC на 011; и обновите OSCConfig до
OSCConfig(OSC_POSC_PLL, OSC_PLL_MULT_20, OSC_PLL_POST_1, 0);
Что соответствует последовательности в битах конфигурации прагмы. Однако, когда я запускаю его на PIC32MX, отладчик на PICKIT3 не может обойти функцию с этими битами настройки, однако он позволяет установить ее на половинной скорости (OSC_PLL_POST_2).
Однако, если отладчик приостановлен, можно увидеть, что OSCCON остается прежним, но когда он возобновляется, программное обеспечение перезапускается.
Если бы кто-нибудь мог сказать мне, пропустил ли я бит настройки, позволяющий вернуться к исходным часам, или если есть лучший способ сделать это, я был бы очень благодарен!
Дополнительная информация: PIC32MX775F256L, специальная плата, кварцевый резонатор 8 МГц (FOXSDLF/080-20), кварцевый резонатор подключается к OSC1 и OSC2 (контакты 63 и 64), нагрузочные конденсаторы 22 пФ.
заранее спасибо
РЕДАКТИРОВАТЬ Теперь я также попытался установить новый источник часов без использования функции OSCConfig и вместо этого использовать жесткие значения.
OSCCONbits.NOSC = 0b011;
OSCCONbits.PLLODIV = 0b000;
OSCCONbits.PLLMULT = 0b101;
OSCCONbits.PBDIV = 0b00;
Когда PLLODIV равен 0b000, происходит то же самое, однако, когда он установлен на 0b001, он работает, и система работает на половинной скорости, так как она делится на два.
РЕДАКТИРОВАТЬ 2
Теперь я попытался переключаться между часами, не используя биты конфигурации #pragma, которые я удалил.
#pragma config FPLLMUL = MUL_20
#pragma config FPLLODIV = DIV_1
#pragma config FNOSC = PRIPLL
#pragma config FPBDIV = DIV_1
Я использую те же функции для настройки часов в первую очередь и без проблем получаю желаемый результат. Затем я переключаюсь на часы FRC, снова без проблем. Только когда я пытаюсь вернуться к исходным часам, я сталкиваюсь с проблемой. Также не помогает, если я сначала переключаюсь на одни и те же часы с другими параметрами, прежде чем снова переключиться на правильные через FRC. Но это будет работать, если я сначала переключусь на часы с другими параметрами, а затем переключусь на правильные через FRC при запуске.
Теперь у меня есть код, изолированный, чтобы избежать любого другого кода, влияющего на переключение часов, и по-прежнему никакой разницы.
Если вы хотели установить эти биты как двоичные, вам нужно изменить это:
OSCCONbits.NOSC = 000;
к этому:
OSCCONbits.NOSC = 0b000;
Кроме того, где бы вы ни отступили NOSC
, он должен быть установлен 0b011
не только 011
.
Префикс «0» фактически делает восьмеричное значение в компиляторе XC32 (как указано @Lundin в комментариях), что равно десятичному числу 9, что == 0b1001, так что это, безусловно, одна из проблем, требующая исправления.
Кроме того, в Руководстве по библиотеке периферийных устройств PIC32 говорится:
«В общем случае при переключении на более высокую тактовую частоту ЦП делитель периферийной шины должен быть установлен на новое более низкое значение перед изменением частоты ЦП»
Таким образом, при увеличении/уменьшении скорости вы должны использовать соответствующий порядок следующих вызовов:
OSCConfig(OSC_FRC, 0, 0, OSC_FRC_POST_1);
mOSCSetPBDIV(OSC_PB_DIV_1);
011
является восьмеричным (декабрь 9), поэтому в этом ответе есть несколько ошибок.
Лундин
10
, шестнадцатеричная запись:0xA
, восьмеричная запись:012
. В C нет двоичной записи, но распространено нестандартное расширение0b1010
.