HYUNTAE KIM's Portfolio
← Blog
Work

STM32 System Clock

workstudySTM32

1. 목적

하드웨어 팀에서 EMC RE 테스트를 위해 Manul F/W의 Clock Source 변경 요청이 왔다.

Manul은 8MHz의 HSE를 사용하여 180MHz의 System Clock을 사용하고 있다.
이번 요청의 목적은 HSE를 HSI로 변경하고 System Clock은 유지해야 한다는 것이다.

STM32 Clock 관련 포스트: [MCU Clock](/blog/MCU Clock)

2. Clock Source 변경

System Clock Source의 네 종류인 HSE, LSE, HSI, LSI 중 이번 일과 관련된 HSE와 HSI는 다음과 같은 특징이 있다.

  • HSE (High Speed External): 외부 크리스탈 or 오실레이터를 사용하여 빠른 속도와 정밀함이 필요할 때 주로 사용함
  • HSI (High Speed Internal): 칩 내부 오실레이터를 사용하며 HSE보단 정밀도가 떨어짐

펌웨어에서 Clock 소스 변경은 아래 코드와 같이 진행했다.

stm32_rcc_init()


    						⋮
    #if defined(USE_HSI_CLOCK)
    SET_BIT_MASK(RCC->CR, RCC_CR_HSION);
    HAL_RCC_WAIT(RCC_CR_HSIRDY);
    #else
    #if defined(USE_HSI_CLOCK)
    stm32_rcc_pll_config(HAL_RCC_PLL_SRC_HSI, 0, 16, 360, 2, 7);
    #else
						    ⋮
            #elif defined(__STM32F437VG__) || defined(__STM32F446RE__)
            // PLLCLK = 8 MHz / 8 * 360
            // PLL_N = 8
            // PLL_M = 360
            // PLL_P = 2
            // PLL_Q = 7
            stm32_rcc_pll_config(HAL_RCC_PLL_SRC_HSE, 0, 8, 360, 2, 7);
						    ⋮
    #endif
						    ⋮    

3. PLL 설정

Manul 보드의 시스템 Clock은 180MHz를 사용한다.
시스템 Clock을 유지하면서 Clock Source를 HSE에서 HSI로 바꾸기 위해서는 PLL의 설정 값들을 수정해야 한다.

현재 시스템은 STM32 F446칩을 사용하고, HSE를 8MHz로 사용하고 있다.
기존에 설정되어 있던 M, N, P의 값은 8, 360, 2로 구성되어 아래와 같이 계산된다.

SystemClock=8MHz/8360/2=180MHzSystem Clock = 8MHz / 8 * 360 / 2 = 180MHz

Pasted image 20260311175623.png

HSI의 주파수는 16MHz로 설정되어 있기 때문에 시스템 Clock을 유지하기 위해서는 M, N, P의 값을 16, 360, 2로 구성하면 된다.
계산 결과는 아래와 같다.

SystemClock=16MHz/16360/2=180MHzSystem Clock = 16MHz / 16 * 360 / 2 = 180MHz

Pasted image 20260311175602.png

4. 변경 결과

HSE를 HSI로 변경하고 PLL값을 수정한 후 레지스터에 쓰인 값을 통해 정상적으로 HSI로 변경되어있는지 아래 코드를 통해 확인해봤다.


    #if defined(USE_HSI_CLOCK)
        uint32_t cr = RCC->CR;
        uint32_t pll = RCC->PLLCFGR;
        uint32_t hse_on = (cr >> 16) & 1u;
        uint32_t hsi_on = (cr >> 0) & 1u;
        uint32_t pll_src_hse = (pll >> 22) & 1u;
        TRACE_BSS(level_INFO, "RCC: HSE=%s HSI=%s PLL_src=%s",
            hse_on ? "ON" : "OFF", hsi_on ? "ON" : "OFF",
            pll_src_hse ? "HSE" : "HSI");
    #endif

테스트 결과
Pasted image 20260316170601.png

실제 기기에 플래싱 한 후 테스트 한 결과
Pasted image 20260316171138.png

테스트 결과 HSI로 정상적으로 변경되고 Manul 펌웨어가 작동했다.
하지만 HSI를 사용한 결과 CAN 통신이 정상적으로 작동하지 않아 하위 모듈과의 통신이 자주 끊어져 기기가 정상 작동하지 않았다.