Переключение часов зависает при переключении обратно на исходный источник

В настоящее время я работаю над проектом, в котором часы должны переключаться между первичным генератором с 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 при запуске.

Теперь у меня есть код, изолированный, чтобы избежать любого другого кода, влияющего на переключение часов, и по-прежнему никакой разницы.

Для десятичного числа 10 десятичная запись: 10, шестнадцатеричная запись: 0xA, восьмеричная запись: 012. В C нет двоичной записи, но распространено нестандартное расширение 0b1010.

Ответы (1)

Если вы хотели установить эти биты как двоичные, вам нужно изменить это:

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);
Спасибо, я добавил это, но никаких изменений в результате для моей проблемы. Похоже, что при изменении PLLODIV на 0b001 он не будет зависать, но тогда явно дает половину скорости. Любые идеи относительно того, почему установка PLLODIV на 0b000 может привести к зависанию?
@MattWinstanley Я не вижу очевидной проблемы с этим в таблице данных. Дело не в том, что PICKit вызывает сброс или что-то глупое?
Теперь я попробовал это с программатором ICD3 и снова, когда он не находится в режиме отладки, и снова происходит то же самое. На этот раз он не сбрасывается, но MPLAB не позволяет возобновить работу программы. Вероятно, это что-то смехотворно глупое, но просто найти хоть что-то, что нужно изменить, чтобы заставить его работать, становится все труднее и труднее!
@MattWinstanley Смотрите обновленный ответ, он может быть актуальным?
Спасибо, я пытался переместить его во все возможные положения, но безуспешно. я думаю, что мой следующий шаг — попытаться запустить осциллятор, используя аналогичный процесс в начале кода, и избегать использования конфигурации #pragma, чтобы увидеть, имеет ли это какое-то значение. Просто на подходе «попробуй что-нибудь и посмотри, что изменится» на данный момент
011является восьмеричным (декабрь 9), поэтому в этом ответе есть несколько ошибок.
@Lundin Спасибо, хорошо замечено - я обновил свой ответ с учетом вашего комментария.
@Lundin Итак, если в таблице данных указано установить для бита NOSC значение 011, какое правильное значение для его установки? должно быть только 3? В техническом описании указано следующее: бит 10-8 NOSC<2:0>: биты выбора нового генератора 111 = внутренний быстрый RC-генератор (FRC), разделенный на биты OSCCON<FRCDIV> 110 = внутренний быстрый RC-генератор (FRC), разделенный на 16 101 = Внутренний маломощный RC-генератор (LPRC) 100 = вторичный генератор (SOSC) 011 = первичный генератор с модулем PLL (XTPLL, HSPLL или ECPLL) — извините за ужасное расстояние
@MattWinstanley В таблице данных явно используется двоичная запись.
@RogerRowland Я только что отредактировал вопрос, добавив еще несколько тестов, если у вас есть идеи?
@Lundin Я обновил значения, чтобы читать 0b11, и попробовал это с 3, и это не имеет никакого значения. Компилятор, похоже, распознает команды, так как он может сначала выполнить переключение (см. редактирование 2), но не может затем вернуться к часам с параметрами, которые я хотел бы использовать.
@RogerRowland Спасибо за вашу помощь. Опубликовано там сейчас