シリーズ:実験シリーズ(フェーズ2)
対応ロードマップ:フェーズ2 / E2-02
この記事の役割:1msごとに増えるカウンタを作り、「今何msか」をプログラムの中で判定できるようにする。
1. 目的
今回は、1msごとに増えるカウンタを作り、
「今、何ms経ったか」をプログラムの中で扱えるようにします。
E2-01 では delay で待っている間、ほかの処理が止まることを確認しました。
今回はその次の段階として、待つのではなく、経過時間を見るための土台を作ります。
この実験のゴール(合格条件)
- FSPでタイマを1つ追加できる
- 1msごとにタイマが動く設定ができる
- 1msごとにカウンタが 1 ずつ増える
- デバッガのWatchで、カウンタが増えているのを確認できる
2. 前提・環境
- 評価ボード:RTK7EKA8M2S00001BE
- 開発環境:e² studio + FSP
- 前回までにできていること
- e² studio + FSP でプロジェクトがビルドできる
⇒次の記事の4章以降にプロジェクト作成~ビルドまでの手順の記載があります。
統合開発環境e² studio+FSPのインストールからビルドまで(リンク) - EK-RA8M2を接続できている
- e² studio + FSP でプロジェクトがビルドできる
3. 今回の変更点
3-1. 配線変更
- 今回は評価ボードのみを使用するため、特に配線は考えなくてよいです
3-2. FSP設定変更
今回は FSP Configurator でタイマを1つ追加します。
- モードは Periodic
- 周期は 1ms
- 割り込みを有効にする
- コールバック関数を設定する
3-3. コード変更
- 1msごとに増えるグローバル変数を追加
- タイマのコールバック関数を追加
delayの代わりに「今の時刻との差」で処理する形に変える
4. 手順
4-1. まず、今回の完成形をイメージする
今回の完成形はこれです。
- FSPでタイマを追加する
- 1msごとに動く設定にする
- 1msごとに呼ばれる関数を書く
- その関数の中でカウンタを 1 増やす
- デバッグで、カウンタが増えているのを確認する
4-2. FSP Configurator を開く
e² studio で、対象プロジェクトを開きます。
次に、いつもの FSP Configurator を開きます。
- プロジェクトを開く
configuration.xmlを開く- FSP Configurator の画面を表示する
4-3. タイマスタックを追加する
FSP Configurator で、タイマを1つ追加します。
- 「Stacks」や「Add Stack」から追加する
- Timer 系のスタックを選ぶ
- AGTを選ぶ
図(E2-02_AGT生成.png)

