본문 바로가기
Study/nRF51xxx(BLE)

nRF51 DK 예제 17 -SIMPLE TIMER

by Answer Choi 2015. 3. 13.
반응형




이번예제는 simple timer입니다.


LED1과 LED2 가 모두 켜진후 


각각 2초간 토글되는 예제입니다.




main.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(void)
{
    uint32_t err_code = app_simple_timer_init();
    APP_ERROR_CHECK(err_code);
 
    LEDS_CONFIGURE(BSP_LED_0_MASK | BSP_LED_1_MASK);
    LEDS_ON(BSP_LED_0_MASK | BSP_LED_1_MASK);    
 
    nrf_delay_ms(GENERIC_DELAY_TIME);
   
    state_machine_state_change(APP_STATE_SINGLE_SHOT);
 
    for (;;)
    {
        power_manage();
    }    
}
cs


Line 3~4 : timer 초기화입니다.


app_simple_timer


1
2
3
4
5
6
7
8
9
10
11
12
13
uint32_t app_simple_timer_init(void)
{
    uint32_t err_code = NRF_SUCCESS;
 
    err_code = nrf_drv_timer_init(&SIMPLE_TIMER, NULL, app_simple_timer_event_handler);
 
    if(NRF_SUCCESS == err_code)
    {
        m_simple_timer_state = SIMPLE_TIMER_STATE_INITIALIZED;
    }
 
    return err_code;
}
cs


5 : timer driver를 초기화합니다.


nrf_drv_timer_init(타이머 인스턴스, 타이머설정, 타이머 핸들러)



1
2
3
4
5
6
7
8
9
10
11
#define APP_SIMPLE_TIMER_INSTANCE 1
const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(1);
 
#if (TIMER1_ENABLED == 1)
#define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_1MHz
#define TIMER1_CONFIG_MODE         TIMER_MODE_MODE_Timer
#define TIMER1_CONFIG_BIT_WIDTH    TIMER_BITMODE_BITMODE_16Bit
#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
 
#define TIMER1_INSTANCE_INDEX      (TIMER0_ENABLED)
#endif
cs


Line 6~9 : LED 1과 2를 초기화 한 후 켜주고, 1초간 기다립니다.


Line 11 : 현재상태에 따른 LED표시를 바꾸는 부분입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static __INLINE void state_entry_action_execute(void)
{
    switch (m_state)
    {        
        case APP_STATE_SINGLE_SHOT:
            led_and_timer_control(BSP_LED_0_MASK, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT);
            break;
           
        case APP_STATE_REPEATED:
            led_and_timer_control(BSP_LED_1_MASK, APP_SIMPLE_TIMER_MODE_REPEATED);            
            break;
 
        default:
            APP_ERROR_HANDLER(m_state);
            break;
    }        
}
cs


5~7 : 현재상태가 APP_STATE_SINGLE_SHOT일때 동작합니다.


9~11 : 현재상태가 APP_STATE_REPEATED일때 동작합니다.


동작은 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
static void led_and_timer_control(uint32_t led_id, app_simple_timer_mode_t timer_mode)
{
    uint32_t err_code;
 
    LEDS_INVERT(led_id);                
           
    m_state_transit_counter = STATE_TRANSIT_COUNTER_INIT_VALUE;    
    m_toggle_led_counter    = TOGGLE_LED_COUNTER;                    
           
    err_code = app_simple_timer_start(timer_mode, timeout_handler, TIMEOUT_VALUE, NULL);            
    APP_ERROR_CHECK(err_code);                                                                                                      
}
cs


5 : LED를 토클합니다.


7 : 총 토글되는 카운터 입니다. 4*10=40


8 : 토글되는 시간입니다. 500/(50000/1000)=10


10~11 : simple timer를 동작시킵니다.


app_simple_timer_start(타이머 모드, 타임아웃 핸들러, 타임아웃 값, context)


Freq=1MHz 이므로 1us이고, 타임아웃값이 50000이므로 1us*50000=50ms마다 타임아웃이


걸리게 됩니다.


타임아웃이 걸리게 되면 timeout handler가 호출이 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void timeout_handler(void * p_context)
{
    switch (m_state)
    {
        uint32_t err_code;
       
        case APP_STATE_SINGLE_SHOT:
            if (--m_state_transit_counter != 0)
            {            
                if (--m_toggle_led_counter == 0)
                {
                    m_toggle_led_counter = TOGGLE_LED_COUNTER;    
                    LEDS_INVERT(BSP_LED_0_MASK);                
                }
               
                err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT,
                                       timeout_handler,
                                       TIMEOUT_VALUE,
                                       NULL);            
                APP_ERROR_CHECK(err_code);                                                                                          
            }
            else
            {
                state_machine_state_change(APP_STATE_REPEATED);
            }        
            break;
           
        case APP_STATE_REPEATED:            
            if (--m_state_transit_counter != 0)
            {            
                if (--m_toggle_led_counter == 0)
                {
                    m_toggle_led_counter = TOGGLE_LED_COUNTER;                    
                    LEDS_INVERT(BSP_LED_1_MASK);
                }                
            }
            else
            {
                LEDS_ON(BSP_LED_0_MASK | BSP_LED_1_MASK);
               
                err_code = app_simple_timer_stop();
                APP_ERROR_CHECK(err_code);    
               
                nrf_delay_ms(GENERIC_DELAY_TIME);
               
                state_machine_state_change(APP_STATE_SINGLE_SHOT);
            }    
            break;
 
        default:
            APP_ERROR_HANDLER(m_state);
            break;
    }    
}
cs


7~21 : 모드가 APP_STATE_SINGLE_SHOT일때 들어오게 됩니다.


8~21 : m_state_transit_counter 가 40이므로 50ms*40번을 들어오게 됩니다.


10~14 : m_toggle_led_counter는 10이므로 50ms*10번 연산후 즉 0.5초마다 들어와서


LED를 토글하게 됩니다.


16~20 : 타이머를 재시작합니다.


22~25m_state_transit_counter 가 0이 되고나면, mode를 APP_STATE_REPEATED로 바꿔서


28~48 이 실행되게 됩니다.


29~36 : 위의 APP_STATE_SINGLE_SHOT 모드일때와 비슷하게 동작하며,


37~48m_state_transit_counter 가 0이 되면, 


39 : LED1과 LED2를 켜주고,


41~42 : 타이머를 stop시킵니다.


44 : 1초간 기다립니다.


46 : state_machine_state_change 를 다시 시작합니다.





반응형

인기글