본문 바로가기
하만 세미콘 아카데미/Embedded (STM32)

[Embedded] STM32 - Timer

by smileww 2024. 5. 31.

이번에는 PWM을 사용하여 LED의 밝기를 서서히 올리는 코드를 작성해보도록 하겠습니다.

 

PWM(Pulse Width Modulation, 펄스 폭 변조)은 아날로그 신호를 디지털 출력으로 흉내 내는 기법으로, 전자제어에서 널리 사용됩니다. STM32와 같은 마이크로컨트롤러에서 PWM은 LED 밝기 조절, 모터 속도 제어 등에 활용됩니다.

PWM의 기본 원리

  • 듀티 사이클(Duty Cycle): PWM 신호는 "HIGH"와 "LOW" 상태의 반복으로 구성되며, 듀티 사이클은 신호가 HIGH 상태를 유지하는 시간의 비율을 의미합니다. 예를 들어, 듀티 사이클이 50%인 경우, 신호는 절반의 시간 동안 HIGH 상태이고 나머지 절반은 LOW 상태입니다.
  • 주파수(Frequency): PWM 신호의 주파수는 신호가 얼마나 빨리 반복되는지를 나타냅니다. 주파수가 높을수록 신호의 변화가 빠르며, 일반적으로 이는 더 부드러운 제어를 가능하게 합니다.

STM32에서 PWM 사용

  1. 타이머 설정: STM32는 내장된 타이머를 사용하여 PWM 신호를 생성합니다. 타이머는 PWM의 주파수와 듀티 사이클을 정밀하게 제어할 수 있게 해줍니다.
  2. 채널 설정: 대부분의 STM32 타이머는 여러 PWM 출력 채널을 지원합니다. 각 채널은 독립적으로 듀티 사이클을 설정할 수 있어 다양한 출력을 제어할 수 있습니다.
  3. 출력 설정: PWM 신호는 STM32의 특정 핀을 통해 출력됩니다. 이 핀은 마이크로컨트롤러의 설정을 통해 PWM 출력으로 구성되어야 합니다.
  4. 소프트웨어 설정: STM32CubeIDE와 같은 개발 환경을 사용하여 PWM 관련 설정을 구성할 수 있습니다. 이는 타이머의 설정, PWM 채널의 활성화, 듀티 사이클의 초기값 설정 등을 포함합니다.

PWM을 사용하는 가장 큰 장점은 디지털 제어를 통해 매우 안정적이고 정밀한 아날로그 수준의 결과를 얻을 수 있다는 것입니다. 예를 들어, LED의 경우 PWM을 사용하면 섬세한 밝기 조절이 가능하고, 모터 제어에서는 원하는 속도로 정확하게 모터를 제어할 수 있습니다.

 

 

 

우선 타이머를 활성화 시켜줍니다. 저는 Timer1의 2채널을 사용하도록 하겠습니다.

 

 

 

Parameter Settings에서 각 설정에 대한 설명을 드리겠습니다.

 

Prescaler (분주기)

  • 목적: 타이머의 입력 클록 속도를 조절합니다. 이는 타이머 카운터가 증가하는 속도를 늦추기 위해 사용됩니다.
  • 계산: 시스템 클록이 84MHz일 때, 840으로 분주하면 타이머 클록은 84MHz / 840 = 100,000Hz 또는 100kHz로 줄어듭니다.

ARR (Auto-Reload Register)

  • 목적: 타이머의 최대 카운트 값을 설정합니다. 이 값에 도달하면 타이머는 0으로 리셋되고, 필요한 경우 인터럽트를 발생시킵니다.
  • 설정: ARR을 100으로 설정하면 타이머는 0부터 100까지 카운트한 후 리셋됩니다.

타이머 주기 계산:

  • 주파수가 100kHz이고, 타이머가 100까지 카운트하면, 한 사이클을 완료하는 데 필요한 시간은 1 / 100,000Hz * 100 = 0.001초 또는 1ms가 됩니다. 이는 타이머가 1ms마다 한 번씩 오버플로우하거나 인터럽트를 발생시킬 수 있음을 의미합니다.

결과적으로, 이 설정을 통해 타이머는 매 1밀리초마다 리셋되며, 이를 활용하여 정확한 시간 간격으로 특정 작업을 수행하거나 이벤트를 처리할 수 있습니다. 이러한 방식으로, 예를 들어 PWM 신호의 주기를 제어하거나, 시간 기반의 작업을 정밀하게 스케줄링할 수 있습니다.

 

그 다음 PWM 모드를 설정해줍니다.

 

Mode: PWM mode 1

  • PWM mode 1은 타이머의 카운터 값이 캡처/비교 레지스터(CCR)의 값보다 작거나 같을 때 출력을 HIGH로 설정합니다. 카운터 값이 CCR을 초과하면 LOW로 설정됩니다. 이 모드는 가장 일반적인 PWM 신호 생성 방식으로 사용됩니다.

