タイマ機能には,一定時間間隔で繰り返し機能する「インターバルタイマ」と,設定した時間が経過したことを一度だけしらせる「ワンショットタイマ」がある.通常マイコンを搭載した組込機器にはこうしたタイマ機能が内蔵されているが,M16Cには自分自身に内蔵されたタイマ機能がある.この実験のようなロボットの制御ではインターバルタイマを利用する.
M16Cには,タイマがa0からa4まで存在する.
レジスタ | 機能 |
---|---|
ta番号mr | 番号は0から4まで.タイマモードを設定 |
ta番号 | 番号は0から4まで(ta0からta4).ここに時間を設定する |
tabsr | タイマ開始を合図 |
udf | カウンタのアップ/ダウンの指定 |
ta番号ic | 番号0から4まで.割り込みを制御 |
ir_ta番号ic | 番号0から4まで.※レジスタ「ta番号ic」の中の割込要求ビット部分 |
ta番号mrレジスタとta番号レジスタは,次のように各ビットに機能が割り当てられていて,それぞれに適切に「1」「0」を書き込むことで,タイマー機能を設定できるようになっている.ta番号mrレジスタで動作モードや測定時間の単位を設定し,ta番号レジスタに設定された値×測定時間の単位分の時間を計測することになる.使用しているM16Cのマイコンボードでは,CPUは16MHzで動作しており,周期は62.5ナノ秒である.タイマー機能では,もっとも細かい時間設定をしても62.5ナノ秒単位で時間を計測することになる.
tabsrレジスタは,タイマーを起動するためのレジスタで,各ビットがタイマーひとつ分に対応している.そのしたのudfは,全タイマーをアップカウント(0, 1, 2,…)するか,ダウンカウント(5000, 4999, 4998,…)するかを設定するためのレジスタである.
ta番号icレジスタは,割り込み(後で説明)に関する設定をするためのレジスタである.このレジスタは下位4ビットだけ機能が割り当てられ,上位4ビットは何も機能がない.下3ビット(b0からb2)は割り込みレベル(同時に割り込みが発生したときの優先順位)を設定するためのものであり,本演習では使用しない.図に説明がないがb3に割り込み要求ビットが設定されており,タイマー機能によって一定時間間隔でこのビットが1に自動的にセットされる.sfr62a.hでは「ir_ta番号ic」として独立の変数として宣言している.
一秒に一回何かを実行する例を示す.マイコンの動作は人間の感覚に比べて極めて早い.使用しているM16Cのマイコンボードでは,CPUが16MHz(周期62.5ナノ秒)で動作している.この速度だと,実はM16Cのタイマー機能では1秒のように(マイコンにとっては)非常に長い時間をカウントするようなタイマー設定ができない.(ta0のカウント値が16bitなので65535までしか設定できないためである.)そのため,1/100秒のタイマー設定にして,タイマーが100回動作したら1秒分だとすればよい.
#include "sfr62a.h" #define PORTOUT 0xff #define LEDOFF 0xff #define LEDON 0x00 #define OFF 0x00 #define ON 0x01 #define CNT_TA0 (5000-1) #define CYCLE_TIME (63-1) #define COUNT1SEC 100 void main( void ) { unsigned char count = COUNT1SEC; unsigned char p7buf = LEDOFF; p7 = LEDOFF; pd7 = PORTOUT; //タイマの設定部分 udf = 0x00; // ダウンカウントに設定 ta0mr = 0x80; // タイマーのモードを設定 ta0 = CNT_TA0; // タイマーのカウント値を初期化 ta0ic = 0x00; // タイマー割り込み要求ビットをクリア tabsr = 0x01; // タイマーA0だけを開始 for( ; ; ) {//この括弧の中は1/100000秒に一回実行 if( ir_ta0ic == 1 ) //割り込み要求ビットがセットされた,つまり指定した時間(1/100秒)が経過した {//この括弧の中は1/100秒に一回実行 ir_ta0ic = 0; //割り込み要求ビットをクリア(次のタイマーのために) count--; if( count == 0 ) {//この括弧の中は1秒に一回実行 count = COUNT1SEC; /* ここに一秒に一回だけ実行したいことを書く*/ } } } }