시작하기
\examples\peripheral\timer\pca10040\blank\ses 폴더에서 바로 타이머 예제 프로젝트를 실행시켜보자.
그리고 노르딕 인포센터 링크에 접속하여 예제에 대한 내용을 확인하자.
blinky 예제에서 시간 지연으로 사용했던 nrf_delay_ms 함수보다 더 정확한 하드웨어 기반 시간 지연이라고 한다.
500ms마다 LED 상태가 순차적으로 변경되는 매우 간단한 예제이다.
const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);
/**
* @brief Handler for timer events.
*/
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
static uint32_t i;
uint32_t led_to_invert = ((i++) % LEDS_NUMBER);
switch (event_type)
{
case NRF_TIMER_EVENT_COMPARE0:
bsp_board_led_invert(led_to_invert);
break;
default:
//Do nothing.
break;
}
}
/**
* @brief Function for main application entry.
*/
int main(void)
{
uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
uint32_t time_ticks;
uint32_t err_code = NRF_SUCCESS;
//Configure all leds on board.
bsp_board_init(BSP_INIT_LEDS);
//Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
APP_ERROR_CHECK(err_code);
time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);
nrf_drv_timer_extended_compare(
&TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
nrf_drv_timer_enable(&TIMER_LED);
while (1)
{
__WFI();
}
}
main 함수를 살펴보면 크게 LED 출력을 위한 GPIO 설정과 타이머 설정으로 나눌 수 있다.
blinky 예제에서 다뤘던 bsp_board_init 함수에 대해선 생략하고 바로 타이머 설정에 대해서 알아보자.
nrf_drv_timer_init 함수에 사용할 타이머(Timer 0)와 설정값(NRF_DRV_TIMER_DEFAULT_CONFIG), 이벤트 핸들러(timer_led_event_handler)를 전달 인자로 넘겨 설정한다.
NRF_DRV_TIMER_DEFAULT_CONFIG는 NRF_TIMER_FREQ_16MHz, NRF_TIMER_MODE_TIMER, NRF_TIMER_BIT_WIDTH_32, 인터럽트 우선순위 6의 값을 가지고 있다.
nrf_drv_timer_ms_to_ticks 함수를 통해 Timer 0가 500ms에 대한 time_ticks값을 반환받는다.
nrf_drv_timer_extended_compare 함수에 Timer 0, Timer CC channel 0, time_ticks, Shortcut register에 COMPARE0_CLEAR_MASK를 전달 인자로 넘겨 설정한다.
마지막으로 nrf_drv_timer_enable 함수로 Timer 0를 활성화한다.
이렇게 500ms마다 timer_led_event_handler 함수가 호출되는 타이머가 실행된다.
타이머 설정에 관한 자세한 내용은 데이터시트 234페이지부터 나와있다.
위 소스코드를 응용하여 타이머를 4개 사용하여 4개의 LED를 각각 다른 시간 지연을 가지며 반짝이게 해 보도록 하자.
먼저 Timer 0, 1, 2, 3을 사용하기 위해 sdk_config.h 파일에서 다음과 같이 설정을 변경해야 사용할 수 있다.
/* sdk_config.h */
// <q> TIMER0_ENABLED - Enable TIMER0 instance
#ifndef TIMER0_ENABLED
#define TIMER0_ENABLED 1
#endif
// <q> TIMER1_ENABLED - Enable TIMER1 instance
#ifndef TIMER1_ENABLED
#define TIMER1_ENABLED 1
#endif
// <q> TIMER2_ENABLED - Enable TIMER2 instance
#ifndef TIMER2_ENABLED
#define TIMER2_ENABLED 1
#endif
// <q> TIMER3_ENABLED - Enable TIMER3 instance
#ifndef TIMER3_ENABLED
#define TIMER3_ENABLED 1
#endif
// <q> TIMER4_ENABLED - Enable TIMER4 instance
#ifndef TIMER4_ENABLED
#define TIMER4_ENABLED 0
#endif
const nrf_drv_timer_t TIMER_LED1 = NRF_DRV_TIMER_INSTANCE(0);
const nrf_drv_timer_t TIMER_LED2 = NRF_DRV_TIMER_INSTANCE(1);
const nrf_drv_timer_t TIMER_LED3 = NRF_DRV_TIMER_INSTANCE(2);
const nrf_drv_timer_t TIMER_LED4 = NRF_DRV_TIMER_INSTANCE(3);
/**
* @brief Handler for timer events.
*/
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
switch (event_type)
{
case NRF_TIMER_EVENT_COMPARE0:
bsp_board_led_invert(0);
break;
case NRF_TIMER_EVENT_COMPARE1:
bsp_board_led_invert(1);
break;
case NRF_TIMER_EVENT_COMPARE2:
bsp_board_led_invert(2);
break;
case NRF_TIMER_EVENT_COMPARE3:
bsp_board_led_invert(3);
break;
default:
//Do nothing.
break;
}
}
/**
* @brief Function for main application entry.
*/
int main(void)
{
uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
uint32_t time_ticks1, time_ticks2, time_ticks3, time_ticks4;
uint32_t err_code = NRF_SUCCESS;
//Configure all leds on board.
bsp_board_init(BSP_INIT_LEDS);
//Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
err_code = nrf_drv_timer_init(&TIMER_LED1, &timer_cfg, timer_led_event_handler);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_timer_init(&TIMER_LED2, &timer_cfg, timer_led_event_handler);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_timer_init(&TIMER_LED3, &timer_cfg, timer_led_event_handler);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_timer_init(&TIMER_LED4, &timer_cfg, timer_led_event_handler);
APP_ERROR_CHECK(err_code);
time_ticks1 = nrf_drv_timer_ms_to_ticks(&TIMER_LED1, 1000);
time_ticks2 = nrf_drv_timer_ms_to_ticks(&TIMER_LED2, 500);
time_ticks3 = nrf_drv_timer_ms_to_ticks(&TIMER_LED3, 250);
time_ticks4 = nrf_drv_timer_ms_to_ticks(&TIMER_LED4, 100);
nrf_drv_timer_extended_compare(
&TIMER_LED1, NRF_TIMER_CC_CHANNEL0, time_ticks1, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
nrf_drv_timer_extended_compare(
&TIMER_LED2, NRF_TIMER_CC_CHANNEL1, time_ticks2, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);
nrf_drv_timer_extended_compare(
&TIMER_LED3, NRF_TIMER_CC_CHANNEL2, time_ticks3, NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, true);
nrf_drv_timer_extended_compare(
&TIMER_LED4, NRF_TIMER_CC_CHANNEL3, time_ticks4, NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK, true);
nrf_drv_timer_enable(&TIMER_LED1);
nrf_drv_timer_enable(&TIMER_LED2);
nrf_drv_timer_enable(&TIMER_LED3);
nrf_drv_timer_enable(&TIMER_LED4);
while (1)
{
__WFI();
}
}
앞으로
지금까지 nRF52의 대표적인 타이머를 이용하여 LED를 제어해보는 예제를 알아보았다.
다음에는 simple_timer 예제를 살펴보도록 하자.
'Embedded > nRF52 BLE 개발 안내서' 카테고리의 다른 글
nRF52 BLE 개발하기 - rtc (8) | 2021.01.15 |
---|---|
nRF52 BLE 개발하기 - simple_timer (0) | 2021.01.14 |
nRF52 BLE 개발하기 - pin_change_int (5) | 2021.01.11 |
nRF52 BLE 개발하기 - led_softblink (0) | 2021.01.02 |
nRF52 BLE 개발하기 - blinky (0) | 2021.01.01 |
댓글