Микроконтроллер переведён на работу на 170 МГц

This commit is contained in:
2026-04-09 14:43:38 +03:00
parent 941d3c44bb
commit b62fd39a67
3 changed files with 59 additions and 1 deletions

View File

@@ -282,7 +282,63 @@ void SystemCoreClockUpdate(void)
* @}
*/
void SystemClock_Config() // STM32G431CBT6
{
// 1. Включить тактирование для интерфейса управления питанием (PWR)
// Это действие необходимо совершать одним из первых.
RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
// 2. Установить задержку Flash ПЕРЕД любым увеличением частоты.
// При переключении на PLL 170 МГц и Vcore Range 1 требуется 4 цикла ожидания.
// Безопаснее установить это значение заранее, пока система работает на низкой частоте HSI.
MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_4WS);
// 3. Включить prefetch buffer, instruction cache и data cache для максимальной производительности.
FLASH->ACR |= FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN;
// 4. Включить и дождаться готовности HSI (16 МГц).
// Это важно, даже если он уже включен по умолчанию, для явного контроля.
RCC->CR |= RCC_CR_HSION;
while(!(RCC->CR & RCC_CR_HSIRDY));
// 5. Настроить масштабирование напряжения на Range 1 (High-performance).
// Это необходимо для работы на высоких частотах.
// ВАЖНО: Делать это ДО включения PLL и переключения на него.
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_CR1_VOS_0);
// Ожидаем готовности регулятора напряжения (ухода флага VOSF).
while ((PWR->SR2 & PWR_SR2_VOSF) != 0);
// 6. Включить режим Range 1 Boost для частот > 150 МГц.
// Согласно документации (Reference Manual), это нужно делать, когда система
// тактируется от HSI/HSE, ДО включения PLL.
PWR->CR5 |= PWR_CR5_R1MODE;
// 7. Убедиться, что PLL выключен, перед его настройкой.
RCC->CR &= ~RCC_CR_PLLON;
while(RCC->CR & RCC_CR_PLLRDY);
// 8. Настроить PLL для получения 170 МГц от HSI.
// SYSCLK = (HSI / M) * N / R = (16МГц / 4) * 85 / 2 = 170 МГц
// VCO = (HSI / M) * N = 4МГц * 85 = 340 МГц (в допустимом диапазоне 64..344 МГц)
RCC->PLLCFGR = (RCC_PLLCFGR_PLLSRC_HSI | // Источник: HSI (16 МГц)
(3 << RCC_PLLCFGR_PLLM_Pos) | // Предделитель M = 4 (записывается 3)
(85 << RCC_PLLCFGR_PLLN_Pos) | // Множитель N = 85
RCC_PLLCFGR_PLLREN); // Включить главный выход PLL 'R'
// PLLR divider = 2 (по умолчанию, запись 0)
// 9. Включить PLL и дождаться его готовности.
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));
// 10. Переключить системные часы (SYSCLK) на PLL.
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
// Ожидаем подтверждения, что система действительно переключилась на PLL.
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
// 11. Обновить глобальную переменную с частотой ядра.
// Это необходимо для корректной работы функций HAL/CMSIS (например, для настройки SysTick).
SystemCoreClock = 170000000UL;
}