RCC User Description

RCC 그림에서 각 구역이 어떤 레지스터/필드로 제어되는지 빠르게 보는 페이지.

RCC Datasheet · 현재 Trainer 실행 예제 · GPIO · TIM · ADC · Lab Guide

1. 그림에서 먼저 보기

그림은 원본 clock tree를 가리지 않고 그대로 표시합니다. 아래 표의 1~4번은 이 그림의 clock source·PLL·SYSCLK/PCLK 경로를 설명합니다. 그림 속 /1, /2, /4 ...는 여러 분주기가 직렬로 연결된 모습이 아니라, 각 prescaler 필드에서 하나만 선택할 수 있는 값 목록입니다. 현재 helper는 HPRE=/1, PPRE1=/2, PPRE2=/1을 선택합니다.

STM32F103 RCC clock tree

HSI 8 MHz → /2는 PLLSRC가 HSI일 때만 쓰는 경로입니다. 현재 helper는 PLLSRC=HSE, PLLXTPRE=/1을 선택하므로 HSE 8 MHz → PLL ×9 → SYSCLK 72 MHz 경로를 사용합니다. 표의 5번은 이 그림 안의 분주비가 아니라, RCC_APB2ENR/RCC_APB1ENR gate bit로 peripheral register block을 여는 영역입니다.

2. 블록 → 레지스터 비트

읽는 순서: 지원되는 항목을 먼저 확인하고, 미지원 항목은 문서 하단의 지원하지 않는 항목에서 확인합니다.

각 행은 그림에서 하는 일 → 값별 의미 → 설정 조건 순서로 읽습니다. 설정 비트는 소프트웨어가 쓰고, 상태 비트는 실제 STM32 하드웨어가 동작 결과를 반영하므로 읽어서 확인합니다. 현재 구현에서 사용하는 trainer_clock_init_72mhz()는 HSE·PLL 준비 상태와 SYSCLK 상태를 즉시 함께 씁니다. 따라서 직접 HSEON/PLLON만 썼을 때 발진 안정화나 PLL lock이 자동 진행되는 것은 아닙니다.

그림 블록 레지스터 필드 / bit 그림에서 하는 일 / 값 의미 지원 여부
1 HSI — 내부 8 MHz source
HSIRCC_CRHSION[0]그림에서: 내부 8 MHz HSI clock source를 켜거나 끕니다.0 = HSI 끔1 = HSI 켬SYSCLK로 쓰려면 HSIRDY=1을 확인한 뒤 SW=00으로 선택합니다.지원됨
HSIRCC_CRHSIRDY[1]그림에서: HSI가 안정되어 사용할 준비가 되었는지 알려 줍니다.0 = 아직 준비되지 않음1 = 안정됨, clock source로 사용 가능실제 STM32에서는 소프트웨어가 쓰지 않는 하드웨어 상태 비트입니다.지원됨
2 HSE — 외부 crystal / bypass source
HSERCC_CRHSEON[16]그림에서: 외부 HSE clock source를 켜거나 끕니다.0 = HSE 끔1 = HSE 켬SYSCLK 또는 PLL 입력으로 쓰기 전에 HSERDY=1을 확인합니다.지원됨
HSERCC_CRHSERDY[17]그림에서: 외부 HSE가 안정되어 사용할 준비가 되었는지 알려 줍니다.0 = 아직 준비되지 않음1 = 안정됨, clock source로 사용 가능실제 STM32에서는 소프트웨어가 직접 쓰지 않는 하드웨어 상태 비트입니다. 이 clock helper는 발진 안정화 시간을 모델링하지 않고 대기 루프가 끝나도록 즉시 1로 맞춰 씁니다.지원됨
3 PLL — 입력 source와 배율
PLLRCC_CFGRPLLSRC[16]그림에서: PLL로 들어갈 원본 clock을 선택합니다.0 = HSI를 2분주한 HSI/21 = HSEPLL이 꺼진 상태에서 설정합니다.지원됨
PLLRCC_CFGRPLLXTPRE[17]그림에서: HSE가 PLL로 들어가기 전에 2분주할지 정합니다.0 = HSE 그대로 입력(HSE/1)1 = HSE를 2분주해 입력(HSE/2)PLL이 꺼지고 PLLSRC=1(HSE)인 상태에서만 의미가 있습니다.지원됨
PLLRCC_CFGRPLLMUL[21:18]그림에서: 선택한 PLL 입력 clock에 곱할 배율을 정합니다.0x0~0xD = ×2~×15(코드값 + 2)0xE/0xF = ×160x7 = ×9, 8 MHz HSE를 72 MHz로 만듦PLL이 꺼진 상태에서 설정하며, PLL 출력은 72 MHz를 넘기면 안 됩니다.지원됨
PLLRCC_CRPLLON[24]그림에서: PLL 블록을 켜거나 끕니다.0 = PLL 끔1 = PLL 켬, lock 시작입력 source와 배율을 먼저 설정합니다.지원됨
PLLRCC_CRPLLRDY[25]그림에서: PLL이 lock되어 사용할 준비가 되었는지 알려 줍니다.0 = 아직 lock되지 않음1 = lock 완료, SYSCLK source로 사용 가능실제 STM32에서는 소프트웨어가 직접 쓰지 않는 하드웨어 상태 비트입니다. 이 clock helper는 PLL lock 시간을 모델링하지 않고 대기 루프가 끝나도록 즉시 1로 맞춰 씁니다.지원됨
4 SYSCLK → HCLK / PCLK — mux와 prescaler
SYSCLKRCC_CFGRSW[1:0]그림에서: SYSCLK가 사용할 source를 선택하도록 요청합니다.00 = HSI01 = HSE10 = PLL11 = 예약값, 사용하지 않음실제 전환 결과는 SWS를 읽어 확인합니다.지원됨
SYSCLKRCC_CFGRSWS[3:2]그림에서: 현재 SYSCLK가 실제로 사용 중인 source를 알려 줍니다.00 = HSI 사용 중01 = HSE 사용 중10 = PLL 사용 중11 = 해당 없음실제 STM32에서는 소프트웨어가 직접 쓰지 않는 하드웨어 상태 필드입니다. 이 clock helper는 SW=PLL 뒤 SWS=PLL을 즉시 맞춰 쓰며, 일반 SW write가 SWS를 자동 mirror하지 않습니다.지원됨
AHBRCC_CFGRHPRE[7:4]그림에서: HPRE라는 분주기 하나가 SYSCLK를 나눠 CPU와 AHB가 쓰는 HCLK를 만듭니다. 아래 값 중 하나만 선택하며, 분주를 연속으로 적용하지 않습니다.0xxx = SYSCLK /11000~1011 = /2, /4, /8, /16 중 하나1100~1111 = /64, /128, /256, /512 중 하나지원됨
APB1RCC_CFGRPPRE1[10:8]그림에서: PPRE1이라는 분주기 하나가 HCLK를 나눠 APB1 peripheral clock인 PCLK1을 만듭니다. 아래 값 중 하나만 선택합니다.0xx = HCLK /1100 = /2101 = /4110 = /8111 = /16지원됨
5 그림 밖: PCLK gate — peripheral register block 열기
PCLK2RCC_APB2ENRAFIOEN[0]그림 밖에서: AFIO register block으로 가는 PCLK2 gate를 엽니다.0 = AFIO clock 차단1 = AFIO clock 공급, EXTI source mapping 경로 활성화지원됨
PCLK2RCC_APB2ENRIOPAEN[2]그림 밖에서: GPIOA register block으로 가는 PCLK2 gate를 엽니다.0 = GPIOA clock 차단1 = GPIOA clock 공급, mode·입출력 경로 활성화지원됨
PCLK2RCC_APB2ENRIOPBEN[3]그림 밖에서: GPIOB register block으로 가는 PCLK2 gate를 엽니다.0 = GPIOB clock 차단1 = GPIOB clock 공급, mode·입출력 경로 활성화지원됨
PCLK2RCC_APB2ENRUSART1EN[14]그림 밖에서: USART1 register block으로 가는 PCLK2 gate를 엽니다.0 = USART1 clock 차단1 = USART1 clock 공급, 송수신 설정 경로 활성화지원됨
PCLK1RCC_APB1ENRTIM2EN[0]그림 밖에서: TIM2 register block으로 가는 PCLK1 gate를 엽니다.0 = TIM2 clock 차단1 = TIM2 clock 공급, counter·timer 경로 활성화지원됨

3. 72 MHz 초기화 함수가 하는 일

