본문 바로가기
Embedded/nRF52 BLE 개발 안내서

nRF52 BLE 개발하기 - low_power_pwm

by 큐찡 2021. 2. 4.
728x90
반응형

시작하기

Low-Power PWM 라이브러리를 사용해서 PWM 신호를 생성해서 출력하는 방법에 대해서 알아보도록 하자.

먼저 \examples\peripheral\low_power_pwm\pca10040\blank\ses 폴더에서 프로젝트를 실행한다.

여기서는 노르딕에서 제공하는 예제의 main.c 소스코드를 약간 수정해서 이해하기 쉽게 설명을 하고자 한다.

static low_power_pwm_t low_power_pwm_0;

/**
 * @brief Function to initalize low_power_pwm instances.
 *
 */

static void pwm_init(void)
{
    uint32_t err_code;
    low_power_pwm_config_t low_power_pwm_config;

    APP_TIMER_DEF(lpp_timer_0);
    low_power_pwm_config.active_high    = false;
    low_power_pwm_config.period         = 220;
    low_power_pwm_config.bit_mask       = BSP_LED_0_MASK;
    low_power_pwm_config.p_timer_id     = &lpp_timer_0;
    low_power_pwm_config.p_port         = NRF_GPIO;

    err_code = low_power_pwm_init((&low_power_pwm_0), &low_power_pwm_config, pwm_handler);
    APP_ERROR_CHECK(err_code);
    err_code = low_power_pwm_duty_set(&low_power_pwm_0, 0);
    APP_ERROR_CHECK(err_code);

    err_code = low_power_pwm_start((&low_power_pwm_0), low_power_pwm_0.bit_mask);
    APP_ERROR_CHECK(err_code);
}

static void lfclk_init(void)
{
    uint32_t err_code;
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);
}

/**
 * @brief Function for application main entry.
 */
int main(void)
{
    uint8_t new_duty_cycle;
    uint32_t err_code;

    lfclk_init();

    // Start APP_TIMER to generate timeouts.
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    /*Initialize low power PWM for all 3  channels of RGB or 3 channels of leds on pca10028*/
    pwm_init();

    while (true)
    {
    
    }
}

그럼 바로 pwm_init 함수를 살펴보도록 하자.

APP_TIMER_DEF(lpp_timer_0) 호출해 app timer 사용할 수 있도록 선언하고 low_power_pwm_config 변수에 low power pwm 설정을 한다.

nRF52 DK의 LED가 Active Low로 회로가 구성되어 있으므로 active_high는 false값으로 한다.

period는 PWM 신호의 주기로 0~255의 범위로 설정 가능하며 주기 값이 작으면 신호의 폭이 짧아지고 주기 값이 크면 신호의 폭이 길어진다.

bit_mask에 PWM 신호를 출력할 GPIO 마스크 값을 넣어준다.

p_timer_id에 위에서 선언한 app timer를 넣어준다.

p_port에는 GPIO 포트를 넣어주는데 nRF52 DK에는 P0 포트만 있어 수정할 일은 없다.

low_power_pwm_init 함수의 전달 인자로 PWM 설정, 이벤트 핸들러 함수를 넣어주면 기본적인 PWM 설정이 끝난다.

low_power_pwm_duty_set 함수는 PWM 신호의 듀티를 설정하며 0~255의 범위로 설정 가능하다.

여기서는 0 값을 설정해 PWM 신호의 출력이 없는 상태로 초기 상태를 만들어 주었다.

low_power_pwm_start 함수의 전달 인자로 PWM 신호를 출력할 GPIO 마스크를 넣어주면 해당 GPIO에 PWM 신호를 출력하기 시작한다.

static uint8_t pwm_0_duty_cycle = 0;
/**
 * @brief Function to be called in timer interrupt.
 *
 * @param[in] p_context     General purpose pointer (unused).
 */
static void pwm_handler(void * p_context)
{
    static uint16_t led_0;
    uint32_t err_code;
    UNUSED_PARAMETER(p_context);

    low_power_pwm_t * pwm_instance = (low_power_pwm_t*)p_context;
    if (pwm_instance->bit_mask == BSP_LED_0_MASK)
    {
        led_0++;

        if (led_0 > 10)
        {
            if(pwm_0_duty_cycle == pwm_instance->period) pwm_0_duty_cycle = 0;
            else                   pwm_0_duty_cycle = pwm_0_duty_cycle + 10;
            err_code = low_power_pwm_duty_set(pwm_instance, pwm_0_duty_cycle);
            APP_ERROR_CHECK(err_code);

            led_0 = 0;
        }
    }
}

app timer에 의해 호출되는 이벤트 핸들러인 pwm_handler 함수는 일정 시간마다 PWM 신호의 듀티를 10씩 증가시키다가 PWM 신호의 주기 값에 도달하면 0 값으로 설정하며 이 동작을 반복한다.

이제 nRF52 DK에 펌웨어를 다운로드하고 어떻게 동작하는지 살펴보도록 하자.

사진의 왼쪽은 period 값이 220이고 오른쪽은 period 값이 110일 때의 PWM 신호 출력이다.

 

728x90
반응형

댓글