PWM은 전기 신호의 펄스 폭을 조절하여 출력의 평균 전압을 변경하는 기술
디지털 신호를 통해 아날로그 출력처럼 보이는 결과를 얻기 위해 사용
펄스 폭 : 신호가 "켜짐" 상태에 있는 시간과 "꺼짐" 상태에 있는 시간의 비율
듀티 사이클 (Duty Cycle) : 신호가 "켜짐"(HIGH) 상태에 있는 시간의 비율
ex) 듀티 사이클이 25%라면, 주기의 25% 동안 신호가 켜져 있고, 나머지 75% 동안 꺼져 있습니다
주파수 (Frequency) : PWM 신호의 반복 주기
모터 속도 제어
LED 밝기 제어
온도 제어
#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 = 디버그 레벨)
#define PWM_INST_IDX 0 // 사용할 PWM 인스턴스(여기서는 0번) #define VALUE_REPEATS 150UL // 각 듀티 사이클 값의 반복 횟수 (breathe 효과 속도에 영향) #define NUM_OF_LOOPS 3UL // 전체 시퀀스가 실행되는 반복 횟수 #define PLAYBACK_COUNT 1UL // 시퀀스를 몇 번 재생할지 설정(1번만 재생)
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 밝기 수치에 사용
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 인터럽트 연결
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)를 연결
nrf_pwm_sequence_t seq = // PWM 시퀀스 설정 { .values = {pwm_val}, // 듀티 사이클 값 배열 .length = NRFX_ARRAY_SIZE(pwm_val), // 배열의 길이 .repeats = VALUE_REPEATS, // 각 듀티 사이클 값의 반복 횟수 .end_delay = 0 // 시퀀스 끝에서 추가 지연 시간 };
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 초기화
2. 시퀀스 설정
3. 시퀀스 실행
4. 루프 종료
