nRF APP_TIMER

 APP_TIMERを少しやってみた。

sys_configの中身を確認しておく。templateから作っているので、必要なものはある。

The low frequency clock (LFCLK)
クロックのタイマーは32.768kHz(上の数字は2で割られている)
app_timer: RTCペリフェラルを使用するSWタイマライブラリで、LFCLKを使用
nrf_drv_timer: TIMERペリフェラル用のドライバ。RTCと同等と考えることができるが、LFクロックの代わりにHFクロックを使用する。


流れは以下
1.  ヘッダーファイルを読み込む(対応するcファイルがない場合は加える)
2.タイマーに使う定数を定義する。
3. idを生成する。
4.クロックの設定とタイマーハンドラーを作る。
5. main の中で初期化してタイマータスクを開始する。

1.  ヘッダーファイルを読み込む

//To use application timer

#include "app_timer.h"

#include "nrf_drv_clock.h"

コンパイルしてエラーがないか確認する。

2.タイマーに使う定数を定義する。

#define LED_INTERVAL APP_TIMER_TICKS(200)

を定義する。APP_TIMER_TICKSは200msecを待つ時に必要なTICKSの数に変換してくれる関数。

3. idを生成する。

mainの外で

APP_TIMER_DEF(timer_id);

timer_idの部分は任意で、タイマーの識別子。識別子を作成し、タイマー用のメモリを静的に割り当てる。

4.クロックの設定とタイマーハンドラーを作る。

static void lfclk_config(void)

{

  ret_code_t err_code =nrf_drv_clock_init();

  APP_ERROR_CHECK(err_code);

  nrf_drv_clock_lfclk_request(NULL);

}

static void app_timer_handler(void * p_context)

{

    nrf_gpio_pin_toggle(26);

}

nrf_drv_clock_init()は説明を読んでも初期化するとしか書いていない。まあおまじない。 bleのソフトデバイスを使う時はイニシャライズがいらない。

 nrf_drv_clock_lfclk_request(NULL)の部分で、最初のリクエストは、選択されたLFCLKソースを開始する。イメージは、クロックにLFCLKを接続するって感じかな。

タイマーハンドラーは指定時間になったらここに飛んでくる。

static void timers_init(void)

{

  ret_code_t  err_code;

  err_code=app_timer_init();

  APP_ERROR_CHECK(err_code);

  err_code=app_timer_create(&timer_id, APP_TIMER_MODE_REPEATED, app_timer_handler);

  APP_ERROR_CHECK(err_code);

}


5. main の中で初期化してタイマータスクを開始する。

 //configration GPIP pin

    nrf_gpio_cfg_output(26);

    //Initilization of timer

    lfclk_config();

    timers_init();

    //timer start

    uint32_t err_code =app_timer_start(timer_id, LED_INTERVAL,NULL);

タイマーIDと間隔を指定するだけで定期的な時間になったらハンドラーに飛んでいく。


このタイマーはペリフェラルを消費しない。マイコンでよくあるのはTIMERペリフェラルが4つあって、4つにタスクを割りあてると、5つ目が・・・とよくなるが、これは消費しないというのがポイントかな。

ってことで異なる周期の2つにさらにしてみたのが以下

IDを2つ用意してそれぞれcreateし、ハンドラーもそれぞれ用意すればよい。



#include <stdbool.h>

#include <stdint.h>


#include "nrf.h"

#include "nordic_common.h"

#include "boards.h"

//To use nrf_delay

#include "nrf_delay.h"


//To use nrf_log, add three include files. 

#include "nrf_log.h"

#include "nrf_log_ctrl.h"

#include "nrf_log_default_backends.h"


//To use application timer

#include "app_timer.h"

#include "nrf_drv_clock.h"


#define LED_INTERVAL1 APP_TIMER_TICKS(100)

#define LED_INTERVAL2 APP_TIMER_TICKS(200)

#define LED1_PIN  26

#define LED2_PIN  30


APP_TIMER_DEF(timer_id1);

APP_TIMER_DEF(timer_id2);


static void lfclk_config(void)

{

  ret_code_t err_code =nrf_drv_clock_init();

  APP_ERROR_CHECK(err_code);

  nrf_drv_clock_lfclk_request(NULL);

}


static void app_timer_handler1(void * p_context)

{

  nrf_gpio_pin_toggle(LED1_PIN);

}

static void app_timer_handler2(void * p_context)

{

  nrf_gpio_pin_toggle(LED2_PIN);

}

static void timers_init(void)

{

  ret_code_t  err_code;

  err_code=app_timer_init();

  APP_ERROR_CHECK(err_code);


  err_code=app_timer_create(&timer_id1, APP_TIMER_MODE_REPEATED, app_timer_handler1);

  APP_ERROR_CHECK(err_code);

  err_code=app_timer_create(&timer_id2, APP_TIMER_MODE_REPEATED, app_timer_handler2);

  APP_ERROR_CHECK(err_code);

}


/**

 * @brief Function for application main entry.

 */

int main(void)

{

    //Initilization of NRF_LOG

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    NRF_LOG_DEFAULT_BACKENDS_INIT();


    //configration GPIP pin

    nrf_gpio_cfg_output(LED1_PIN);

    nrf_gpio_cfg_output(LED2_PIN);


    //Initilization of timer

    lfclk_config();

    timers_init();


    //timer start

    uint32_t err_code;

    err_code =app_timer_start(timer_id1, LED_INTERVAL1,NULL);

    APP_ERROR_CHECK(err_code);

    err_code =app_timer_start(timer_id2, LED_INTERVAL2,NULL);

    APP_ERROR_CHECK(err_code);

   while (true)

    {

      //do nothing

    }

}

/** @} */



コメント

このブログの人気の投稿

Attiny85とAQM0802A(LCD)のI2C接続

Attiny85 FuseRest

HS101 STM32の自作お手軽オシロスコープ