R8Cの機能を一通り実装、テストしている。
今回は、コンパレータークラス。
テストプログラムでは、ICOMP3、IVREF3 を電圧比較をして、その結果、LEDの点滅速度が変わると言うもの。
※実験では、REF側に、VCCを1/2に分圧し、COMP側にボリュームを接続、確認した。
R8Cには2チャネルのコンパレーターがある、機能的には、単純な物だが、割り込みを使った時に、実行する
処理をどのような構成にするか、考えてみた。
以前にタイマークラスを実装した時に、タイマー割り込みから、何らかの処理を実行できるように、
void (*task_)(void);
実行ポインターを用意した、ところが、こんな事をすると、コンパイラは、「task_」で何が実行されるか不明
な為、メイン側で利用しているライブラリーのワークを全てスタックに積むようコードを生成する。
※タスク内で、メイン側と同じライブラリーを使った場合に備える為で、強引な方法だが、動作は正しい。
しかし、これでは、スタックが直ぐに限界を超え深くなるのは容易に想像出来る、その為、「実行ポインター」
でのタスク管理は不採用とした。
そこで、コンパイル時に静的な関数が実行できるような仕組みを追加した。
関数オブジェクトを使い。
class task {
public:
void operator() () {
.....
}
};
()オペレーター内に、実行したい手続きを実装して、それをテンプレートの引数とする。
関数オブジェクト内の手続きが何も無い場合、コンパイラは、その部分一切を削除する。
template <class TASK1, class TASK2>
class comp_io {
static TASK1 task1_;
static TASK2 task2_;
public:
static INTERRUPT_FUNC void itask1() {
task1_();
WCB1INTR.WCB1F = 0;
}
.....
};
これなら、コンパイラが、テンプレートクラスを展開する時に、割り込み内手続きを考慮するので、ライブラリー
で使われる変数の退避も最小限となる。
-----
そして、R8CのI/O定義は、ほぼ全てを網羅した。