시작하기
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 신호 출력이다.
'Embedded > nRF52 BLE 개발 안내서' 카테고리의 다른 글
nRF52 BLE 개발하기 - saadc (0) | 2021.02.17 |
---|---|
nRF52 BLE 개발하기 - pwm_driver (4) | 2021.02.07 |
nRF52 BLE 개발하기 - nRF Sniffer (0) | 2021.02.02 |
nRF52 BLE 개발하기 - ble_app_uart with buttonless dfu (1) | 2021.01.31 |
nRF52 BLE 개발하기 - ble_app_buttonless_dfu (2) | 2021.01.29 |
댓글