Pulse (16 bits value): 0

  • 이 값은 캡처/비교 레지스터(CCR)에 설정됩니다. PWM의 듀티 사이클을 결정하는 데 사용됩니다. 여기서 0으로 설정된 경우, 출력은 항상 LOW 상태를 유지할 것입니다(듀티 사이클 0%).

Output compare preload: Enable

  • 출력 비교 프리로드를 활성화하면, CCR 레지스터에 새로운 값이 쓰여질 때 즉시 값이 업데이트되지 않고, 현재 사이클이 끝날 때까지 기다린 후 다음 사이클에서 적용됩니다. 이는 PWM 듀티 사이클을 변경할 때 발생할 수 있는 불규칙성을 방지하여 더 안정적인 출력을 보장합니다.

Fast Mode: Disable

  • 빠른 모드가 비활성화되어 있습니다. 빠른 모드를 사용하면 PWM의 응답 시간이 향상되지만, 여기서는 필요하지 않은 것으로 설정되어 있습니다.

CH Polarity: High

  • 채널의 극성이 High로 설정되어 있습니다. 이는 PWM 출력이 "비활성" 상태일 때 LOW이고, "활성" 상태(즉, CCR 값 이하일 때)일 때 HIGH가 되도록 설정됩니다.

CH Idle State: Reset

  • 채널의 아이들(대기) 상태가 Reset으로 설정됩니다. 이는 PWM 출력이 비활성 상태일 때 LOW 상태가 되도록 설정됩니다.

이 설정들은 주로 PWM 출력의 동작 방식을 정의하며, 사용자가 원하는 특정 어플리케이션 요구 사항에 맞춰 조절됩니다. 예를 들어 LED 밝기 조절 또는 모터 속도 제어 등에 활용됩니다. 듀티 사이클이 0%로 설정된 현재 상태에서는 실제로 PWM 출력에서 변화를 보기 위해서는 Pulse 값을 조정해야 할 것입니다.

 

설정이 모두 완료되었으면 Generation을 눌러줍니다.

 

 

 

 

 

 

유저 코드 영역에서 동작에 필요한 코드를 작성해줍니다. 

 

함수 CCR_OP()

  • 이 함수는 op 변수의 값을 증가시키고, 이 값이 100을 초과하면 0으로 재설정합니다.
  • 증가된 op 값을 화면상의 특정 위치에 출력합니다. 출력 형식은 ANSI 이스케이프 코드를 사용하여 터미널 커서를 (y, x) 위치로 이동시킨 후, 현재 CCR 값을 출력합니다.

함수 HAL_TIM_PeriodElapsedCallback()

  • HAL_TIM_PeriodElapsedCallback()는 타이머 인터럽트 서비스 루틴으로, 타이머 주기가 완료될 때마다 호출됩니다.
  • 이 함수 내에서 htim 파라미터를 확인하여, 이 인터럽트가 htim2에 의해 발생했는지 확인합니다.
  • htim2의 주기가 끝날 때마다 CCR_OP() 함수를 호출하여 op 값을 업데이트하고 터미널에 출력합니다.
  • 주석 처리된 코드는 TIM2가 종료될 때마다 메시지를 출력하고, count2 변수를 증가시키는 부분입니다. (printf("Timer2 elapsed...%d...Press B1 to continue\r\n", count2++);)

함수 HAL_GPIO_EXTI_Callback()

  • 이 함수는 GPIO 외부 인터럽트 서비스 루틴으로, 설정된 GPIO 핀의 상태 변화(예: 버튼 누름)를 감지할 때 호출됩니다.
  • GPIO 인터럽트가 발생하면 CCR_OP() 함수를 호출하여 op 값을 업데이트하고 터미널에 출력합니다.

 

종합적으로 타이머 인터럽트를 사용하여 주기적으로 op 값을 변경하고 이를 터미널에 출력하는 방식으로 PWM 신호의 비율을 시각적으로 나타내고 GPIO 인터럽트를 통해 사용자 상호작용에 반응하여 동일한 값을 업데이트합니다.

 

빌드 후 오류가 없으면 보드와 연결후 run을 눌러줍니다.

 

 

 

 

 

 

 

 

'하만 세미콘 아카데미 > Embedded (STM32)' 카테고리의 다른 글

[Embedded] STM32 - US Interrupt  (0) 2024.05.31
[Embedded] STM32 - US GPIO  (0) 2024.05.31
[Embedded] STM32 - PWM  (0) 2024.05.31
[Embedded] STM32CubeIDE GPIO - LED 점멸  (0) 2024.05.31
STM32_Cube_IDE 설치 방법  (0) 2024.05.31