FirmGod

타이머 프리스케일러 계산기

목표 주기나 주파수에 맞는 프리스케일러와 리로드 조합을 PWM 해상도 순으로 정렬해 보여 주고, 레지스터 값까지 계산합니다.

The usual general-purpose timer. Both registers store their value minus one.

코어 클럭이 아니라 버스 프리스케일러를 지난 뒤의 값입니다.

클럭:
목표:
프리스케일러2틱 27.78 ns
리로드36,000PWM 15.1 비트
주파수1 kHz정확
주기1 ms

레지스터 값

PSC1divide by 2; the register holds 2 − 1
ARR35999count 36000 ticks; the register holds 36000 − 1

두 레지스터 모두 0부터 세므로, 실제 단계 수보다 1 작은 값을 담습니다. 1을 빼지 않고 단계 수를 그대로 쓰는 것이 몇 분의 1 퍼센트씩 어긋나는 가장 흔한 원인입니다.

PWM 듀티 사이클

리로드가 36,000이면 듀티 사이클은 0.0028% 단위로 움직입니다. 리로드를 크게 잡아서 얻는 것이 이 해상도입니다.

비교 레지스터: 18,00050.0000%가 되고, 500 µs 동안 하이입니다

다른 조합

같은 주파수, 다른 절충입니다. 리로드가 크면 듀티를 더 곱게 조절할 수 있고, 프리스케일러가 크면 틱이 더 떨어지는 값이 되어 같은 타이머로 시간을 재기에 편합니다.

프리스케일러리로드틱PWM 비트오차
236,00027.78 ns15.1정확
324,00041.67 ns14.6정확
418,00055.56 ns14.1정확
514,40069.44 ns13.8정확
612,00083.33 ns13.6정확
89,000111.1 ns13.1정확
98,000125 ns13.0정확
107,200138.9 ns12.8정확
126,000166.7 ns12.6정확
154,800208.3 ns12.2정확
164,500222.2 ns12.1정확
184,000250 ns12.0정확

두 단계로 나눕니다

타이머는 클럭을 두 번 나눕니다. 먼저 프리스케일러가 입력 클럭을 나눠 틱을 만들고, 그다음 카운터가 리로드 값까지 세면 한 주기가 끝납니다.

주기 = (프리스케일러 + 1) × (리로드 + 1) ÷ 타이머 클럭

두 값 모두 1을 더해 계산합니다. 타이머가 0부터 세기 때문입니다. 1000틱을 원하면 리로드에 999를 넣습니다. 이 오프셋을 빼먹으면 주기가 미세하게 어긋나고, 짧은 주기일수록 비율로는 크게 틀립니다.

같은 주기, 다른 조합

곱이 같으면 주기도 같습니다. 프리스케일러 7에 리로드 999나, 프리스케일러 79에 리로드 99나 결과는 동일합니다. 단순 주기 인터럽트라면 아무거나 써도 됩니다.

PWM이라면 다릅니다. 듀티 해상도가 리로드 값으로 정해집니다. 리로드 999는 1,000단계, 99는 100단계입니다. 같은 주파수의 PWM인데 한쪽은 0.1% 단위로, 다른 쪽은 1% 단위로만 조절됩니다.

그래서 이 계산기는 후보를 해상도 순으로 정렬합니다. 프리스케일러를 작게, 리로드를 크게 잡는 조합이 위에 옵니다.

타이머 클럭을 잘못 넣는 실수

코어 클럭을 그대로 넣는 경우가 많은데 대개 다릅니다. 타이머는 주변장치 버스에 붙어 있고 그 버스에는 별도의 분주가 걸립니다.

STM32에는 더 헷갈리는 규칙이 있습니다 — APB 프리스케일러가 1이 아니면 타이머 클럭이 버스 클럭의 두 배가 됩니다. 72MHz 코어에 APB1이 2분주면 버스는 36MHz인데 타이머는 72MHz입니다. 레퍼런스 매뉴얼의 클럭 트리를 확인하고 넣으세요.

16비트의 한계

16비트 타이머의 리로드 상한은 65535입니다. 72MHz 클럭에서 1초 주기를 만들려면 곱이 72,000,000이 되어야 하는데, 리로드를 최대로 써도 프리스케일러가 1099 이상 필요합니다.

그 자체는 문제가 아니지만 PWM을 함께 쓴다면 선택지가 줄어듭니다. 긴 주기와 높은 해상도를 동시에 원한다면 32비트 타이머를 쓰는 편이 간단합니다.

오차를 0으로 만들 수 있는 경우

클럭과 목표 주기의 비가 두 정수의 곱으로 떨어지면 오차가 0입니다. 떨어지지 않으면 가장 가까운 조합을 고를 수밖에 없습니다.

목표 주기를 조금 움직일 수 있다면 오차 0인 값으로 맞추세요. 통신 타이밍처럼 정확한 주기가 요구되는 경우가 아니면 대개 가능합니다. UART 보율도 같은 성격의 문제이고 UART 보율 계산기가 같은 방식으로 다룹니다.

자주 묻는 질문

같은 주기를 만드는 조합이 여러 개인데 무엇을 골라야 하나요?

PWM을 쓴다면 리로드 값이 큰 쪽을 고르세요. 듀티 해상도가 리로드 값에 비례합니다. 리로드가 999면 1,000단계, 99면 100단계입니다. PWM을 쓰지 않는 단순 주기 인터럽트라면 어느 조합이든 같습니다. 이 계산기가 해상도 순으로 정렬해 보여 주는 이유입니다.

왜 리로드 값에 1을 빼나요?

타이머가 0부터 세기 때문입니다. 1000틱마다 인터럽트를 원하면 리로드에 999를 넣습니다. 0부터 999까지가 1000개입니다. 프리스케일러도 같아서, 클럭을 8로 나누려면 7을 넣습니다. 이 오프셋을 빼먹는 것이 주기가 미세하게 어긋나는 흔한 원인입니다.

오차가 0인 조합이 없습니다.

클럭과 목표 주기의 비가 정수로 떨어지지 않는 경우입니다. 프리스케일러와 리로드 둘 다 정수라 만들 수 있는 주기가 듬성듬성합니다. 목표를 조금 조정할 수 있다면 오차 0인 값으로 맞추는 편이 낫고, 정확한 주기가 꼭 필요하다면 타이머 클럭 자체를 바꿔야 합니다.

타이머 클럭이 코어 클럭과 다른가요?

대개 다릅니다. 타이머는 버스에 붙어 있고 그 버스에 별도의 분주가 걸립니다. STM32에서는 APB 프리스케일러가 1이 아니면 타이머 클럭이 버스 클럭의 두 배가 되는 규칙까지 있어 특히 헷갈립니다. 레퍼런스 매뉴얼의 클럭 트리에서 확인한 값을 넣으세요.

16비트와 32비트 타이머 중 무엇을 쓰나요?

긴 주기나 높은 해상도가 필요하면 32비트입니다. 16비트 타이머의 리로드 상한은 65535라, 느린 주기를 만들려면 프리스케일러를 크게 잡아야 하고 그만큼 PWM 해상도가 떨어집니다. 32비트 타이머는 프리스케일러를 1로 두고도 긴 주기를 만들 수 있어 해상도가 유지됩니다.