STM32H7 — настройка тактирования без HAL
Не так давно компания STM выпустила на рынок очень мощную, по меркам микроконтроллеров, линейку кристаллов STM32H7. Что меня в ней привлекло:
Отлично подумал я, запаял на плату кристалл STM32H743IIT6 вместо STM32F746IGT6 и начал новый проект в SW4STM32.
Для расчета коэффициентов делителей и множителей системы тактирования микроконтроллера удобно пользоваться вкладкой Clock Configuration программы STM32CubeMX.
Настройки тактирования:
Соответственно, частота ядра (SYSCLK)- 400 МГц.

Кроме STM32CubeMX есть еще набор «STM32CubeH7 firmware package», который содержит большое количество примеров для работы с периферией для STM32H7. Именно из него была взята последовательность инициализации системы тактирования микроконтроллера.
Информация и комментарии взяты из следующих источников:
Итак, начнем.
1. Включение внешнего кварца и ожидание готовности.
2. Указание источника частоты для PLL1 — внешний кварц.
3. Значение делителя устанавливается равным 4.
4. Множитель N и делители P, Q, R
5. Дробный делитель частоты PLL (если нужен)
6. Указание диапазона входной частоты PLL1
7. Указание диапазона выходной частоты PLL1
8. Включение выходных делителей PLL1: P, Q, R
9. Включение дробного делителя.
10. Пуск PLL1 и ожидание готовности
PLL1 настроен и запущен. Теперь выбор источника частоты SYSCLK и настройка делителей шин.
11. Делитель на 2 HPRE
12. Без деления D1CPRE
13. Задаем PLL1 как источник SYSCLK и ожидаем готовности
14. Делитель на 2 D1PPRE
15. Делитель на 2 D2PPRE1
16. Делитель на 2 D2PPRE2
17. Делитель на 2 D3PPRE
Для того чтобы убедиться, что конфигурирование и запуск прошли успешно используем выход микроконтроллера MCO2. На этом выходе должна быть частота 26.666 МГц при делителе выхода 15.

Отлично. Частота присутствует, значит все сделано правильно.
- повышенная частота ядра до 400 МГц
- увеличенный объем ОЗУ, до 1 МБ
- 16 разрядный АЦП
- pin-to-pin совместимость с серий F7
Отлично подумал я, запаял на плату кристалл STM32H743IIT6 вместо STM32F746IGT6 и начал новый проект в SW4STM32.
Для расчета коэффициентов делителей и множителей системы тактирования микроконтроллера удобно пользоваться вкладкой Clock Configuration программы STM32CubeMX.
Настройки тактирования:
- внешний кварц — 8 МГц
- источник частоты для PLL1 — внешний кварц (HSE)
- делитель для PLL1 — 4 (DIVM1)
- множитель PLL1 — 400 (DIVN1)
- выходные делители — 2 (DIVP1, DIVQ1, DIVR1)
Соответственно, частота ядра (SYSCLK)- 400 МГц.

Кроме STM32CubeMX есть еще набор «STM32CubeH7 firmware package», который содержит большое количество примеров для работы с периферией для STM32H7. Именно из него была взята последовательность инициализации системы тактирования микроконтроллера.
Информация и комментарии взяты из следующих источников:
- SystemClock_Config из STM32CubeH7 firmware package
- Reference manual STM32H743/753 and STM32H750 advanced ARM-based 32-bit MCUs
- — Datasheet STM32H743xI
Итак, начнем.
1. Включение внешнего кварца и ожидание готовности.
// Enable HSE
RCC->CR |= RCC_CR_HSEON;
// Wait till HSE is ready
while((RCC->CR & RCC_CR_HSERDY) == 0);
2. Указание источника частоты для PLL1 — внешний кварц.
//RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC -> PLLCKSELR |= RCC_PLLCKSELR_PLLSRC_HSE;
3. Значение делителя устанавливается равным 4.
//PLLM = 4
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_5; //0
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_4; //0
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_3; //0
RCC -> PLLCKSELR |= RCC_PLLCKSELR_DIVM1_2; //1
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_1; //0
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_0; //0
4. Множитель N и делители P, Q, R
//PLL1DIVR bits
//DIVN1[8:0] 0 - 8 PLLN = 400
//DIVP1[6:0] 9 - 15 PLLP = 2
//DIVQ1[6:0] 16 - 22 PLLQ = 2
//DIVR1[6:0] 24 - 30 PLLR = 2
RCC -> PLL1DIVR |= 0x0101038F;
5. Дробный делитель частоты PLL (если нужен)
// /* Configure PLL PLL1FRACN */
//__HAL_RCC_PLLFRACN_CONFIG(RCC_OscInitStruct->PLL.PLLFRACN);
RCC -> PLL1FRACR = 0;
6. Указание диапазона входной частоты PLL1
/* Select PLL1 input reference frequency range: VCI */
//__HAL_RCC_PLL_VCIRANGE(RCC_OscInitStruct->PLL.PLLRGE) ;
RCC->PLLCFGR |= RCC_PLLCFGR_PLL1RGE_3;
7. Указание диапазона выходной частоты PLL1
/* Select PLL1 output frequency range : VCO */
//__HAL_RCC_PLL_VCORANGE(RCC_OscInitStruct->PLL.PLLVCOSEL) ;
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLL1VCOSEL;
8. Включение выходных делителей PLL1: P, Q, R
/* Enable PLL System Clock output. */
// __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVP);
//Bit 16 DIVP1EN: PLL1 DIVP divider output enable
RCC->PLLCFGR |= RCC_PLLCFGR_DIVP1EN;
/* Enable PLL1Q Clock output. */
//__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
RCC->PLLCFGR |= RCC_PLLCFGR_DIVQ1EN;
/* Enable PLL1R Clock output. */
// __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVR);
RCC->PLLCFGR |= RCC_PLLCFGR_DIVR1EN;
9. Включение дробного делителя.
/* Enable PLL1FRACN . */
//__HAL_RCC_PLLFRACN_ENABLE();
RCC->PLLCFGR |= RCC_PLLCFGR_PLL1FRACEN;
10. Пуск PLL1 и ожидание готовности
/* Enable the main PLL. */
//__HAL_RCC_PLL_ENABLE();
RCC->CR |= RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLL1RDY) == 0);
PLL1 настроен и запущен. Теперь выбор источника частоты SYSCLK и настройка делителей шин.
11. Делитель на 2 HPRE
//RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
// MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
//HPRE[3:0]: D1 domain AHB prescaler
//1000: rcc_hclk3 = sys_d1cpre_ck / 2
RCC -> D1CFGR |= RCC_D1CFGR_HPRE_3; //1
RCC -> D1CFGR &= ~RCC_D1CFGR_HPRE_2; //0
RCC -> D1CFGR &= ~RCC_D1CFGR_HPRE_1; //0
RCC -> D1CFGR &= ~RCC_D1CFGR_HPRE_0; //0
12. Без деления D1CPRE
//RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
//MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_D1CPRE, RCC_ClkInitStruct->SYSCLKDivider);
//D1CPRE[3:0]: D1 domain Core prescaler
//0xxx: sys_ck not divided (default after reset)
RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_3; //0
RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_2; //0
RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_1; //0
RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_0; //0
13. Задаем PLL1 как источник SYSCLK и ожидаем готовности
//RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
//MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
//SW[2:0]: System clock switch
//011: PLL1 selected as system clock (pll1_p_ck)
RCC->CFGR &= ~RCC_CFGR_SW_2; //0
RCC->CFGR |= RCC_CFGR_SW_1; //1
RCC->CFGR |= RCC_CFGR_SW_0; //1
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL1);
14. Делитель на 2 D1PPRE
//D1PCLK1 Configuration
//RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
//MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_D1PPRE, RCC_ClkInitStruct->APB3CLKDivider);
//Bits 6:4 D1PPRE[2:0]: D1 domain APB3 prescaler
//100: rcc_pclk3 = rcc_hclk3 / 2
RCC -> D1CFGR |= RCC_D1CFGR_D1PPRE_2;
RCC -> D1CFGR &= ~RCC_D1CFGR_D1PPRE_1;
RCC -> D1CFGR &= ~RCC_D1CFGR_D1PPRE_0;
15. Делитель на 2 D2PPRE1
//PCLK1 Configuration
//RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
//MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE1, (RCC_ClkInitStruct->APB1CLKDivider));
//Bits 6:4 D2PPRE1[2:0]: D2 domain APB1 prescaler
//100: rcc_pclk1 = rcc_hclk1 / 2
RCC -> D2CFGR |= RCC_D2CFGR_D2PPRE1_2;
RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE1_1;
RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE1_0;
16. Делитель на 2 D2PPRE2
//PCLK2 Configuration
//RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
//MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE2, (RCC_ClkInitStruct->APB2CLKDivider));
//Bits 10:8 D2PPRE2[2:0]: D2 domain APB2 prescaler
//100: rcc_pclk2 = rcc_hclk1 / 2
RCC -> D2CFGR |= RCC_D2CFGR_D2PPRE2_2;
RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE2_1;
RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE2_0;
17. Делитель на 2 D3PPRE
//D3PCLK1 Configuration
//RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
//MODIFY_REG(RCC->D3CFGR, RCC_D3CFGR_D3PPRE, (RCC_ClkInitStruct->APB4CLKDivider) );
//Bits 6:4 D3PPRE[2:0]: D3 domain APB4 prescaler
//100: rcc_pclk4 = rcc_hclk4 / 2
RCC -> D3CFGR |= RCC_D3CFGR_D3PPRE_2;
RCC -> D3CFGR &= ~RCC_D3CFGR_D3PPRE_1;
RCC -> D3CFGR &= ~RCC_D3CFGR_D3PPRE_0;
Для того чтобы убедиться, что конфигурирование и запуск прошли успешно используем выход микроконтроллера MCO2. На этом выходе должна быть частота 26.666 МГц при делителе выхода 15.

Отлично. Частота присутствует, значит все сделано правильно.
Комментарии 54
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.