2007年03月26日

プログラムの説明

あんまりたいした内容ではないのですが、eyecat-0.1.zipに含まれる eyecat-test.c についてポイントを解説しておきます。
読み手を想定して書いているわけではありません。-- 実はプログラムを引用して説明を書く練習だったりします。


平タスク

平タスクともメインループとも呼ばれる典型的な処理です。いろいろ凝った仕掛けを作ろうかと思ったこともありましたが、最近はもっぱらこの形式で書いています。注意点としては、イベントの中で止まらないようにすること。特にこのプログラムでは、LED の連続点灯になってしまうとマズイので注意が必要です。具体的に書くと getc() は入力データがないとき待ちになってしまうので、 can_getc(1) で読み込めるかどうか確認するとか...
あと、イベントに変数を使うときは volatile を付けること。これを忘れるとレジスタにコピーした値をずっと参照して、イベントが上がらないケースがあります。


int main(void)
{

/* set system_clock pre scaler 1/8 => 1/1 */
CLKPR = (1<<CLKPCE);
CLKPR = 0;

各種初期化

sei();

for(;;) {
wdt_reset();
poll();

if (イベント1) {
      イベント1の処理
}
if (イベント2) {
      イベント2の処理
}
:
}
}


タイマー処理

一定間隔である処理をさせたいとき使う処理に以下の set_timeout / check_timeout ってのを作って使っています。時間の定義は 最小の時間と最大の時間が int16_t の正の範囲(0-32767)に収まるようにプログラム毎に調整しています。ちなみに、変数とかの型は、uint8_t とか使ってサイズと signed/unsigned を明示するようこころがけています。-- こう書いておくと、プログラムの一部を PC にもっていってテストする場合に便利なのです。


static inline uint16_t get_time() {
return TCNT1;
}

static void set_timeout(uint8_t chan, uint16_t t) {
to_time[chan] = t + get_time();
to_flag[chan] = 1;
}

static int8_t check_timeout(uint8_t chan) {
if (to_flag[chan] && (to_time[chan]
         - (int16_t)(get_time()) <= 0)) {
to_flag[chan] = 0;
}
return !to_flag[chan];
}

使用例:
if(check_timeout(TO_DOT)) {
          :
set_timeout(TO_DOT, 24);
    }


詳しいコメント:

TCNT1を直接使えばよいものを get_time で ラップ(wrap)しているのは、ATtiny861 みたいな HIとLO が別々のレジスタになる拡張に対応できるようにしたため。

to_flagが冗長で無駄のように思えるかも知れません。以前は使っていなかったのですが、そうすると set_timeoutで最初の TIMEOUT を設定しないといけないので、フラグを使うようにしました。1bit の情報を扱うのに 1バイトも!使うのは無駄だと思う場合は、set_timeout/check_timeout を inline 化して to_flag を bitmap にする場合もあります。

timeoutの名前の由来は、UNIX。もともとは、timeout という関数で時間が来れば登録した関数を callするものですが、そこまでするとコードを小さくできないので set_/check_ という プレフィックスを付けた二組の関数にしました。もちろん 定期的な処理だけでなく(名前のとおり)一定の時間が立つのを待ち合わせるのにも使えます。

ボタンの処理


static uint8_t button_read() {
static uint8_t b1_state;

b1_state <<=1;
if (bit_is_clear(ROW2_PIN, ROW2)) {
b1_state |= 1;
}
if (b1_state == 0 || b1_state == 0xff) {
:
}
}


ざっくり簡略化すると上のような処理になっています。これはチャタリング除去の処理で、8回連続(120Hz なので、66ms の間)同じ値なら採用するというもの。
posted by すz at 21:18| Comment(0) | TrackBack(0) | USBアイキャッチャー
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/30760381
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック