leecrossun 2025. 3. 1. 15:46

Introduction of PLL

PLL을 사용하면 마이크로 프로세서의 최대치 (180MHz) 까지 시스템 클럭 증가

이론적으로는 400MHz 이상도 가능하지만 PLL 프리스케일러로 출력 제한

 

  • PLL의 입력 소스
    • HSE또는 HSI 를 입력으로 사용
    • 력 신호가 바로 VCO(전압 제어 오실레이터, Voltage-Controlled Oscillator)로 전달되지 않고,먼저 M 분주기(PLL M Divider) 를 통과
  • VCO(Voltage-Controlled Oscillator) 역할
    • VCO는 PLL 엔진의 핵심 부품으로, 주파수 합성(Frequency Synthesizer) 역할
    • M 분주기(PLL M)를 통해 입력된 클럭이 VCO의 입력 클럭(f_vco input clock)
    • VCO 내부에서 설정된 배수 값(PLL N Multiplier)을 적용하여 고주파 출력 클럭을 생성
  • 출력 클럭 조정
    • VCO에서 생성된 출력 클럭은 매우 높은 주파수를 가지므로,이를 다시 P 분주기(PLL P Divider) 를 거쳐 원하는 시스템 클럭(SYSCLK)으로 변환
    • PLLCLK(PLL 출력 클럭) 을 SYSCLK으로 사용

PLL 설정 규칙

VCO 입력 클럭 제한

  • VCO 입력 클럭은 1MHz ~ 2MHz 범위 내
  • 예를 들어, HSE가 8MHz일 경우:
    • M 값이 8이면: 8MHz / 8 = 1MHz → 허용됨 ✅
    • M 값이 4이면: 8MHz / 4 = 2MHz → 허용됨 ✅
  • 이 규칙을 준수해야 PLL이 정상적으로 동작

 

VCO 출력 클럭 제한

  • VCO 출력 클럭은 100MHz 이상, 432MHz 이하
  • 따라서, PLL N 배수를 설정할 때 이 범위를 초과하지 않도록 주의

 

PLL 출력 클럭 계산 공식

  • PLLM : 입력 클럭 분주기 (M Divider)
  • PLLN : VCO 배수 값 (N Multiplier)
  • f_VCO : VCO 출력 클럭 (100MHz ~ 432MHz)

최종적으로 시스템 클럭(SYSCLK)을 얻기 위해 P 분주기(PLLP) 적용


PLL Configuration - Oscillator initialization

  • PLLQ(USB OTG FS, SDIO CLK), PLLR(I2S, SAI 등) 은 사용하지 않으므로 기본값 2로 냅둠
  • 주의할 점 :
    • PLL 엔진의 입력 클럭 주파수는 1MHz ~ 2MHz 범위
    • PLLN은 50이상 432이하 (레퍼런스 메뉴얼)
  • 설정값 예 :
    • 50MHz: PLLM=16, PLLN=100, PLLP=2 (예시 그림 참조)
    • 84MHz: PLLM=16, PLLN=168, PLLP=2
    • 120MHz: PLLM=16, PLLN=240, PLLP=2

PLL Configuration - Clock Initialization

  • 클럭 초기화
    • HCLK, APB1, APB2의 분배기를 설정하여 원하는 주파수에 맞게 시스템 클럭 설정
    • 50MHz의 경우 APB1과 APB2는 2로 설정
  • 플래시 대기 시간 설정:
    • HCLK가 50MHz일 경우 플래시 대기 시간은 2, 84MHz일 경우 2, 120MHz일 경우 3
  • Systick 구성:
    • HCLK 주파수에 맞춰 Systick을 설정하여 1ms레이턴시 설정
// main_app.c
void SystemClock_Config(uint8_t clock_freq)
{
	RCC_OscInitTypeDef osc_init;
	RCC_ClkInitTypeDef clk_init;
	uint32_t FLatency = 0;

	osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
	osc_init.HSIState = RCC_HSI_ON;
	osc_init.HSICalibrationValue = 16;
	osc_init.PLL.PLLState = RCC_PLL_ON;
	osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSI;

	switch(clock_freq){
	case SYS_CLOCK_FREQ_50_MHZ:
		osc_init.PLL.PLLM = 16;
		osc_init.PLL.PLLN = 100;
		osc_init.PLL.PLLP = 2;
		osc_init.PLL.PLLQ = 2;
		osc_init.PLL.PLLR = 2;

		clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
		clk_init.APB1CLKDivider = RCC_HCLK_DIV2;
		clk_init.APB2CLKDivider = RCC_HCLK_DIV2;
		FLatency = FLASH_ACR_LATENCY_1WS;
		break;
	case SYS_CLOCK_FREQ_84_MHZ:
		osc_init.PLL.PLLM = 16;
		osc_init.PLL.PLLN = 168;
		osc_init.PLL.PLLP = 2;
		osc_init.PLL.PLLQ = 2;
		osc_init.PLL.PLLR = 2;

		clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
		clk_init.APB1CLKDivider = RCC_HCLK_DIV2;
		clk_init.APB2CLKDivider = RCC_HCLK_DIV2;
		FLatency = FLASH_ACR_LATENCY_2WS;
		break;
	case SYS_CLOCK_FREQ_120_MHZ:
		osc_init.PLL.PLLM = 16;
		osc_init.PLL.PLLN = 240;
		osc_init.PLL.PLLP = 2;
		osc_init.PLL.PLLQ = 2;
		osc_init.PLL.PLLR = 2;

		clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
		clk_init.APB1CLKDivider = RCC_HCLK_DIV4;
		clk_init.APB2CLKDivider = RCC_HCLK_DIV2;
		FLatency = FLASH_ACR_LATENCY_3WS;
		break;
	default:
		return;
	}

	if(HAL_RCC_OscConfig(&osc_init) != HAL_OK) Error_handler();
	if(HAL_RCC_ClockConfig(&clk_init, FLatency) != HAL_OK) Error_handler();


	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

}

MAXIMUM 180MHz Configuration

  • HCLK를 180MHz에서 실행하려면 voltage regulators over-drive mode 를 켜야 함. 그렇지 않으면 AHB CLK이 180MHz에 도달하지 않음. 그리고 voltage scale이 1이어야 함
  • 전원 컨트롤러의 CR 이라는 레지스터를 통해 이를 설정할 수 있음
    • ODEN : over-drive switching enabled
    • VOS : voltage scale

	case SYS_CLOCK_FREQ_180_MHZ:
		__HAL_RCC_PWR_CLK_ENABLE(); // enable the clock for the power controller
		__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); // set regulator voltage scale as 1
		__HAL_PWR_OVERDRIVE_ENABLE(); // turn on the oer drive mode of the voltage regulator
		
		osc_init.PLL.PLLM = 16;
		osc_init.PLL.PLLN = 360;
		osc_init.PLL.PLLP = 2;
		osc_init.PLL.PLLQ = 2;
		osc_init.PLL.PLLR = 2;

		clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
		clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
		clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
		clk_init.APB1CLKDivider = RCC_HCLK_DIV4;
		clk_init.APB2CLKDivider = RCC_HCLK_DIV2;
		FLatency = FLASH_ACR_LATENCY_5WS;
		break;

 

실행 결과

반응형