目次
前
次
デバッグシステム設計
デバッグは、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
ビット値の組み合わせと、返値の対応は、以下とします。
- 00 → TRG_NONE
- 01 → TRG_STOP
- 10 → TRG_START
- 11 → TRG_NONE
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
目次
前
次