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을 선택합니다.
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 | ||||
| HSI | RCC_CR | HSION[0] | 그림에서: 내부 8 MHz HSI clock source를 켜거나 끕니다.0 = HSI 끔1 = HSI 켬SYSCLK로 쓰려면 HSIRDY=1을 확인한 뒤 SW=00으로 선택합니다. | 지원됨 |
| HSI | RCC_CR | HSIRDY[1] | 그림에서: HSI가 안정되어 사용할 준비가 되었는지 알려 줍니다.0 = 아직 준비되지 않음1 = 안정됨, clock source로 사용 가능실제 STM32에서는 소프트웨어가 쓰지 않는 하드웨어 상태 비트입니다. | 지원됨 |
| 2 HSE — 외부 crystal / bypass source | ||||
| HSE | RCC_CR | HSEON[16] | 그림에서: 외부 HSE clock source를 켜거나 끕니다.0 = HSE 끔1 = HSE 켬SYSCLK 또는 PLL 입력으로 쓰기 전에 HSERDY=1을 확인합니다. | 지원됨 |
| HSE | RCC_CR | HSERDY[17] | 그림에서: 외부 HSE가 안정되어 사용할 준비가 되었는지 알려 줍니다.0 = 아직 준비되지 않음1 = 안정됨, clock source로 사용 가능실제 STM32에서는 소프트웨어가 직접 쓰지 않는 하드웨어 상태 비트입니다. 이 clock helper는 발진 안정화 시간을 모델링하지 않고 대기 루프가 끝나도록 즉시 1로 맞춰 씁니다. | 지원됨 |
| 3 PLL — 입력 source와 배율 | ||||
| PLL | RCC_CFGR | PLLSRC[16] | 그림에서: PLL로 들어갈 원본 clock을 선택합니다.0 = HSI를 2분주한 HSI/21 = HSEPLL이 꺼진 상태에서 설정합니다. | 지원됨 |
| PLL | RCC_CFGR | PLLXTPRE[17] | 그림에서: HSE가 PLL로 들어가기 전에 2분주할지 정합니다.0 = HSE 그대로 입력(HSE/1)1 = HSE를 2분주해 입력(HSE/2)PLL이 꺼지고 PLLSRC=1(HSE)인 상태에서만 의미가 있습니다. | 지원됨 |
| PLL | RCC_CFGR | PLLMUL[21:18] | 그림에서: 선택한 PLL 입력 clock에 곱할 배율을 정합니다.0x0~0xD = ×2~×15(코드값 + 2)0xE/0xF = ×160x7 = ×9, 8 MHz HSE를 72 MHz로 만듦PLL이 꺼진 상태에서 설정하며, PLL 출력은 72 MHz를 넘기면 안 됩니다. | 지원됨 |
| PLL | RCC_CR | PLLON[24] | 그림에서: PLL 블록을 켜거나 끕니다.0 = PLL 끔1 = PLL 켬, lock 시작입력 source와 배율을 먼저 설정합니다. | 지원됨 |
| PLL | RCC_CR | PLLRDY[25] | 그림에서: PLL이 lock되어 사용할 준비가 되었는지 알려 줍니다.0 = 아직 lock되지 않음1 = lock 완료, SYSCLK source로 사용 가능실제 STM32에서는 소프트웨어가 직접 쓰지 않는 하드웨어 상태 비트입니다. 이 clock helper는 PLL lock 시간을 모델링하지 않고 대기 루프가 끝나도록 즉시 1로 맞춰 씁니다. | 지원됨 |
| 4 SYSCLK → HCLK / PCLK — mux와 prescaler | ||||
| SYSCLK | RCC_CFGR | SW[1:0] | 그림에서: SYSCLK가 사용할 source를 선택하도록 요청합니다.00 = HSI01 = HSE10 = PLL11 = 예약값, 사용하지 않음실제 전환 결과는 SWS를 읽어 확인합니다. | 지원됨 |
| SYSCLK | RCC_CFGR | SWS[3:2] | 그림에서: 현재 SYSCLK가 실제로 사용 중인 source를 알려 줍니다.00 = HSI 사용 중01 = HSE 사용 중10 = PLL 사용 중11 = 해당 없음실제 STM32에서는 소프트웨어가 직접 쓰지 않는 하드웨어 상태 필드입니다. 이 clock helper는 SW=PLL 뒤 SWS=PLL을 즉시 맞춰 쓰며, 일반 SW write가 SWS를 자동 mirror하지 않습니다. | 지원됨 |
| AHB | RCC_CFGR | HPRE[7:4] | 그림에서: HPRE라는 분주기 하나가 SYSCLK를 나눠 CPU와 AHB가 쓰는 HCLK를 만듭니다. 아래 값 중 하나만 선택하며, 분주를 연속으로 적용하지 않습니다.0xxx = SYSCLK /11000~1011 = /2, /4, /8, /16 중 하나1100~1111 = /64, /128, /256, /512 중 하나 | 지원됨 |
| APB1 | RCC_CFGR | PPRE1[10:8] | 그림에서: PPRE1이라는 분주기 하나가 HCLK를 나눠 APB1 peripheral clock인 PCLK1을 만듭니다. 아래 값 중 하나만 선택합니다.0xx = HCLK /1100 = /2101 = /4110 = /8111 = /16 | 지원됨 |
| 5 그림 밖: PCLK gate — peripheral register block 열기 | ||||
| PCLK2 | RCC_APB2ENR | AFIOEN[0] | 그림 밖에서: AFIO register block으로 가는 PCLK2 gate를 엽니다.0 = AFIO clock 차단1 = AFIO clock 공급, EXTI source mapping 경로 활성화 | 지원됨 |
| PCLK2 | RCC_APB2ENR | IOPAEN[2] | 그림 밖에서: GPIOA register block으로 가는 PCLK2 gate를 엽니다.0 = GPIOA clock 차단1 = GPIOA clock 공급, mode·입출력 경로 활성화 | 지원됨 |
| PCLK2 | RCC_APB2ENR | IOPBEN[3] | 그림 밖에서: GPIOB register block으로 가는 PCLK2 gate를 엽니다.0 = GPIOB clock 차단1 = GPIOB clock 공급, mode·입출력 경로 활성화 | 지원됨 |
| PCLK2 | RCC_APB2ENR | USART1EN[14] | 그림 밖에서: USART1 register block으로 가는 PCLK2 gate를 엽니다.0 = USART1 clock 차단1 = USART1 clock 공급, 송수신 설정 경로 활성화 | 지원됨 |
| PCLK1 | RCC_APB1ENR | TIM2EN[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_DIV1 | RCC_CFGR.PLLSRC[16] = 1, PLLXTPRE[17] = 0. 8 MHz HSE를 PLL 입력으로 그대로 보냅니다. | 보통 직접 조절하지 않고 helper 결과를 Code Watch에서 확인합니다. |
| RCC_CFGR_PLLMUL9 | RCC_CFGR.PLLMUL[21:18] = 0111. 8 MHz × 9 = 72 MHz PLL clock을 만듭니다. | 보통 직접 조절하지 않고 helper 결과를 Code Watch에서 확인합니다. |
| RCC_CFGR_SW_PLL, RCC_CFGR_SWS_PLL | RCC_CFGR.SW[1:0] = 10, SWS[3:2] = 10. PLL clock을 SYSCLK로 사용합니다. 실제 STM32에서 SWS는 하드웨어 상태값이고, clock helper는 대기 루프가 끝나도록 즉시 맞춰 둡니다. | Code Watch에서 확인합니다. |
| RCC_CFGR_HPRE_DIV1 | RCC_CFGR.HPRE[7:4] = 0xxx. HCLK = 72 MHz. | Code Watch에서 확인합니다. |
| RCC_CFGR_PPRE1_DIV2 | RCC_CFGR.PPRE1[10:8] = 100. PCLK1 = 36 MHz이고 TIM2 timing에 반영됩니다. | Code Watch와 TIM2 동작에서 확인합니다. |
| RCC_CFGR_PPRE2_DIV1 | RCC_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 = 0x00000002 | 72 MHz 전환 전 Flash latency 2를 저장합니다. 실제 Flash 대기 시간은 모델링하지 않습니다. | Code Watch |
| RCC->CR = 0x03030083 | HSE/PLL enable과 clock helper가 직접 기록한 ready 상태를 포함합니다. | Code Watch |
| RCC->CFGR = 0x001D840A | HSE /1 → PLL ×9, HCLK /1, PCLK1 /2, PCLK2 /1 및 PLL 선택 상태입니다. ADCPRE 고정값도 포함되지만 이 RCC 화면의 조절 대상은 아닙니다. | Code Watch |
| RCC_APB2ENR.IOPAEN = 1 | GPIOA register path를 엽니다. PA 핀 mode는 아직 별도 GPIO 설정이 필요합니다. | Registers → Clock |
| RCC_APB2ENR.IOPBEN = 1 | GPIOB register path를 엽니다. PB0의 analog mode는 아직 별도 GPIO 설정이 필요합니다. | Registers → Clock |
| RCC_APB1ENR.TIM2EN = 1 | TIM2 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를 확인합니다.
- Registers: Clock 그룹에서 RCC_APB2ENR의 AFIOEN/IOPAEN/IOPBEN/USART1EN과 RCC_APB1ENR의 TIM2EN을 ON/OFF로 확인합니다. 실행 예제의 ADC1EN은 ADC User Description 1번에서 확인합니다. RCC_CR/RCC_CFGR은 이 목록에 없으므로 Code Watch에서 확인합니다.
- Board · Lab pin routes: PA2/PWM_OUT 같은 신호 행을 선택하면 상세 패널에서 Live clock gates가 ON인지 확인할 수 있고 Graph trace 목록에 자동으로 추가됩니다.
- Graph: 추가된 신호가 보이는지 확인합니다. 이 RCC 전용 코드는 GPIO/TIM 출력을 아직 설정하지 않으므로 trace가 동작하지 않는 것이 정상입니다.
- Code Watch: RCC_CR의 HSEON/HSERDY/PLLON/PLLRDY, RCC_CFGR의 SW/SWS/PLLMUL, RCC_APB2ENR, RCC_APB1ENR 값이 갱신되는지 확인합니다.
- Docs / Log: RCC 전용 상태 로그는 자동으로 생성되지 않습니다. Clock 그룹과 Code Watch를 RCC 설정의 확인 근거로 사용합니다.
6. 지원하지 않는 항목
공식 STM32에는 존재하지만 현재 구현에서는 값 저장 또는 참고만 가능하며, 관련 동작은 실행하지 않습니다.
| 그림 블록 | 레지스터 | 필드 / bit | 공식 의미와 현재 구현 범위 | 지원 여부 |
|---|---|---|---|---|
| HSE | RCC_CR | HSEBYP[18] | 그림에서: HSE 입력을 crystal로 받을지 외부 clock 신호로 직접 받을지 정합니다.0 = crystal / resonator 사용1 = OSC_IN 외부 clock bypass 사용HSE가 꺼진 상태에서 설정합니다. 현재 구현은 값을 저장하지만 외부 bypass clock 입력 동작은 구현하지 않습니다. | 미지원 |
| APB2 | RCC_CFGR | PPRE2[13:11] | 그림에서: HCLK를 나눠 APB2 peripheral clock인 PCLK2를 만듭니다.0xx = HCLK /1100 = /2101 = /4110 = /8111 = /16현재 구현은 값을 저장하지만 PCLK2 동작 시간에는 반영하지 않습니다. | 미지원 |