タイマ機能の設定は、CPU層の「RL78G14_init.c」ファイルに記述していきます。
タイマ機能の設定は、仕様や設計で検討してきたタイマ機能を整理して必要なタイマを設定していきます。
必要なタイマを整理
必要なタイマを整理します。
- メイン周期の10ms
- 赤外線リモコンからの受信なしが一定時間経過した場合にHALTモードに移行するときの30s
- PWMのデューティ出力するときのタイマ
- 赤外線リモコン受信時の外部イベントのタイマ
- 赤外線リモコン押下からタイムアウトをカウントするタイマ
※受信開始してから一定時間経過しても受信が完了しない、または、次の受信がない場合は、異常や押しっぱなしでなくなったと判断するために監視用のタイマ
タイマで思い当たるものを挙げてみました。もし、忘れていたら途中で追加するかもしれません。
タイマ機能の設定の概要
赤外線リモコン受信時の外部イベントで使用するタイマは、赤外線リモコン受信に割当たっているP16/TI01に該当するタイマであるタイマ・アレイ・ユニットのチャネル1のタイマを使用します。デバッグし易いように、1カウントは1μsになるように設定します。
モータ制御に使用するPWM制御のタイマは、ENA、ENBに割当たっているP10/TRDIOD1と、P15/TRDIOB0に該当するタイマであるタイマRDのD1、B0を使用します。
メイン周期のタイマは、タイマ・アレイ・ユニットのチャネル0を使用し、1カウントは4μsとすることにします。10ms毎のインターバル・タイマとし、タイマ割り込み処理で、10ms周期のフラグをセットして、メイン処理に通知します。
1カウントを4μsとした理由は、赤外線リモコン受信のタイムアウトを監視するタイマと同じ動作クロックを使用することを想定しているからです。この赤外線リモコン受信のタイムアウトを監視するタイマの時間が107msなので、107ms以上カウント可能な動作クロックにするため、1カウントを4μsとしました。
HALTモードに移行する30sのタイマは、タイマ機能は使用せず、メイン周期毎(10ms)に受信なしの場合にカウントアップし、3000カウントしたときに30s経過と判断することとします。
赤外線リモコン受信のタイムアウトを監視するタイマは、タイマ・アレイ・ユニットチャネル2を使用します。赤外線リモコンからリーダーコード、または、リピートコードを受信する度にタイマをクリアし、タイマを開始します。タイムアップした場合は、ボタンが離されたか、不正受信により受信が正常に完了できなかった場合なので、そのことをメイン処理に通知します。メイン処理では、通知を受け取って、モータを停止させることを行います。
タイマの時間は、107msです。ただし、リピートコードを受信した場合は、40msのタイマ時間に変更することを考えています。このため、初期値としては、107msのカウントを設定します。
ロボットカー用タイマ設定の実装
「RL78G14_init.c」ファイルに、タイマ初期化関数を用意します。
このファイルは、ロボットカー用IOポート設定で使用したファイルです。そのファイルに次の実装内容を追加します。
省略
static void RL78G14_init_IO_Port( void );
static void RL78G14_init_Timer( void ); //今回追加箇所
省略
//↓今回追加箇所
#define RL78G14_INIT_TPS0 (0x0075U)
#define RL78G14_INIT_TMR00 (0x8000U)
#define RL78G14_INIT_TMR01 (0x02CCU)
#define RL78G14_INIT_TMR02 (0x8000U)
#define RL78G14_INIT_TDR00 (0x09C3U)
#define RL78G14_INIT_TDR01 (0x0000U)
#define RL78G14_INIT_TDR02 (0x687DU)
#define RL78G14_INIT_TIS0 (0x00U)
#define RL78G14_INIT_TOE0 (0x0000U)
#define RL78G14_INIT_TO0 (0x0000U)
#define RL78G14_INIT_TOL0 (0x0000U)
#define RL78G14_INIT_TOM0 (0x0000U)
#define RL78G14_INIT_ISC (0x00U)
#define RL78G14_INIT_NFEN1 (0x00U)
#define RL78G14_INIT_TRDELC (0x00U)
#define RL78G14_INIT_TRDMR (0x00U)
#define RL78G14_INIT_TRDPMR (0x41U)
#define RL78G14_INIT_TRDFCR (0x80U)
#define RL78G14_INIT_TRDOER1 (0x7DU)
#define RL78G14_INIT_TRDOER2 (0x00U)
#define RL78G14_INIT_TRDOCR (0x00U)
#define RL78G14_INIT_TRDDF0 (0x00U)
#define RL78G14_INIT_TRDDF1 (0x00U)
#define RL78G14_INIT_TRDCR0 (0x20U)
#define RL78G14_INIT_TRDCR1 (0x20U)
#define RL78G14_INIT_TRDIER0 (0x00U)
#define RL78G14_INIT_TRDIER1 (0x00U)
#define RL78G14_INIT_TRDPOCR0 (0x00U)
#define RL78G14_INIT_TRDPOCR1 (0x00U)
#define RL78G14_INIT_TRDGRA0 (0x7F8DU)
#define RL78G14_INIT_TRDGRA1 (0x7F8DU)
#define RL78G14_INIT_TRDGRB0 (0x3FC6U)
#define RL78G14_INIT_TRDGRD1 (0x3FC6U)
//↑今回追加箇所
void hdwinit( void )
{
PIOR0 = RL78G14_INIT_PIOR0;
PIOR1 = RL78G14_INIT_PIOR1;
RL78G14_init_IO_Port();
RL78G14_init_Timer(); //今回追加箇所
}
省略
static void RL78G14_init_Timer( void )
{
TAU0EN = RL78G14_INIT_ACT;
TPS0 = RL78G14_INIT_TPS0;
TMR00 = RL78G14_INIT_TMR00;
TMR01 = RL78G14_INIT_TMR01;
TMR02 = RL78G14_INIT_TMR02;
TDR00 = RL78G14_INIT_TDR00;
TDR01 = RL78G14_INIT_TDR01;
TDR02 = RL78G14_INIT_TDR02;
TIS0 = RL78G14_INIT_TIS0;
TOE0 = RL78G14_INIT_TOE0;
TO0 = RL78G14_INIT_TO0;
TOL0 = RL78G14_INIT_TOL0;
TOM0 = RL78G14_INIT_TOM0;
ISC = RL78G14_INIT_ISC;
NFEN1 = RL78G14_INIT_NFEN1;
TRD0EN = RL78G14_INIT_ACT;
TRDELC = RL78G14_INIT_TRDELC;
TRDMR = RL78G14_INIT_TRDMR;
TRDPMR = RL78G14_INIT_TRDPMR;
TRDFCR = RL78G14_INIT_TRDFCR;
TRDOER1 = RL78G14_INIT_TRDOER1;
TRDOER2 = RL78G14_INIT_TRDOER2;
TRDOCR = RL78G14_INIT_TRDOCR;
TRDDF0 = RL78G14_INIT_TRDDF0;
TRDDF1 = RL78G14_INIT_TRDDF1;
TRDCR0 = RL78G14_INIT_TRDCR0;
TRDCR1 = RL78G14_INIT_TRDCR1;
TRDIER0 = RL78G14_INIT_TRDIER0;
TRDIER1 = RL78G14_INIT_TRDIER1;
TRDPOCR0 = RL78G14_INIT_TRDPOCR0;
TRDPOCR1 = RL78G14_INIT_TRDPOCR1;
TRDGRA0 = RL78G14_INIT_TRDGRA0;
TRDGRA1 = RL78G14_INIT_TRDGRA1;
TRDGRD1 = RL78G14_INIT_TRDGRD1;
TRDGRB0 = RL78G14_INIT_TRDGRB0;
}
TRDELCは、イベント・リンク・コントローラ(ELC)を使用しないので、初期値のままとします。
ELCとは、各周辺機能が出力するイベントを周辺機能間で相互に接続(リンク)します。イベントリンクによりCPUを介さず直接、周辺機能間での連携動作が可能になります。
TRDMRは、 TRDIOD1をPWM出力として使用するため、ジェネラルレジスタのまま、タイマRD同期は、独立動作でよいということで、初期値から変更がないのでそのままとします。
TRDPMRは、PWMとして使用するのは、TRDIOD1とTRDIOB0のため、この2つをPWM機能に設定します。
TRDFCRは、PWM機能がタイマモードなので、それに合わせて設定します。外部クロック入力は使用しないので無効のままでよいです。このため、初期値のままにします。
TRDOER1は、TRDIOD1とTRDIOB0を出力に使用するため、それに合わせて設定します。
TRDOER2は、パルス出力強制遮断の機能は使用しないため、初期値のままにします。
TRDOCRは、TRDIOD1とTRDIOB0の初期出力は非アクティブなので、初期値のままにします。
TRDDF0/TRDDF1は、パルス強制遮断の機能は使用しないため、初期値のままにします。
TRDCR0/TRDCR1は、PWM機能を使用し、外部クロックは使用しない、PWMの周波数はArduinoの仕様に合わた約980Hzのため、0x20にします。
TRDIER0/TRDIER1は、割り込みは使用しないため、初期値のままにします。
TRDPOCR0/TRDPOCR1は、TRDIOD1とTRDIOB0の出力レベルはLアクティブにします。Hアクティブでもよいのですが、指定した時間がHI区間のほうが解りやすいかなという考えで設定しました。
TRDGRA0/TRDGRA0は、980Hzのため、1020μs周期の設定である32653を設定します。(カウントクロックは32MHzのため、1カウントは31.25ナノ秒です。)
TRDGRB0/TRDGRD1は、デューティ比を50%とするため、 32653/2を設定します。
簡単ではありましたが、ロボットカー用のタイマ機能の設定については以上となります。