- 전원 공급
MCU가 설계한 대로 동작하기 위해 가장 먼저 확인해야 할 중요한 부분이다.
외부에서 인가되는 전원이 정해진 전압 내에 있는지 감시하는 기능이 있다.
즉, VDD(디지털 회로 전원 공급 pin) / VDDA(ADC, DAC 아날로그 회로 전원 공급원)가
2V보다 커지거나 작아지면,
위의 기능이 발생하여 자동으로 NRST pin을 low로 구동시킨다.
NRST pin은 Reset pin으로 low상태가 되면, MCU를 Reset하여 Flash memory의 처음부터 다시 시작하게한다.
일반적으로 전원이 들어오면 자동으로 Reset되지만, 외부에서 수동으로도 가능하다.
내부적으로 풀업저항이 존재하지만, 안정성을 위해 외부 풀업저항을 회로에 연결해주는 것이 좋다.
즉, 오류 복구, 전원 불안정 감지, 디버깅, 초기화 등에 사용하는 핀이다.
여하튼, 측정된 공급 전압이 POR, PDR 임계값보다 작으면 Reset mode를 유지한다.
POR과 PDR은 항상 active상태를 유지한다.
일반적으로, STM32 MCU의 정상동작을 위해 2[V]~3.6[V]의 외부 전원 VDD가 공급되어야 한다.
이후, 내장된 Regulator가 이를 1.8[V]로 변환해 내부 Core, Memory 등 주변 장치들에 공급한다.
외부 전원 VDD가 공급되지 않는 경우에는 자동으로 BKP(Backup) register, RTC, BKPSRAM은 battery전원인 VBAT에서 전원을 공급받는다.
PWR_CR(Power Control Register)의 PLS[2:0]에서 선택한 PVD(Programmable Voltage Detector) level 설정을 통해 공급 전원과 PVD 임계값을 PVDO flag를 통해 비교하고,
크거나 작아지면 event를 발생시킬 수가 있다. EXTI line 16에 연결되어 있으므로, 이를 enabling해주면 MCU 공급 전원을 감시하다 외부에 전원 정보를 알려줄 수가 있다.
예를 들면, EXTI line 16을 Rising edge sensitvity로 구성시, VDD가 PVD임계값 아래로 떨어질 때, Interrupt가 발생한다. 이때의 ISR은 emergency shutdown task가 된다.
PVDO(PVD Output) 플래그는 현재 공급 전압이 임계값보다 낮으면 1(Set), 높으면 0(Reset)이 된다.
즉,
VDD ≥ PVD 임계값 → PVDO = 0
VDD < PVD 임계값 → PVDO = 1 (전압이 낮아졌다는 의미)
EXTI Line 16과 인터럽트 트리거 방식
EXTI Line 16은 PVDO 상태 변화를 감지하여 인터럽트를 발생시킴.
EXTI의 감지 방식에는 Rising Edge(상승 엣지), Falling Edge(하강 엣지), Both Edge(양쪽 엣지) 가 있다.
Rising Edge를 설정했을 때의 동작
PVDO 플래그가 0 → 1로 변할 때, 즉 VDD가 PVD 임계값보다 낮아지는 순간 인터럽트가 발생합니다.
PVDO는 VDD < PVD 임계값이 되면 0 → 1로 변하므로, Rising Edge 감도를 설정하면 이 순간 인터럽트가 트리거됩니다.
즉, "전압이 떨어질 때" PVDO가 0 → 1로 변하므로 Rising Edge 트리거가 발생하는 것
반대로 Falling Edge를 설정하면?
VDD가 다시 PVD 임계값을 넘어서 올라갈 때, PVDO가 1 → 0으로 변함
이 경우, Falling Edge 감도를 설정했다면
"전원이 회복되는 순간" 인터럽트 발생. 이때 ISR은 전원 회복
즉, EXTI를 Rising Edge로 설정하면 VDD가 임계값 아래로 떨어질 때 인터럽트가 발생하는 것
왜냐하면 PVDO가 0 → 1로 변하는 순간이 "전압이 떨어질 때"이기 때문
즉, PVD 인터럽트는 PVDO가 변할 때 발생하는 것이므로, 전압이 떨어질 때 Rising Edge로 감지된다는 점을 이해하면 된다.
PLS bit값이 커질수록, PVD 임계값의 MIN / MAX값이 양쪽으로 커지며 band가 커지게 된다.
PVD와 PDR에는 hysteresis라는 것을 갖는다.
예를 들어, PLS를 0b000으로 설정하면 2.18[V]가 전압 검출 레벨이지만
PDR hysteresis를 100[mV]를 적용시키면 2.18[V]에서 +-50[mV]까지는 모두 2.18[V]로 인식한다.
즉, 2.18[V]를 range로 사용할 수가 있다.
이를 사용하는 이유는, 전기적 특성이 잡음 등의 외적 이유로 항상 일정한 값을 갖지 못한다.
이러한 전기적인 특성이 없다면, 조금만 전압이 변해도 검출과 비검출을 오고가기 때문에 사용할 수가 없기 때문이다.
결론 : hysteresis는 경계값이 아닌, 경계 범위를 설정하는 것이다.
ON과 OFF를 반복시 위험한 Application의 경우 항상 이를 설정하여 사용해주어야한다.
이는, GPIO pin에도 TTL Schmitt trigger라는 이름으로 High/Low를 구분해주는 것이 있다. 이 또한 hysteresis에 해당한다.
- STM32F446RE의 전력 모드
전력 모드는 시리즈마다 다르므로, MCU에 따라 따로 확인을 해야한다.
특히나 저전력 시리즈인 L 시리즈는 F시리즈보다 많은 mode를 보유하고 있다.
Run mode :
Reset 이후 MCU의 default mode
Low Power mode :
2-1. Sleep mode : CPU clock 정지, 주변 장치는 동작
Interrupt/event 발생시 CPU wake-up 가능, 저전력 모드중 가장 전력 소비가 큼
2-2. Stop mode : All clock 정지(HSI/HSE RC 오실레이터 비활성화), SRAM, 레지스터 Data값은 유지
마찬가지로 EXTI에서 Interrupt 발생 시, CPU wake-up 가능
2-3. Standby mode : All clock 정지, BKP관련 제외 모든 Data 지워짐
NRST나, wake up pin에서 rising edge 발생, RTC events, IWDG reset등에 의해 빠져나옴
관련 내용 : https://controllerstech.com/low-power-modes-in-stm32/
중요한 것은 전력 소모를 줄이기 위해, 사용하지 않는 pin들은 모두 analog pin(GPIO_Analog)로 바꿔야 한다는 점. CubeMX의 Project Manager -> Code Generator options에서 HAL Settings의
"Set all free pins as analog(to optimize the power consumption)"을 check해주면 자동 설정이 가능하다.
- Clock 설정
SYSCLK(system clock)은 3가지 clock source중 1개로 구동된다.
HSI(High Speed Internal) : HSI 내부 8[MHz] RC 오실레이터 clock
system reset 이후 기본적으로 선택됨. 내부 RC 오실레이터를 사용하여 정확도가 떨어짐
즉, 온도가 높으면 정밀도가 떨어진다는 것
HSE(High Speed External) : MCU 외부에서 4[MHz] ~ 32[MHz] clock을 오실레이터, 크리스털 소자를 이용해 공급. 정확도가 높아 RTC나 UART같이 정확한 타이밍이 필요한 경우 사용
PLL(Phased Locked Loop) : PLL을 이용해 HSI or HSE clock의 입력으로 사용
출력신호와 입력신호를 동기화하는 회로로, 주로 주파수 합성, clock 생성, 모터 속도 제어 등에 사용
다음은 부가적인 source들이다.
LSI(Low Speed Internal) RC clock : 40[KHz]로, watchdog 구성과, Stop 및 Standby mode로 부터 Auto-wake up을 위해 사용하는 RTC를 구동
LSE(Low Speed External) : 32.768[kHZ]로, 선택적으로 RTCCLK을 구동. 외부 크리스털과 같은 소자에서 공급됨.
모든 clock source들은 전력 소비를 줄이기 위해 각각 ON/OFF 시킬 수 있으며, 몇가지 예외 사항을 제외하면 All 주변장치를 위한 clock은 연결된 bus clock(HCLK, PCLK1, PCLK2)로부터 만들어진다.
정리하자면 :
1️⃣ SYSCLK (System Clock, 시스템 클럭)
MCU의 기본 클럭 소스
HSE(외부 클럭, 크리스탈), HSI(내부 RC 오실레이터), PLL 중 하나를 선택 가능
CPU와 모든 버스의 기본이 되는 클럭
2️⃣ HCLK (AHB Clock, High-speed Clock)
고속 버스(AHB, Advanced High-performance Bus) 클럭
CPU, RAM, Flash 메모리, DMA, GPIO, Cortex-M 코어 등의 속도를 결정
SYSCLK을 분주(Divider)하여 설정 가능
HCLK = SYSCLK / AHB Prescaler
3️⃣ PCLK1 (APB1 Peripheral Clock, 저속 버스 클럭)
APB1(Advanced Peripheral Bus 1) 클럭
타이머(TIM2TIM7), UART25, I2C, SPI2~3, CAN 등의 동작 속도를 결정
HCLK을 분주하여 설정 가능
PCLK1 = HCLK / APB1 Prescaler
APB1 타이머(TIM2~7)는 추가로 ×2 배율 적용
4️⃣ PCLK2 (APB2 Peripheral Clock, 고속 버스 클럭)
APB2(Advanced Peripheral Bus 2) 클럭
타이머(TIM1, TIM8), UART1, SPI1, ADC, GPIO 고속 포트 등의 속도를 결정
HCLK을 분주하여 설정 가능
PCLK2 = HCLK / APB2 Prescaler
APB2 타이머(TIM1, TIM8)는 추가로 ×2 배율 적용
HCLK는 AHB 버스 속도를 결정하며, SYSCLK을 기반으로 분주(Divider)하여 설정
PCLK1(APB1), PCLK2(APB2)는 HCLK을 기반으로 설정
APB 타이머(TIMx)들은 APB 클럭이 2배로 동작
주 목적은 clock speed를 낮춰 원하는 TIM설정을 하거나,
ex) SYSCLK이 100[MHz]인 경우, Prescaler를 통해 1[MHz]로 낮춰 TIM CLK을 원하는 주파수로 입력해 사용가능.
주변 장치가 원하는 특정 clock speed를 맞춰주기 위해 사용된다.
ex) UART의 115200bps와 SPI, I2C의 Protocol 규격 등을 맞추기위해
Flash memory programming interface clock(FLITFCLK)은 항상 HSI clock을 사용한다.
option byte loader clock은 항상 HSI clock
ADC clock은 PLL로부터 생성됨. 72[MHz]까지 도달가능하며, 이를 1,2,4,6,8,10,12,16,32,64,128,256으로 분주하여 사용 가능
USART는 SW에 의해 SYSCLK / HSI / LSE / APB1 / APB2 중 하나로 선택되어 사용
하지만, 일반적으로 Tx, Rx port만 사용할 뿐, clock을 사용하는 경우는 거의 없음
I2C clock은 SYSCLK / HSI 중 택1
RTC clock은 LSE / LSI나 32로 분주된 HSE로 만들어짐
IWDG(Watch Dog) clock은 항상 LSI
CubeMX의 Clock Tree를 통해 누가 해당 소자의 clock을 공급하는지 확인 가능하다.
Cortex Core의 경우 AHB / APB를 통해 Core 주변 소자나 논리회로에 연결된다.
RCC(Reset and Clock Control)은 AHB clock인 HCLK를 8로 나눈 clock으로,
(Cortex system timer)SYSTICK의 외부 clock을 공급함. 이는 HCLK를 바로 쓸 수도 있음.
CSS(Core Security System)이 활성화되고, HSE clock fail시, CSS Interrupt가 발생해
NMI가 자동 발생해, ISR이 RCC_CIR register내의 CSSC bit를 이용해 CSS Interrupt를 clear 해주어야 한다.
만약, HSE OSC가 SYSCLK로 사용되는 동안 fail이 검출되면, 자동으로 HSI OSC로 전환되고 HSE는 비활성화 된다.
clock 정리
1️⃣ HSI clock :
외부 clock이 없는 경우, 내부 8[MHz] RC OSC로부터 생성됨.
HSE 크리스털 OSC보다 빠른 startup time을 가지지만, 고온에서 정밀도가 낮음.
25도 이상에서 동작시 외부에 크리스털을 붙여 사용하는 것이 낫다.
즉, HSE 실패시 대안으로 쓸 source로 쓰는 것이 일반적이다.
2️⃣ PLL :
PLL의 출력 주파수는 16~72[MHz] 범위 내에 있어야함.
일반적으로 Clock Configuration tab에서 설정해주면 된다.
3️⃣ LSE clock :
32.768[kHz]를 가져야 하며,
RTC를 위해 매우 정확한 clock source를 제공해야 함.
RTC를 사용하지 않는다면, 사용하지 않는 것이 좋다.
만약 외부에서 정확히 이를 제공 가능하다면, RCC_OSC32_IN에 연결하고, OUT은 NC처리 해주면 된다.
단, BYPASS Clock Source를 선택해야함.
단, 크리스털이나 세라믹 레조네이터를 사용할 경우에는 OSC32_IN/OUT을 둘다 사용해야한다.
4️⃣ LSI clock :
Stop, Standby mode에서 독립적인 watchdog(IWDG)와 RTC가 계속 동작할 수 있도록 저전력 clock source로 사용됨.
5️⃣ ADC clock :
최대 72[MHz]까지 도달, 분주 가능
6️⃣ RTC clock :
HSE/32 LSE LSI중 어느 하나
RCC_BDCR, RTCSEL bit field에 의해 선택됨.
이 선택은 RTC domain reset이 있어야 수정이 가능한데, LSE만 RTC domain에 속함.
그러므로,
RTC clock = LSE :
VDD 끊겨도 VBAT 공급시 RTC는 계속 동작가능. 즉 system reset상황에서도 clock이 공급되고, 정상 동작한다는 얘기
RTC clock = LSI :
VDD가 끊기면 RTC 상태 보장 안됨.
RTC clock = HSE/32 :
VDD 끊기거나 내부 전압 레귤레이터가 끊기면, RTC 상태 보장 안됨.
즉, 안정적으로 사용하기 위해선 LSE를 채택하는게 좋겠다.