이 예제가 본격적으로 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_out은 nrf_gpio.h에 define되어 있으며, 출력으로 설정하는 부분입니다.
nrf_gpiote_task_config는 nrf_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_PPI는 nrf51.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 |