目次

スキャナ制御ファームウエア

 回路図を作成したので、ライントレースロボットで使う
 スキャナ制御用ファームウエアを設計します。

 このファームウエアは、1,024回、データを入力して
 リニアイメージセンサが出力する論理値を記憶して
 出力します。

 論理値出力Voutは、φ1の立ち上がりエッジでと規定されています。
 Enable信号がHのときに、Voutを記憶します。

 スキャナからは、2,094個の論理値が出力されますが、半分の
 1,047個を捕捉します。この1,047のうち、最初の16と最後の7
 ビットは不要なので、これらを除いた1,024個の情報を扱います。
 128の整数倍の位置にある論理値を8個結合し、センサーデータ
 にします。

 有効なVoutが出力されていることは、EnableがHのときなので
 シフトレジスタで、L→Hをとらえて、シーケンサを動かします。



 0〜1024回目の処理を考えます。
 データ入力を、次のシーケンスで実行します。
  1. SHの立ち上がりエッジ補足しカウンタイネーブル
  2. φ1の立ち上がりエッジでセンサーデータ入力
  3. 指定されたカウンタ値でEnableがHならば、シフトレジスタにデータ入力
  4. カウンタの値が1024ならば、8ビットセンサーデータを出力
  5. 1にもどる
 φ1の立ち上がりエッジ補足は、シフトレジスタを利用します。  利用するマイコンは、ATtiny2313を選びました。  SHの立ち上がりエッジ捕捉で、内部カウンタをイネーブル  φ1の立ち上がりエッジ捕足で、データ入力トリガー生成  として対応します。  8ビットのシフトレジスタに、入力データを入れるかは  Enableの論理値で決定します。  無限ループの中で、次の処理を実行します。  ソースコードにまとめます。 #include <avr/io.h> #include <avr/interrupt.h> typedef unsigned char UBYTE ; typedef unsigned short UWORD ; #define OFF 0 #define ON OFF+1 #define SH_BIT 2 #define CLKA_BIT 3 #define ENABLE_BIT 5 volatile UWORD scnt ; volatile UBYTE shsft ; volatile UBYTE clockasft ; volatile UBYTE sensor ; volatile UBYTE tmp ; volatile UBYTE sdata ; #define NO 0 #define YES NO+1 #define MASK01 0x01 #define MASK03 0x03 #define LAST 1050 /*--------------------------------*/ /* Insert user functions protoype */ /*--------------------------------*/ void user_initialize(void); /*------*/ /* main */ /*------*/ int main(void) { /* initialize port and variables */ user_initialize(); /* endless loop */ while ( ON ) { /* get signals */ tmp = PIND ; /* shift */ shsft <<= 1 ; clockasft <<= 1 ; /* mask */ shsft &= MASK03 ; clockasft &= MASK03 ; /* store */ if ( tmp & (1 << SH_BIT) ) { shsft |= ON ; } if ( tmp & (1 << CLKA_BIT) ) { clockasft |= ON ; } /* judge SH rising edge */ if ( shsft == 0x01 ) { scnt = 0 ; sensor = 0 ; } /* judge CLOCKA rising edge */ if ( clockasft == MASK01 ) { scnt++ ; if ( scnt == LAST ) { scnt = 0 ; } } /* get data */ sdata = 0 ; if ( tmp & 0x30 ) { sdata |= ON ; } /* store */ if ( tmp & (1 << ENABLE_BIT) ) { switch ( scnt ) { case 79 : sensor <<= 1 ; sensor |= sdata ; break ; case 207 : sensor <<= 1 ; sensor |= sdata ; break ; case 335 : sensor <<= 1 ; sensor |= sdata ; break ; case 463 : sensor <<= 1 ; sensor |= sdata ; break ; case 591 : sensor <<= 1 ; sensor |= sdata ; break ; case 719 : sensor <<= 1 ; sensor |= sdata ; break ; case 847 : sensor <<= 1 ; sensor |= sdata ; break ; case 975 : sensor <<= 1 ; sensor |= sdata ; break ; default : break ; } } /* impress */ if ( scnt == 1000 ) { PORTB = sensor ; } } /* dummy */ return 0 ; } /*-----------------------*/ /* Insert user functions */ /*-----------------------*/ void user_initialize(void) { /* PORT B */ PORTB = 0b00000000 ; /* 00000000 */ DDRB = 0b11111111 ; /* oooooooo */ /* PORT D */ PORTD = 0b00001100 ; /* 00000000 */ DDRD = 0b10000011 ; /* oiiiiioo */ /* clear */ scnt = 0 ; shsft = 0 ; clockasft = 0 ; sensor = 0 ; }  入力データの前後には、画素でないデータが存在しますが  有効な1024画素の中から8画素を入手する方法を取ります。  カウンタの値が128の奇数倍になるのは、カウンタの値が  1024になるまでに、いくつあるのかは、AWKで計算しました。 { # calculate location result = $1 * $2 ; # set area center result = result + $3 ; # skip dummy data result = result + $4 ; # show printf("%s => %d \n",$0,result); }  元になるテキストファイルの内容は、以下。 0 128 64 15 1 128 64 15 2 128 64 15 3 128 64 15 4 128 64 15 5 128 64 15 6 128 64 15 7 128 64 15  このスクリプトで、次のように8回分の処理が  なされていることを確認できます。 0 128 64 15 => 79 1 128 64 15 => 207 2 128 64 15 => 335 3 128 64 15 => 463 4 128 64 15 => 591 5 128 64 15 => 719 6 128 64 15 => 847 7 128 64 15 => 975
目次

inserted by FC2 system