nrfx - PWM (LED breathe)

모코코개발자·2025년 1월 24일

nrfx

목록 보기
2/3
post-thumbnail

PWM (Pulse Width Modulation) : 펄스 폭 변조

PWM은 전기 신호의 펄스 폭을 조절하여 출력의 평균 전압을 변경하는 기술

디지털 신호를 통해 아날로그 출력처럼 보이는 결과를 얻기 위해 사용

주요 개념

  • 펄스 폭 : 신호가 "켜짐" 상태에 있는 시간과 "꺼짐" 상태에 있는 시간의 비율

  • 듀티 사이클 (Duty Cycle) : 신호가 "켜짐"(HIGH) 상태에 있는 시간의 비율
    ex) 듀티 사이클이 25%라면, 주기의 25% 동안 신호가 켜져 있고, 나머지 75% 동안 꺼져 있습니다

  • 주파수 (Frequency) : PWM 신호의 반복 주기

사용 사례

  1. 모터 속도 제어

  2. LED 밝기 제어

  3. 온도 제어

실습

헤더 파일 및 로깅 설정

#include <nrfx_example.h>
#include <nrfx_pwm.h>  // PWM(펄스 폭 변조) 제어를 위한 NRFX 드라이버 헤더
#define NRFX_LOG_MODULE EXAMPLE // 로깅 모듈 이름 설정
#define NRFX_EXAMPLE_CONFIG_LOG_ENABLED 1 // 로깅 활성화 여부
#define NRFX_EXAMPLE_CONFIG_LOG_LEVEL 3 // 로깅 레벨 설정(3 = 디버그 레벨)

PWM 인스턴스 및 설정 매크로

#define PWM_INST_IDX 0  // 사용할 PWM 인스턴스(여기서는 0번)
#define VALUE_REPEATS 150UL  // 각 듀티 사이클 값의 반복 횟수 (breathe 효과 속도에 영향)
#define NUM_OF_LOOPS 3UL  // 전체 시퀀스가 실행되는 반복 횟수
#define PLAYBACK_COUNT 1UL // 시퀀스를 몇 번 재생할지 설정(1번만 재생)

PWM 듀티 사이클 값 배열

nrf_pwm_values_common_t pwm_val []=
{
    0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000,
    900, 800, 700, 600, 500, 400, 300, 200, 100, 0
};
// LED 밝기 수치에 사용

PWM 이벤트 핸들러

static void pwm_handler(nrfx_pwm_evt_type_t event_type, void * p_context)
{
    nrfx_pwm_t * inst = p_context;
    static uint32_t curr_loop = 1;
	NRFX_LOG_INFO("Loops: %u / %lu", curr_loop, NUM_OF_LOOPS);
if (curr_loop == NUM_OF_LOOPS)
 {
     NRFX_LOG_INFO("PWM finished");
     nrfx_pwm_uninit(inst);
 }
 curr_loop++;
}

현재 반복 횟수를 로그로 출력.
모든 반복(NUM_OF_LOOPS)이 끝나면 PWM을 비활성화(nrfx_pwm_uninit)

메인 함수 시작

 int main(void)
{
    nrfx_err_t status;
    (void)status;
#if defined(__ZEPHYR__)
    IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_PWM_INST_GET(PWM_INST_IDX)), IRQ_PRIO_LOWEST,
                NRFX_PWM_INST_HANDLER_GET(PWM_INST_IDX), 0, 0);
#endif

IRQ_CONNECT: Zephyr 환경에서 PWM 인터럽트 연결

PWM 드라이버 초기화

    nrfx_pwm_t pwm_instance = NRFX_PWM_INSTANCE(PWM_INST_IDX);  // 사용할 PWM 인스턴스
    nrfx_pwm_config_t config = NRFX_PWM_DEFAULT_CONFIG(LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN); // PWM 설정값(LED 핀과 관련된 기본값)
    status = nrfx_pwm_init(&pwm_instance, &config, pwm_handler, &pwm_instance); 
    NRFX_ASSERT(status == NRFX_SUCCESS);
    // PWM 드라이버를 초기화
    // WM 핸들러(pwm_handler)와 인스턴스 포인터(pwm_instance)를 연결

PWM 시퀀스 설정

    nrf_pwm_sequence_t seq = // PWM 시퀀스 설정
    {
        .values = {pwm_val},  // 듀티 사이클 값 배열
        .length = NRFX_ARRAY_SIZE(pwm_val), // 배열의 길이
        .repeats = VALUE_REPEATS, // 각 듀티 사이클 값의 반복 횟수
        .end_delay = 0  // 시퀀스 끝에서 추가 지연 시간
    };

PWM 시퀀스 실행

    nrfx_pwm_simple_playback(&pwm_instance, &seq, PLAYBACK_COUNT, NRFX_PWM_FLAG_LOOP);

nrfx_pwm_simple_playback: PWM 시퀀스를 실행

pwm_instance: 사용할 PWM 인스턴스

seq: 실행할 시퀀스

PLAYBACK_COUNT: 시퀀스를 몇 번 재생할지

NRFX_PWM_FLAG_LOOP: 무한 반복 플래그

무한 루프

    while (1)
    {
        NRFX_EXAMPLE_LOG_PROCESS();  // 무한 루프에서 로그를 처리
    }
}

전체 동작 과정

1. PWM 초기화

  • PWM 드라이버를 초기화하고, 이벤트 핸들러와 연결
  • 사용할 GPIO 핀 설정

2. 시퀀스 설정

  • 듀티 사이클 배열(pwm_val)을 기반으로 LED 밝기 패턴 생성

3. 시퀀스 실행

  • 시퀀스를 반복 재생하며, LED 밝기를 조정

4. 루프 종료

  • 설정된 반복 횟수(NUM_OF_LOOPS)에 도달하면 PWM 비활성화

profile
모코코개발자

0개의 댓글