Timersには、複数の種類があり、どれを選ぶかで悩みやすいですが、今回の目的は
- 1msごとに周期的に動けばよい
なので、AGTを選べば大丈夫です。
4-4. タイマを「1msごと」に動く設定にする
追加したタイマの設定を開いて、次を確認します。
確認する項目
- Mode:Periodic
- Period:1ms
- Period Unit:Milliseconds
- Callback:
timer0_callback - Underflow Interrupt Priority:Priority 1
用語の意味
- Periodic
一定間隔で、何度も繰り返すモードです。 - Period
繰り返す間隔の値です。 - Period Unit
繰り返す間隔の単位です。 - Callback
1msごとに自動で呼びたい関数の名前です。 - Underflow Interrupt Priority
Callbackを使用するか、使用する場合の優先度の指定です。
4-5. Generate を実行する
設定を変えたら、コード生成を行います。
- Generate Project Content
- または自動生成が動く場合は、そのまま反映を待つ
これで、FSPの設定に対応したコードが生成されます。
4-6. hal_entry() に使う変数を追加する
次に hal_entry() があるファイルを開きます。
通常は hal_entry.cです。
まず、1msごとに増やす変数を追加します。
#include "hal_data.h"
#include <stdint.h>
volatile uint32_t g_ms_count = 0;ここで使っているものの意味
uint32_t- 0以上の整数を入れるための型です
g_ms_count- 今、何msたったかを入れる変数です
volatile- この値は普通の流れとは別に変わるので、毎回ちゃんと見てください、という意味です
今回は 割り込みの中で値が変わる ので、volatile を付けます。
初心者向けには、
「割り込みで変わる変数には volatile を付ける」
とまず覚えておけば十分です。
4-7. コールバック関数を書く
次に、1msごとに自動で呼ばれる関数を書きます。
void timer0_callback(timer_callback_args_t * p_args)
{
FSP_PARAMETER_NOT_USED(p_args);
g_ms_count++;
}この関数でやっていること
やっていることは、本当にこれだけです。
- 1msたつ
timer0_callback()が呼ばれるg_ms_countを 1 増やす
つまり、
- 1ms後 → 1
- 2ms後 → 2
- 3ms後 → 3
と増えていきます。
p_args とは?
今は難しく考えなくて大丈夫です。
FSPがコールバック関数を呼ぶときに渡してくる情報です。
ただし、今回は使わないため、FSP_PARAMETER_NOT_USED(p_args);としています。
※「今回は p_args を使いません」 という意味だと思えば十分です。
4-8. タイマを開始する
次に、hal_entry() の最初でタイマを開始します。
void hal_entry(void)
{
fsp_err_t err;
err = R_AGT_Open(&g_timer0_ctrl, &g_timer0_cfg);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
err = R_AGT_Start(&g_timer0_ctrl);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
while (1)
{
;
}
}このコードの意味
R_AGT_Open(...)- タイマを使う準備をする
R_AGT_Start(...)- タイマを動かし始める
while(1)- メイン処理はずっと回り続ける
ここではまだ、メインループの中で特別なことはしません。
今回の確認対象は「カウンタが増えるか」だからです。
4-9. ここまでの完成コード
まずは次のコードで十分です。
#include "hal_data.h"
#include <stdint.h>
volatile uint32_t g_ms_count = 0;
void timer0_callback(timer_callback_args_t * p_args)
{
FSP_PARAMETER_NOT_USED(p_args);
g_ms_count++;
}
void hal_entry(void)
{
fsp_err_t err;
err = R_AGT_Open(&g_timer0_ctrl, &g_timer0_cfg);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
err = R_AGT_Start(&g_timer0_ctrl);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
while (1)
{
;
}
}4-10. ビルドする
ここで一度ビルドします。
- Save
- Build Project
ビルドが通ればOK
まずはビルド成功が第一です。
まだ動作確認前なので、エラーが出たらここで直します。
4-11. 書き込んでデバッグ開始する
次に、これをボードへ書き込みます。
- デバッグ開始
hal_entry()まで進める- 必要ならブレークポイントを置く
そのあと、Watch で g_ms_count を見ます。
4-12. Watchで g_ms_count を確認する
Watchウィンドウで、g_ms_count を追加します。
5. 結果
5-1. 成功時の見え方
成功すると、Watchでg_ms_countの値が、
字間の経過とともに増えていきます。
6. ハマりポイント/原因と対策
6-1. ビルドエラーになる
原因
- 関数名のつづりが違う
- FSPで設定した名前と、コードに書いた名前が合っていない
- AGT用のコードを書くところで、別のタイマ用の関数名を書いている
対策
- FSPで作られたタイマ名が
g_timer0になっているか確認する - コールバック名が
timer0_callbackになっているか確認する R_AGT_Open()とR_AGT_Start()になっているか確認する
6-2. g_ms_count が 0 のまま増えない
原因
- タイマが開始できていない
- 割り込み設定が入っていない
- コールバック関数が呼ばれていない
対策
R_AGT_Open()とR_AGT_Start()のあとでエラーになっていないか確認する- FSP設定で周期が 1ms になっているか確認する
- コールバック関数名が設定と一致しているか見直す
Underflow Interrupt PriorityがDisabledのままになっていないか確認する
6-3. どこで失敗しているか分からない
対策
次の順で切り分けます。
- FSPでタイマ追加できているか
- Generateできているか
- ビルドできるか
R_AGT_Open()まで来ているかR_AGT_Start()まで来ているかg_ms_countが増えているか
一気に考えず、1つずつ確認 すると分かりやすいです。
7. 次回やること
次回は、この 1msカウンタを使って、一定周期で処理を動かす 実験に進みます。
8. 関連リンク
- 実験シリーズのロードマップ
→ E2-02 タイマで1ms毎にカウントアップするストップウォッチを作る - 実験シリーズの全体像
→ フェーズ2:時間を測る(1msカウンタ)→周期処理→状態分け - C言語:はじめに読む
→ フェーズ2で使うカウンタ変数・フラグの入口 - 技術成果物
- ソース:
main.cまたはhal_entry.c - 手順書:本記事
- 設定例:FSPタイマ設定
- ソース: