그라운드 임베디드 EN 유튜브 구독

노트 / MCU 펌웨어

타이머: 정확한 주기와 시간 재기

타이머는 클럭을 세는 카운터입니다. 주기 인터럽트, 입력 캡처로 펄스 폭 재기, 엔코더 모드까지.

GROUND EMBEDDED · 정리 노트펌웨어 05타이머 1카운터 클럭 = 타이머 클럭 / (PSC + 1) 2이벤트 주기 = (PSC + 1) × (ARR + 1) / 타이머 클럭

기본 동작

타이머 클럭PSC÷ (PSC + 1)CNT0 → ARR 까지 셈업데이트 이벤트인터럽트, 트리거
타이머는 나눈 클럭을 세다가 ARR에 닿으면 0으로 돌아가며 이벤트를 냅니다.

타이머 입력 클럭 → PSC(프리스케일러)로 나눔 → CNT가 1씩 증가 → ARR에 도달하면 0으로 돌아가며 업데이트 이벤트

주기 = (PSC + 1) × (ARR + 1) / 타이머 클럭

100MHz 타이머로 1kHz 인터럽트: PSC = 99 (1MHz), ARR = 999 → 1ms

쓰임

모드 용도
업데이트 인터럽트 정확한 제어 주기 (1kHz 속도 루프)
출력 비교 / PWM 모터, LED 밝기
입력 캡처 펄스 폭, 주파수 측정 (서보 신호, 초음파 센서)
엔코더 모드 A/B상 신호로 위치 자동 카운트
트리거 출력 (TRGO) ADC 샘플링 시점 지정

입력 캡처로 시간 재기

신호 에지가 들어오는 순간 CNT 값이 CCR에 자동 저장됩니다. 상승 에지와 하강 에지의 CCR 차이가 펄스 폭입니다. 소프트웨어로 재는 것보다 지터가 없습니다.

HAL_Delay와의 차이

HAL_Delay는 SysTick을 기다리며 CPU를 묶어 둡니다. 주기적인 일은 타이머 인터럽트나 RTOS 태스크로 돌려야 다른 일을 동시에 할 수 있습니다.

타이머는 숫자를 세는 카운터다

클럭이 들어올 때마다 카운터가 1씩 올라가고, 정해 둔 값(ARR)에 닿으면 0으로 돌아가면서 업데이트 이벤트를 냅니다. 프리스케일러(PSC)는 클럭을 먼저 나눠 카운터가 느리게 세도록 합니다.

카운터 클럭 = 타이머 클럭 / (PSC + 1)
이벤트 주기 = (PSC + 1) × (ARR + 1) / 타이머 클럭
3D 실험실여기까지 읽은 내용을 직접 돌려 볼 수 있습니다→

예제: 1 ms 주기 만들기

타이머 클럭이 72 MHz일 때

PSC = 71    →  72 MHz / 72 = 1 MHz   (1 카운트 = 1 μs)
ARR = 999   →  1000 카운트마다 이벤트 = 1 ms
TIM2->PSC  = 71;
TIM2->ARR  = 999;
TIM2->DIER |= TIM_DIER_UIE;      // 업데이트 인터럽트 허용
TIM2->CR1  |= TIM_CR1_CEN;       // 시작
NVIC_EnableIRQ(TIM2_IRQn);

+ 1을 빼먹어 PSC에 72, ARR에 1000을 쓰면 주기가 약 1.5% 길어집니다. 통신 타이밍이나 제어 주기에서는 무시할 수 없는 오차입니다.

그림으로 보기: 카운터와 PWM

PWM 출력업데이트0123456701234567
카운터가 비교값(CCR)보다 작은 동안 출력이 HIGH입니다. CCR을 바꾸면 듀티비가 바뀝니다.

같은 타이머가 설정에 따라 네 가지 일을 합니다.

모드 하는 일 쓰임
기본 타이머 일정 주기로 인터럽트 시스템 틱, 제어 루프
출력 비교 / PWM 카운터와 비교해 핀 출력 모터, LED 밝기, 서보
입력 캡처 핀이 변한 순간의 카운터 값 저장 주파수·펄스 폭 측정, 홀센서
엔코더 모드 A/B 상 신호로 카운터 증감 회전 위치

16비트의 한계

16비트 타이머는 65535까지만 셉니다. 1 μs 단위로 세면 65.5 ms에서 넘칩니다. 더 긴 시간을 재려면 PSC를 키워 단위를 늘리거나, 넘침 인터럽트에서 상위 자리를 따로 세어 이어 붙입니다. 입력 캡처로 두 시각의 차이를 구할 때는 (uint16_t)(now - prev)처럼 부호 없는 뺄셈을 쓰면 넘침이 한 번 있어도 올바른 값이 나옵니다.

현업에서 자주 터지는 문제

  • 타이머 클럭이 예상의 두 배: 버스 분주비가 1이 아닐 때 타이머 클럭만 두 배가 되는 MCU가 많습니다. 주기가 절반으로 나오면 클럭 트리를 확인합니다.
  • ARR을 바꿨는데 바로 반영되어 펄스가 깨짐: 프리로드를 켜 두면 다음 업데이트 시점에 한꺼번에 바뀝니다.
  • 인터럽트 플래그를 지우지 않음: 핸들러가 끝나자마자 다시 불려 메인 루프가 멈춥니다.
3D 실험실에서 직접 돌려 보기값을 바꾸며 이 노트의 원리를 확인합니다→영상으로 이어 보기회로와 하드웨어 시리즈 8편전자제품 속 회로 소자는 어떻게 동작할까? · 저항 · 커패시터 · 인덕터 완벽 정리PROJECT COURSE레지스터 설정을 실제 보드에서 해 보고 싶다면밸런싱 로봇 하나를 요구사항, 회로와 PCB, 펌웨어, 앱까지 실무 순서대로 만드는 강의입니다. 10파트 165강.강의 살펴보기 →FREE PDF무료 전자책 3권 받기이 주제를 한 권으로 이어서 읽고 싶다면. BLDC 모터 제어, 직렬통신, 센서를 책 분량으로 묶었습니다. 이메일만 남기면 바로 받습니다.무료로 받기 →