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

nRF51 DK 예제 5 -GPIOTE

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

 


이 예제가 본격적으로 GPIOTE를 사용하는 예제인 것 같습니다.

 

타이머를 설정하고, PPI를 설정하여서 GPIOTE로 LED를 제어하는 예제.

 


main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main(void)
{
    gpiote_init(); // Configure a GPIO to toggle on a GPIOTE task.
    timer0_init(); // Use TIMER0 to generate events every 200 ms.
    ppi_init();    // Use a PPI channel to connect the event to the task automatically.
   
    // Workaround for PAN-73: Use of an EVENT from any TIMER module to trigger a TASK in GPIOTE or
    // RTC using the PPI could fail under certain conditions.
    *(uint32_t *)0x40008C0C = 1;
    NRF_TIMER0->TASKS_START = 1;  // Start event generation.
   
    while (true)
    {
        // Do Nothing - GPIO can be toggled without software intervention.
    }
cs

Line 3 : gpiote 초기화 부분입니다.

1
2
3
4
5
6
7
8
9
10
static void gpiote_init(void)
{
    // Configure GPIO_OUTPUT_PIN_NUMBER as an output.
    nrf_gpio_cfg_output(GPIO_OUTPUT_PIN_NUMBER);
   
    // Configure GPIOTE_CHANNEL_NUMBER to toggle the GPIO pin state with input.
    // @note Only one GPIOTE task can be coupled to an output pin.
    nrf_gpiote_task_config(GPIOTE_CHANNEL_NUMBER, GPIO_OUTPUT_PIN_NUMBER, \
                           NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
}
cs

nrf_gpio_cfg_outnrf_gpio.h에 define되어 있으며, 출력으로 설정하는 부분입니다.

nrf_gpiote_task_confignrf_gpiote.h에 define되어 있으며, gpiote task를 설정하는 부분입니다.

nrf_gpiote_task_config(gpiote채널, gpio pin, gpiote polarity, gpio 초기값);

 

Line 4 : Timer 0 초기화 부분입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static void timer0_init(void)
{
    // Start 16 MHz crystal oscillator.
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART    = 1;
   
    // Wait for the external oscillator to start.
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    {
        // Do nothing.
    }
   
    // Clear TIMER0
    NRF_TIMER0->TASKS_CLEAR = 1;
   
    // Configure TIMER0 for compare[0] event every 200 ms.
    NRF_TIMER0->PRESCALER = 4;            // Prescaler 4 results in 1 tick equals 1 microsecond.
    NRF_TIMER0->CC[0]     = 200 * 1000UL; // 1 tick equals 1?, multiply by 1000 for ms value.
    NRF_TIMER0->MODE      = TIMER_MODE_MODE_Timer;
    NRF_TIMER0->BITMODE   = TIMER_BITMODE_BITMODE_24Bit;
    NRF_TIMER0->SHORTS    =
        (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
}
cs

4~14 : clock을 high frequence clock으로 설정해 줍니다.


Clock은 Low Frequence CLK(32.768kHz)와 High Frequence CLK(16MHz)가 있습니다.

타이머에서는 HFCLK를 쓰는데 아래 그림과 같습니다.

17~22 : HFCLK(16MHz)를 분주하게 됩니다.

f=16M/₂⁴=1Mhz가 되고, CC값이 200*1000=200k니깐,

200k/1M=0.2=200ms의 타이머가 생성됩니다.

 

Line 5: PPI 초기화 부분입니다.

1
2
3
4
5
6
7
8
9
static void ppi_init(void)
{
    // Configure PPI channel 0 to toggle GPIO_OUTPUT_PIN on every TIMER0 COMPARE[0] match (200 ms)
    NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER0->EVENTS_COMPARE[0];
    NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[GPIOTE_CHANNEL_NUMBER];
   
    // Enable PPI channel 0
    NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos);
}
cs

NRF_PPInrf51.h에 define되어 있습니다.

4~8 : PPI를 설정하는 부분인데, 똑같이 channel 0으로 설정하였습니다.

NRF_PPI->CH[0].EEP는 event end point로 task 발생조건이고,

NRF_PPI->CH[0].TEP는 task end point로 event에 의해 발생하는 task입니다.

여기서는 위에서 설정한 200ms타이머가 EEP이고, GPIOTE로 설정한 LED가 TEP입니다.

NRF_PPI->CHEN은 채널을 사용한다는 의미입니다.


실행한 모습입니다.



반응형

'Study > nRF51xxx(BLE)' 카테고리의 다른 글

nRF51 DK 예제 7 -Radio Receiver  (0) 2015.03.03
nRF51 DK 예제 6 -Radio Transmitter  (0) 2015.03.03
nRF51 DK 예제4 flashwrite  (0) 2015.03.02
nRF51 DK 예제3 bsp  (0) 2015.02.27
nRF51 DK 예제 2 LED blinky_rtx  (0) 2015.02.26

인기글