目次

デバッグシステム設計

 デバッグは、3段階に区切って考えます。

 各デバッグを説明します。


ハードウエアデバッグ

 全ハードウエア動作が設計通りかをテスト、デバッグします。  ブロック図を見て、テスト・デバッグ項目を考えます。  4種類のアクチュエータがあるので、電圧3Vと0Vを与え  以下の内容をテストします。  サーボモータは、タイマー割込みを利用してテストしなければ  ならないので、実際は3種類のアクチュエータになります。  このテストで判断できるのは、以下です。  3種類のパルスエンコーダがあるので、クロックジェネレータで  パルスを生成し、入力回路にブザーを接続して音で確認します。  以下の内容を確認します。  2種類のプッシュスイッチがあるので、マルチメータで  出力電圧を測ります。  以下の内容を確認します。  接続するカメラは、シリアルインタフェースを利用しなければ  テストできないので、ソフトウエアデバッグで検討します。  ハードウエアが仕様通りの動作をした段階で、ソフトウエアに  よるデバッグに移ります。

ソフトウエアデバッグ

 ハードウエアが仕様通りの動作をした段階で、ソフトウエアに  よるデバッグに移ります。  パーソナルコンピュータ上のCUIで動作確認後、マイコンのファーム  ウエアに組込みます。  モータドライブ   モータは、PWMを利用して回転数を制御します。   MCRに関する書籍をみると、H8の内蔵モジュールを利用して   お手軽に記述してあります。自分の場合は、内蔵モジュール   を利用しないで、単純なタイマー割込みの応用としています。   PWMは、ある1周期の時間内に、Hレベルがどれだけあったか   だけなので、カウンタと値を入れた変数を比較し、1を出すか   0を出すかを決めます。   コードで書くと、非常に単純です。 dummy = 0 ; if ( pcnt <= rcntx ) { dummy |= 0x01 ; }  PORT = dummy ;   このコードは、変数pcntにカウンタの値に入れておき   変数rcntxと比較し、1を出すか0を出すかを決めます。   出力の値を決めれば、ポートに出力します。   カウンタの値を0〜99までとすると、値の増加と初期化   操作は次のように指定します。 pcnt++ ; if ( pcnt == 100 ) { pcnt = 0 ; }   このままでは、PWMの波形を操作できないので、0に戻す   ときに、外部で設定した比較値を入力します。 pcnt++ ; if ( pcnt == 100 ) { pcnt = 0 ;  rcntx = rcnt ; }   このままでは、PWMの波形を操作できないので、0に戻す   ときに、外部で設定した比較値を入力します。   今回は、4種類のPWM波形が必要なので、比較値を入れる   変数を4個用意します。 dummy = 0 ; if ( pcnt <= rcntx ) { dummy |= 0x01 ; } if ( pcnt <= lcntx ) { dummy |= 0x02 ; } if ( pcnt <= scntx ) { dummy |= 0x04 ; } if ( pcnt <= icntx ) { dummy |= 0x08 ; }  PORT = dummy ; pcnt++ ; if ( pcnt == 100 ) { pcnt = 0 ; rcntx = rcnt ; lcntx = lcnt ; scntx = scnt ; icntx = icnt ; }   図で示すと、次のようになります。   CUIのプログラムリストです。 #include <stdio.h> typedef unsigned char UBYTE ; typedef unsigned short UWORD ; #define OFF 0 #define ON OFF+1 UBYTE port ; UBYTE pcnt ; UBYTE rcnt ; UBYTE lcnt ; UBYTE scnt ; UBYTE icnt ; UBYTE rcntx ; UBYTE lcntx ; UBYTE scntx ; UBYTE icntx ; #define PORT port void binary_display(UBYTE x) { int i ; for ( i = 7 ; i > -1 ; i-- ) { putchar('0'+((x >> i) & 1)); } putchar('\n'); } void timer_handler(void) { UBYTE dummy ; /* default */ dummy = 0 ; /* compare */ if ( pcnt <= rcntx ) { dummy |= 0x01 ; } if ( pcnt <= lcntx ) { dummy |= 0x02 ; } if ( pcnt <= scntx ) { dummy |= 0x04 ; } if ( pcnt <= icntx ) { dummy |= 0x08 ; } /* impress */ PORT = dummy ; /* update counter */ pcnt++ ; if ( pcnt == 100 ) { pcnt = 0 ; rcntx = rcnt ; lcntx = lcnt ; scntx = scnt ; icntx = icnt ; } } void main(void) { int i ; pcnt = 0 ; for ( i = 0 ; i < 250 ; i++ ) { printf("pcnt = %03d ",pcnt) ; timer_handler(); binary_display( PORT ); if ( i == 10 ) { rcnt = 10 ; lcnt = 20 ; scnt = 30 ; icnt = 40 ; } if ( i == 150 ) { rcnt = 50 ; lcnt = 40 ; scnt = 15 ; icnt = 10 ; } } }   結果は、以下となり、PWMのDuty比が変化しているのを   確認できました。 pcnt = 000 00001111 pcnt = 001 00000000 pcnt = 002 00000000 pcnt = 003 00000000 pcnt = 004 00000000 pcnt = 005 00000000 pcnt = 006 00000000 pcnt = 007 00000000 pcnt = 008 00000000 pcnt = 009 00000000 pcnt = 010 00000000 pcnt = 011 00000000 pcnt = 012 00000000 pcnt = 013 00000000 pcnt = 014 00000000 pcnt = 015 00000000 pcnt = 016 00000000 pcnt = 017 00000000 pcnt = 018 00000000 pcnt = 019 00000000 pcnt = 020 00000000 pcnt = 021 00000000 pcnt = 022 00000000 pcnt = 023 00000000 pcnt = 024 00000000 pcnt = 025 00000000 pcnt = 026 00000000 pcnt = 027 00000000 pcnt = 028 00000000 pcnt = 029 00000000 pcnt = 030 00000000 pcnt = 031 00000000 pcnt = 032 00000000 pcnt = 033 00000000 pcnt = 034 00000000 pcnt = 035 00000000 pcnt = 036 00000000 pcnt = 037 00000000 pcnt = 038 00000000 pcnt = 039 00000000 pcnt = 040 00000000 pcnt = 041 00000000 pcnt = 042 00000000 pcnt = 043 00000000 pcnt = 044 00000000 pcnt = 045 00000000 pcnt = 046 00000000 pcnt = 047 00000000 pcnt = 048 00000000 pcnt = 049 00000000 pcnt = 050 00000000 pcnt = 051 00000000 pcnt = 052 00000000 pcnt = 053 00000000 pcnt = 054 00000000 pcnt = 055 00000000 pcnt = 056 00000000 pcnt = 057 00000000 pcnt = 058 00000000 pcnt = 059 00000000 pcnt = 060 00000000 pcnt = 061 00000000 pcnt = 062 00000000 pcnt = 063 00000000 pcnt = 064 00000000 pcnt = 065 00000000 pcnt = 066 00000000 pcnt = 067 00000000 pcnt = 068 00000000 pcnt = 069 00000000 pcnt = 070 00000000 pcnt = 071 00000000 pcnt = 072 00000000 pcnt = 073 00000000 pcnt = 074 00000000 pcnt = 075 00000000 pcnt = 076 00000000 pcnt = 077 00000000 pcnt = 078 00000000 pcnt = 079 00000000 pcnt = 080 00000000 pcnt = 081 00000000 pcnt = 082 00000000 pcnt = 083 00000000 pcnt = 084 00000000 pcnt = 085 00000000 pcnt = 086 00000000 pcnt = 087 00000000 pcnt = 088 00000000 pcnt = 089 00000000 pcnt = 090 00000000 pcnt = 091 00000000 pcnt = 092 00000000 pcnt = 093 00000000 pcnt = 094 00000000 pcnt = 095 00000000 pcnt = 096 00000000 pcnt = 097 00000000 pcnt = 098 00000000 pcnt = 099 00000000 pcnt = 000 00001111 pcnt = 001 00001111 pcnt = 002 00001111 pcnt = 003 00001111 pcnt = 004 00001111 pcnt = 005 00001111 pcnt = 006 00001111 pcnt = 007 00001111 pcnt = 008 00001111 pcnt = 009 00001111 pcnt = 010 00001111 pcnt = 011 00001110 pcnt = 012 00001110 pcnt = 013 00001110 pcnt = 014 00001110 pcnt = 015 00001110 pcnt = 016 00001110 pcnt = 017 00001110 pcnt = 018 00001110 pcnt = 019 00001110 pcnt = 020 00001110 pcnt = 021 00001100 pcnt = 022 00001100 pcnt = 023 00001100 pcnt = 024 00001100 pcnt = 025 00001100 pcnt = 026 00001100 pcnt = 027 00001100 pcnt = 028 00001100 pcnt = 029 00001100 pcnt = 030 00001100 pcnt = 031 00001000 pcnt = 032 00001000 pcnt = 033 00001000 pcnt = 034 00001000 pcnt = 035 00001000 pcnt = 036 00001000 pcnt = 037 00001000 pcnt = 038 00001000 pcnt = 039 00001000 pcnt = 040 00001000 pcnt = 041 00000000 pcnt = 042 00000000 pcnt = 043 00000000 pcnt = 044 00000000 pcnt = 045 00000000 pcnt = 046 00000000 pcnt = 047 00000000 pcnt = 048 00000000 pcnt = 049 00000000 pcnt = 050 00000000 pcnt = 051 00000000 pcnt = 052 00000000 pcnt = 053 00000000 pcnt = 054 00000000 pcnt = 055 00000000 pcnt = 056 00000000 pcnt = 057 00000000 pcnt = 058 00000000 pcnt = 059 00000000 pcnt = 060 00000000 pcnt = 061 00000000 pcnt = 062 00000000 pcnt = 063 00000000 pcnt = 064 00000000 pcnt = 065 00000000 pcnt = 066 00000000 pcnt = 067 00000000 pcnt = 068 00000000 pcnt = 069 00000000 pcnt = 070 00000000 pcnt = 071 00000000 pcnt = 072 00000000 pcnt = 073 00000000 pcnt = 074 00000000 pcnt = 075 00000000 pcnt = 076 00000000 pcnt = 077 00000000 pcnt = 078 00000000 pcnt = 079 00000000 pcnt = 080 00000000 pcnt = 081 00000000 pcnt = 082 00000000 pcnt = 083 00000000 pcnt = 084 00000000 pcnt = 085 00000000 pcnt = 086 00000000 pcnt = 087 00000000 pcnt = 088 00000000 pcnt = 089 00000000 pcnt = 090 00000000 pcnt = 091 00000000 pcnt = 092 00000000 pcnt = 093 00000000 pcnt = 094 00000000 pcnt = 095 00000000 pcnt = 096 00000000 pcnt = 097 00000000 pcnt = 098 00000000 pcnt = 099 00000000 pcnt = 000 00001111 pcnt = 001 00001111 pcnt = 002 00001111 pcnt = 003 00001111 pcnt = 004 00001111 pcnt = 005 00001111 pcnt = 006 00001111 pcnt = 007 00001111 pcnt = 008 00001111 pcnt = 009 00001111 pcnt = 010 00001111 pcnt = 011 00000111 pcnt = 012 00000111 pcnt = 013 00000111 pcnt = 014 00000111 pcnt = 015 00000111 pcnt = 016 00000011 pcnt = 017 00000011 pcnt = 018 00000011 pcnt = 019 00000011 pcnt = 020 00000011 pcnt = 021 00000011 pcnt = 022 00000011 pcnt = 023 00000011 pcnt = 024 00000011 pcnt = 025 00000011 pcnt = 026 00000011 pcnt = 027 00000011 pcnt = 028 00000011 pcnt = 029 00000011 pcnt = 030 00000011 pcnt = 031 00000011 pcnt = 032 00000011 pcnt = 033 00000011 pcnt = 034 00000011 pcnt = 035 00000011 pcnt = 036 00000011 pcnt = 037 00000011 pcnt = 038 00000011 pcnt = 039 00000011 pcnt = 040 00000011 pcnt = 041 00000001 pcnt = 042 00000001 pcnt = 043 00000001 pcnt = 044 00000001 pcnt = 045 00000001 pcnt = 046 00000001 pcnt = 047 00000001 pcnt = 048 00000001 pcnt = 049 00000001  パルスエンコーダ   パルスエンコーダは、回転体の動きでパルスを発生します。   パルス数は、マイコンに内蔵されているカウンタに格納します。   これらのカウンタの値を入力し、ゼロクリアできれば充分です。   パルス数には、左右のモータと計測用の3種類があります。   これらのパルス数を格納する変数を用意し、ゼロクリアと変数値   を返す関数を用意して確認します。   CUIのプログラムリストです。 #include <stdio.h> typedef unsigned char UBYTE ; typedef unsigned short UWORD ; #define OFF 0 #define ON OFF+1 #define P_LEFT_MOTOR 0x00 #define P_RIGHT_MOTOR 0x01 #define P_MEASURE 0x02 void binary_display(UBYTE x) { int i ; for ( i = 7 ; i > -1 ; i-- ) { putchar('0'+((x >> i) & 1)); } putchar(' '); } UWORD itu0tnct ; UWORD itu1tnct ; UWORD itu2tnct ; void clear_pulse(UBYTE x) { if ( x== P_LEFT_MOTOR ) { itu0tnct = 0 ; } if ( x== P_RIGHT_MOTOR ) { itu1tnct = 0 ; } if ( x== P_MEASURE ) { itu2tnct = 0 ; } } UWORD get_pulse(UWORD x) { UWORD result ; result = 0 ; if ( x== P_LEFT_MOTOR ) { result = itu0tnct ; } if ( x== P_RIGHT_MOTOR ) { result = itu1tnct ; } if ( x== P_MEASURE ) { result = itu2tnct ; } return result ; } void main(void) { clear_pulse(P_LEFT_MOTOR); clear_pulse(P_RIGHT_MOTOR); clear_pulse(P_MEASURE); printf("LEFT_MOTOR : %d\n",get_pulse(P_LEFT_MOTOR)); printf("RIGHT_MOTOR: %d\n",get_pulse(P_RIGHT_MOTOR)); printf("MEASURE : %d\n",get_pulse(P_MEASURE)); itu0tnct = 100 ; itu1tnct = 200 ; itu2tnct = 300 ; printf("LEFT_MOTOR : %d\n",get_pulse(P_LEFT_MOTOR)); printf("RIGHT_MOTOR: %d\n",get_pulse(P_RIGHT_MOTOR)); printf("MEASURE : %d\n",get_pulse(P_MEASURE)); }   結果は、以下となり、ゼロクリアと参照を確認できました。    LEFT_MOTOR : 0    RIGHT_MOTOR: 0    MEASURE : 0    LEFT_MOTOR : 100    RIGHT_MOTOR: 200    MEASURE : 300  スイッチ   タクタイルスイッチは、ポートBのビット7、6に接続します。   ある1バイトの変数のビット7、6の値を00、01、10、11に   設定して、対応する状態を数値で返してテストします。   関数名をget_triggerとし、返す数値はマクロ定義します。   #define TRG_NONE 0   #define TRG_STOP 1   #define TRG_START 2   ビット値の組み合わせと、返値の対応は、以下とします。   H8のコンパイラとの違いを変数定義で吸収し、次のように定義します。 UBYTE get_trigger(void) { UBYTE tmp ; UBYTE result ; /* get switch state */ /* tmp = PB.DR.BYTE ; */ tmp = bport ; tmp >>= 6 ; tmp &= 3 ; /* judge */ result = TRG_NONE ; if ( tmp == TRG_START ) { result = TRG_START ; } if ( tmp == TRG_STOP ) { result = TRG_STOP ; } return result ; }   テスト用のプログラムコード全体は、以下です。 #include <stdio.h> typedef unsigned char UBYTE ; typedef unsigned short UWORD ; #define OFF 0 #define ON OFF+1 void binary_display(UBYTE x) { int i ; for ( i = 7 ; i > -1 ; i-- ) { putchar('0'+((x >> i) & 1)); } putchar(' '); } UBYTE bport ; #define TRG_NONE 0 #define TRG_STOP 1 #define TRG_START 2 UBYTE get_trigger(void) { UBYTE tmp ; UBYTE result ; /* get switch state */ /* tmp = PB.DR.BYTE ; */ tmp = bport ; tmp >>= 6 ; tmp &= 3 ; /* judge */ result = TRG_NONE ; if ( tmp == TRG_START ) { result = TRG_START ; } if ( tmp == TRG_STOP ) { result = TRG_STOP ; } return result ; } void show_pattern(UBYTE x) { switch (x) { case TRG_START : puts("TRG_START") ; break ; case TRG_STOP : puts("TRG_STOP") ; break ; case TRG_NONE : puts("TRG_NONE") ; break ; default : puts("???"); break ; } } void main(void) { UBYTE tmp ; UBYTE i ; for ( i = 0 ; i < 8 ; i++ ) { bport = (1 << i) ; binary_display( bport ); tmp = get_trigger() ; binary_display( tmp ); show_pattern( tmp ); } bport = 0xc0 ; binary_display( bport ); tmp = get_trigger() ; binary_display( tmp ); show_pattern( tmp ); }   結果は、以下で動作を確認できました。   2進数の左が与えたパターン、右がパターンをシフトして   得られる値、文字列が判定した数値です。 00000001 00000000 TRG_NONE 00000010 00000000 TRG_NONE 00000100 00000000 TRG_NONE 00001000 00000000 TRG_NONE 00010000 00000000 TRG_NONE 00100000 00000000 TRG_NONE 01000000 00000001 TRG_STOP 10000000 00000010 TRG_START 11000000 00000000 TRG_NONE  カメラ under construction  シリアルインタフェース under construction

ドライブデバッグ

 パーソナルコンピュータ上で、かなりの部分のソフトウエアを  デバッグできます。しかし、マイコンのファームウエアに組込む  と、バグが入るのは避けられません。  実際に走行しているときの内部情報を、LCDに表示させます。  LCDドライブ under construction
目次

inserted by FC2 system