trainer_clock_init_72mhz()는 아래 표의 값을 한 번에 넣어 주는 공통 helper입니다. FW EDIT에는 함수를 다시 붙여넣지 않고 호출만 합니다. User Description에서는 내부 비트마스크 코드를 외우는 것이 아니라, 그림 1의 각 블록이 어떤 값으로 고정되는지만 보면 됩니다. HSERDY, PLLRDY, SWS는 실제 STM32에서 하드웨어가 만든 상태값이고, 이 clock helper가 대기 루프를 끝내기 위해 즉시 맞춰 쓰는 구현 전용 동작입니다.

현재 코드 / 값 데이터시트 필드로 해석 화면에서 확인
RCC_CFGR_PLLSRC_HSE, RCC_CFGR_PLLXTPRE_DIV1RCC_CFGR.PLLSRC[16] = 1, PLLXTPRE[17] = 0. 8 MHz HSE를 PLL 입력으로 그대로 보냅니다.보통 직접 조절하지 않고 helper 결과를 Code Watch에서 확인합니다.
RCC_CFGR_PLLMUL9RCC_CFGR.PLLMUL[21:18] = 0111. 8 MHz × 9 = 72 MHz PLL clock을 만듭니다.보통 직접 조절하지 않고 helper 결과를 Code Watch에서 확인합니다.
RCC_CFGR_SW_PLL, RCC_CFGR_SWS_PLLRCC_CFGR.SW[1:0] = 10, SWS[3:2] = 10. PLL clock을 SYSCLK로 사용합니다. 실제 STM32에서 SWS는 하드웨어 상태값이고, clock helper는 대기 루프가 끝나도록 즉시 맞춰 둡니다.Code Watch에서 확인합니다.
RCC_CFGR_HPRE_DIV1RCC_CFGR.HPRE[7:4] = 0xxx. HCLK = 72 MHz.Code Watch에서 확인합니다.
RCC_CFGR_PPRE1_DIV2RCC_CFGR.PPRE1[10:8] = 100. PCLK1 = 36 MHz이고 TIM2 timing에 반영됩니다.Code Watch와 TIM2 동작에서 확인합니다.
RCC_CFGR_PPRE2_DIV1RCC_CFGR.PPRE2[13:11] = 0xx. PCLK2 = 72 MHz입니다.값은 보존하지만 PCLK2 timing side effect는 모델링하지 않으므로 Code Watch 표시만 확인합니다.

3.1 표 기준 단순 코드

아래 코드는 위 표의 값이 어느 줄에서 설정되는지만 보여주는 helper 내부 관찰용 코드입니다. 완성된 실습 코드는 아니며, FW EDIT에는 4번처럼 trainer_clock_init_72mhz()만 호출합니다.

uint32_t cfgr = 0u;

// PLL 입력 선택: HSI를 선택하면 HSI/2 = 4 MHz가 PLL로 들어옵니다.
// 여기서는 PLLSRC=HSE를 선택했으므로 HSE 8 MHz 경로를 사용합니다.
cfgr |= RCC_CFGR_PLLSRC_HSE;       // PLLSRC = HSE
cfgr |= RCC_CFGR_PLLXTPRE_DIV1;    // HSE 경로의 /1 선택: 8 MHz를 그대로 PLL에 입력

// PLL 배율: 8 MHz × 9 = 72 MHz를 만듭니다.
cfgr |= RCC_CFGR_PLLMUL9;          // PLLMUL = ×9

// HPRE/PPRE1/PPRE2는 각각 분주기 하나입니다. /1, /2, /4 ...는
// 여러 단계를 모두 거치는 뜻이 아니라, 각 필드에서 하나만 고르는 선택지입니다.
cfgr |= RCC_CFGR_HPRE_DIV1;        // HPRE=/1 하나 선택: HCLK  = SYSCLK /1 = 72 MHz
cfgr |= RCC_CFGR_PPRE1_DIV2;       // PPRE1=/2 하나 선택: PCLK1 = HCLK /2 = 36 MHz (TIM2CLK는 timer x2 규칙으로 72 MHz)
cfgr |= RCC_CFGR_PPRE2_DIV1;       // PPRE2=/1 하나 선택: PCLK2 = HCLK /1 = 72 MHz

RCC->CFGR = cfgr;

// SYSCLK 선택: PLL을 시스템 클럭으로 사용합니다.
RCC->CFGR |= RCC_CFGR_SW_PLL;      // SW = PLL
RCC->CFGR |= RCC_CFGR_SWS_PLL;     // 현재 구현 전용: 실제 STM32에서는 읽는 상태값

실제 helper도 같은 흐름으로 동작하며, FLASH latency, HSE/PLL ready 상태, 내부 고정값인 ADCPRE까지 함께 처리합니다.

3.2 코드가 남기는 값과 확인 위치

실행 뒤 값의미화면에서 확인할 곳
FLASH->ACR = 0x0000000272 MHz 전환 전 Flash latency 2를 저장합니다. 실제 Flash 대기 시간은 모델링하지 않습니다.Code Watch
RCC->CR = 0x03030083HSE/PLL enable과 clock helper가 직접 기록한 ready 상태를 포함합니다.Code Watch
RCC->CFGR = 0x001D840AHSE /1 → PLL ×9, HCLK /1, PCLK1 /2, PCLK2 /1 및 PLL 선택 상태입니다. ADCPRE 고정값도 포함되지만 이 RCC 화면의 조절 대상은 아닙니다.Code Watch
RCC_APB2ENR.IOPAEN = 1GPIOA register path를 엽니다. PA 핀 mode는 아직 별도 GPIO 설정이 필요합니다.Registers → Clock
RCC_APB2ENR.IOPBEN = 1GPIOB register path를 엽니다. PB0의 analog mode는 아직 별도 GPIO 설정이 필요합니다.Registers → Clock
RCC_APB1ENR.TIM2EN = 1TIM2 register path를 엽니다. 주기·PWM 출력은 아직 별도 TIM2/GPIO 설정이 필요합니다.Registers → Clock

4. 현재 Trainer 실행 예제

FW EDIT에 그대로 붙여넣는 P02 RCC 예제입니다. 각 주석의 번호는 위 블록 → 레지스터 비트 표의 번호와 연결됩니다.

#include "training_api.h"

void user_init(void)
{
    trainer_clock_init_72mhz();                /* RCC User Description 1~4번: HSI/HSE/PLL/SYSCLK·PCLK 경로 */

    RCC->APB2ENR = RCC_APB2ENR_AFIOEN;        /* RCC User Description 5번: AFIO PCLK2 gate */
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;       /* RCC User Description 5번: GPIOA PCLK2 gate */
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;       /* RCC User Description 5번: GPIOB PCLK2 gate */
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;       /* ADC User Description 1번: ADC1 PCLK2 gate */
    RCC->APB1ENR = RCC_APB1ENR_TIM2EN;        /* RCC User Description 5번: TIM2 PCLK1 gate */
}

void user_loop(void)
{
    watch_u32("RCC_CR", RCC->CR);             /* 1~3번 clock source와 PLL 상태 */
    watch_u32("RCC_CFGR", RCC->CFGR);         /* 3~4번 PLL·SYSCLK·prescaler 선택 */
    watch_u32("RCC_APB2ENR", RCC->APB2ENR); /* 5번 PCLK2 peripheral gates */
    watch_u32("RCC_APB1ENR", RCC->APB1ENR); /* 5번 PCLK1 peripheral gates */
}

5. 사이트에서 확인

바로 위 실행 예제를 실행한 뒤 아래 화면에서 clock source와 peripheral gate를 확인합니다.

6. 지원하지 않는 항목

공식 STM32에는 존재하지만 현재 구현에서는 값 저장 또는 참고만 가능하며, 관련 동작은 실행하지 않습니다.

그림 블록레지스터필드 / bit공식 의미와 현재 구현 범위지원 여부
HSERCC_CRHSEBYP[18]그림에서: HSE 입력을 crystal로 받을지 외부 clock 신호로 직접 받을지 정합니다.0 = crystal / resonator 사용1 = OSC_IN 외부 clock bypass 사용HSE가 꺼진 상태에서 설정합니다. 현재 구현은 값을 저장하지만 외부 bypass clock 입력 동작은 구현하지 않습니다.미지원
APB2RCC_CFGRPPRE2[13:11]그림에서: HCLK를 나눠 APB2 peripheral clock인 PCLK2를 만듭니다.0xx = HCLK /1100 = /2101 = /4110 = /8111 = /16현재 구현은 값을 저장하지만 PCLK2 동작 시간에는 반영하지 않습니다.미지원