H8/3687FとCMOS-EYEのバス接続及びシリアル接続
|
はじめに
ここでは H8/Tinyの中の、H8/3687Fを搭載したマイコンボード BTC065(ベストテクノロジー製) と浅草ギ研製CMOSイメージセンサーボードCMOS-EYEとの接続例を紹介します。
※このページで紹介する内容はあくまでも一例です。個別の作成のご相談ご質問はお答えできませんのでご了承下さい。このページと同じ内容についてのご質問についてはロボット掲示板にてお願いいたします。
用語について
このページで説明する用語について解説します。
CMOS-EYEはマイコンと接続することが前提となっております。以下の説明で「マイコン」と書いたところは、CMOS-EYEに接続するユーザー側のマイコンを示します。マイコン側の端子名は極力、そのマイコンのデータシートに書かれている名前を記載しています。
マイコンチップが載ったCPUボードを「マイコンボード」とします。マイコンボードの端子名は極力、そのマイコンボードの取扱説明に書かれている名称を記載しています。
CMOS-EYE上にも制御用のマイコンが搭載されていますが、これは「CMOS-EYE上のマイコン」とします。(バス接続時には特にこの「CMOS-EYE上のマイコン」を意識する必要はありません。)
CMOS-EYEからはいろいろな端子が出ています。アドレスを指定する端子の集まりを「アドレスバス」とします。又、データを指定したり受けたりする端子の集まりを「データバス」とします。
CMOS-EYEとH8/3687F
<CMOS-EYEについて>
CMOS-EYEは携帯電話用のCMOSカメラに、画像取り込み回路とSRAMを取り付けたもので、手持ちのマイコンなどと接続して小型の画像処理システムを構築できます。ロボットなどに搭載してスタンドアローンの自立型ロボットシステムを作るのに最適です。CMOS-EYEについては「CMOS-EYEの紹介・仕様・使い方」(以下「CMOS-EYEの紹介ページ」とする)のページに詳しく掲載しています。このCMOS-EYEの紹介ページはマニュアルも兼ねているので、使用前によく読んでください。特に、このページを読む前に、「ハードウェア仕様」「ピン配列」「バス接続での使い方」の節をよく読んでください。
<なぜ3687Fなのか?>
CMOS-EYEはシリアル命令による内蔵プログラムを使った画像処理も行えますが、本領を発揮するのはバス接続で高速に画像処理を行うパターンです。H8/Tinyの場合は、雑誌の付録にもなったH8/3694Fのマイコンボードがよく販売されていますが、バス接続を行うにはIO数が足りません。H8/3687Fであれば、CMOS-EYEとバス接続及びシリアル接続を行ってもまだ10本ほどIOの空きがありますので今回はこれを使ってみます。
また、H8/3687Fはデータシートを見る限りでは3.3Vでも駆動できるようです。これについては下で実験してみます。
<BTC-065について>
自分でチップの状態からマイコンシステムを作れる方も最近は(2006.8現在)増えてきましたが、多くの電子工作ホビーストやロボットビルダーは市販のマイコンボードを購入して使用していると思います。今回、H8/3687Fを選んだ理由としてはベストテクノロジー社(以下ベステクと略す)からマイコンボードが出ているということもありました。ベステクでは、マイコンの開発経験が少ない方でも比較的簡単にマイコンプログラミングを始められる「GDL」という開発ツールが無償で提供されています。メーカーのC言語のマイコン開発環境が数万円〜数十万円もするこのご時世で、¥4,600で、簡易とは言え、C言語開発環境が無償で使えるというのも魅力的です。
<GDL以外の開発環境を使う方、3687F以外のH8/Tinyを使う方>
アセンブラで開発できる方やGCCなどをインターネット上から取ってきて自分で開発環境を構築できる方、8687F以外のH8/Tinyを使う予定の方は、以降(CMOS-EYEとH8/3687F関連の別なページを含む)はプログラムロジックの参考程度に読んでいってください。個別のサンプルプログラムは作っておりませんのでご了承下さい。
3.3VでBTC065が動くか?のテスト
まず、スペックだけで検討してみます。
3687Fは3.3Vでも動きますが、BTC065全体では3.3V動作をさせると2つの問題が起きる可能性があります。
1つ目。BTC065にはH8/3687F以外にもいくつかのICが搭載されていますが、この中で、プログラムポートの電圧変換に使われているMAX3313というICのスペックが3.3V対応にはなっていませんでした。ということで問題が起きるとすると、「プログラムが書けなくなる」という可能性があります。
2つ目。H8/3687Fのデータシートを見ると、電源電圧が低くなると動作クロックも低くなるというものがありますが、BTC065上のクロックICは20MHzなので、「オーバークロックで動作しない」かもしれないという可能性があります。
下はデータシートの電気特性の抜粋です。これを見ると、3.3V動作時は10MHz程度までしか動かせないことになります。
と、2つの懸念材料がありましたが、結論を言うと、BTC065に3.3Vを入れても問題なく動きました。
テストの結果、プログラム書き込み時に20回に1回ぐらいの確率でプログラムが上手く書き込めない場合がありましたが、BTC065の電源を切り入りすると書き込めるようになります。クロックオーバーは、高速にSRAMにアクセスするプログラムを書いてテストしましたが、プログラムがBTC065にきちんと転送されれば問題なく動作していました。
浅草ギ研からはCMOS-EYEのオプションで5V変換ボードも出す予定ですが、ここでは、オーバースペックではありますが、3.3V動作でCMOS-EYEと直で動かすことにします。
尚、あくまでも仕様外の使い方なので、実際のロボットなどへの搭載時に5V変換をするかどうかは各自で判断してください。
H8/3687Fの端子の検討
<バス接続時に必要なIO(ここではUARTのRXとTXもつなぎます)>
B8/3687Fのデータシートと、BTC065マイコンボードの取説にある回路図を見ながら、CMOS-EYEと接続する端子を検討します。
とりあえず、データシートを見ながら以下のように端子を割り振ってみました。
<端子割り付け案(3687Fデータシートの概要の内部ブロック図より)>
TEST端子ですが、これはCMOS-EYEにはありません。後のページで、画像処理にかかった時間を計測するために利用することにした端子で、処理の前後にこの端子をHIGH/LOWさせてオシロスコープでその波形を観測して時間を測定しようと思います。(このページではそこまでいきません)。
BTC065ではプログラムをダウンロードするのにシリアルポートを1つ使用していますが、H8/3687Fはシリアルポートが2個ありますので空いている1つはCMOS-EYEと接続してシリアル命令も使えるように考えました。
H8/3687Fには入出力IO端子が45本、入力IO端子が8本あります。ほとんどのIOはCMOS-EYEへの出力なので、入力IOは使いません(使えません)が、この入力専用IOはADCも兼ねているので、CMOS-EYEを接続してもADCが8本空くことになります。
入出力IOのうち4つはシリアル通信で使いますので41本が自由に使えることになります。CMOS-EYEはバス接続時にIOを35本使いますので問題なく全ての端子を接続することができます。
実際の接続
下は、BTC065の取扱説明に書いてある回路図の抜粋です。CN1とCN2につなぐことになります。
CMOS-EYEからは3.3V電源出力が出ています。これは700mAぐらいまで供給できますが、BTC065はH8Tiny以外に小さいICが3個しかありませんので十分駆動できます。BTC065は本来5V動作のマイコンボードですが、この辺りは次の節で説明します。
今回はテストなので、CMOS-EYEとBTC065にヘッダピンを取り付けて、その間を一本づつコネクタで接続しました。その様子は下のようになります。写真の黄色い線のコネクタは2550コネクタというのを使ってます(浅草ギ研で販売してます)。このケーブルの作り方はこのページでやってますので参照してください。一本づつのコネクタだと配線を変えられるので実験に最適です。(使いまわしもできます。ブレッドボードの逆ですね。)
線はAWG24相当の太さのものを使ってますが、実際にロボットに組み込むときにはもっと細い線&小さいコネクタを使用した方が良いでしょう。
一応、板金パーツの図面も載せておきます。ご参考まで。サーボホーン用の穴をあけてありますので、ヨー軸方向にカメラを回転させることもできる、というものです(が実際に使うかどうかは?)。CMOS-EYEは2φ5mm長のスペーサとM2L8ネジあたりで止めています。これらはWILCOで買えます。
センサ部の取り付け金具はCMOS-EYEに付属しているものを使いました。
サンプルプログラム
操作の基本であるSRAMへのアクセスと、シリアル命令を送ってみるプログラムを作りました。全ソースプログラムはこちら
CMOS-EYE_H83687.c (右クリックで対象を保存)
これは、
1) 起動時にCMOS-EYEのSRAMの先頭アドレスに数値を書きこんでみる
2)書き込んだ数値を読み出して、違う番地に書き込んでみる
3)その後、10秒ごとにシャッターを切る(シリアル命令による)
という流れになります。この、読み書きと、シリアル命令が実装できれば、CMOS-EYEを使いこなすことができます。
以下、詳細を説明します。
サンプルプログラム−ヘッダーファイル
GDLに添付されているヘッダーファイル 3687.h を使っています。この中で、IOへアクセスする構造体などが記述されていますので、どのようにしてIOにアクセスするかはこのファイルの中をテキストエディタなどで見て、理解します。
ヘッダーファイルの一部
実際には、この下の方で、実際のハードウェアのIOアドレスが割り振られていて、st_io構造体はIOという名称で0xFFD0番地に割り振られているのがわかります。
ここから、例えば特殊レジスタPUCR1にアクセスしたい場合は
バイトアクセスの場合−>IO.PUCR1.BYTE
ビットアクセスでビット2にアクセスの場合−>IO.PUCR1.BIT.B2
というようになります。
このヘッダーファイルは、使っている環境によって違う場合もあるので、GDL以外の環境でプログラムをする場合はその環境のヘッダーファイルを確認して下さい。
ということで、とりあえず、3687.hをインクルードします。
サンプルプログラム−名称定義
CMOS−EYEとアクセスする場合に、IO.xxx.xxxという名称ではわかりづらいので、CMOS−EYEの端子の名称で、H8側の端子を定義しました。
アドレスは19本必要なので、ポート1,3,7の3つをあわせて19本にしています。これらを使ったアドレッシングについては次で説明します。
IO方向ですが、データバスだけは双方向の通信を行うので、入力と出力を切り替える必要があります。よって、入出力の方向を設定する、ポート6のポートコントロールレジスタにDATA_DIRという名称をつけてます。
各ポートの、ポートコントロールレジスタは 0で入力 1で出力 となっています。初期値は0入力になっています。データシートを見なくてもわかるように、ここでは INPUT OUTPUT の名称をつけてます。よって、たとえば、データバスの方向を変えたい場合は
DATA_DIR = ALL_OUTPUT;
のように記述できます。
サンプルプログラム−アドレスセット
CMOS−EYEにアドレスを指定するのに、3つのポートを使っており、アドレッシングは少々複雑ですので関数化しました。
ポート1,3,7の空いている端子を活用していますが、割付イメージは次のようになります。
アドレスを指定する変数の型ですが、型は8ビットの倍数単位なので、8,16,32ビットの型がありますが、19ビット以上は32ビットになりますので long
long 型になります。このアドレスを分解して各ポートに対応させたのが下の関数になります。0x...はビットを抜き出すためのマスクで、1とアンドを取ることでマスクをかけています。
各ポートは8ビット長なので、ポートに代入する際には、一応 (unsigned char)を先頭につけて8ビットに型変換しています。
※これはあくまでも一例です。今回の配線の場合にはこのようになります。ポートのビット抜けが無いようなマイコン(AVRや、1ポートが16ビット長のマイコンとか)の場合はもう少し簡単になるでしょう。
サンプルプログラム−IO初期化
IO初期化部分です。各端子のHIGH/LOWの初期値と、入出力の方向を指定します。
−−−アドレスバス設定−−−
アドレスバスは、H8->CMOS-EYEへアドレス指定しか行わないので、全て出力に設定します。
−−−データバス設定−−−
データバスは入出力切替で使いますが、ICの端子同士が出力同士になると破損する可能性があるので、とりあえず入力に設定しておきます。動作中は、CMOS-EYEのSRAMの中身を読み出すときに、CMOS−EYE側のデータバスが出力になりますので、その時にこちら側が出力にならないように注意して下さい。
−−−シリアルポート設定−−−
H8のIO端子の中には、汎用IO機能の他に特殊な機能がある端子もあります。2つあるシリアル端子はどちらも使いますので、これらを特殊機能に設定します。この部分は、データシートの「I/Oポート」の部分と「シリアルコミュニケーションインターフェイス3」の部分両方を読む必要があります。(詳しくはデータシートにて確認)
−−−SCI3_2のシリアル設定−−−
GDLのヘッダファイルでは、2つあるシリアル通信機能は SCI3 と SCI3_2 という名称がつけられています。SCI3の方はプログラムをダウンロードするときに、BTC065の内蔵ダウンロードプログラムで自動的に設定されます。SCI3_2の方は今回、CMOS-EYEと通信しますのでユーザー側で設定します。設定内容はソースのコメントを参照してください。設定方法と設定値についてはデータシートの「シリアルコミュニケーションインターフェイス3」の部分に詳しく書いてあります。
−−−コントロール線−−−
ポート5はSRAMコントロール(CE,WE,OE)と、CMOS-EYEへのモード指定で使用しますので、全部出力に設定します。PMR5はポート5の特殊機能を使うかどうかの設定ですが、初期値で全部0(汎用IO指定)になってますので、この設定は無くてもかまいません(念のため入れた)。
ポート2はその他のCMOS-EYEの端子につないでいます。BSYだけはCMOS-EYEがビジーかどうかの判定をする線、つまりCMOS−EYE側は出力なので、こちら側は入力になっています。P21/RXDはプログラム用のシリアル受信端子で、プログラムダウンロード時にBTC065の内蔵ダウンロードプログラムで自動設定されますので設定は不要ですが、ここでは一応、RXを入力に設定してます。
−−−タイマ設定−−−
ウェイト用にタイマVを使っています。この部分はベステクのサンプルプログラムそのままです。
−−−初期値−−−
初期値では、
1)アドレスを0番地指定
2)モードを80x60白黒
3)SRAMコントロールを全て無効
4)シャッターを待機状態
にしています。
シャッター端子のSTですが、これは撮影時以外はHIGHにしておかないとCMOS−EYEが撮影しっぱなし(常にBUSY状態でLEDが点きっぱなし)になるので、初期値は必ずHIGHにして下さい。
モード指定やSRAMコントロールについては「CMOS-EYEの紹介」のページで説明しています。
サンプルプログラム−起動部分
では設定関係の部分を作ったところで、main関数を作り、実際にCMOS−EYEを動かしてみましょう。始めにIO設定などをして、CMOS−EYEに初期状態を決めますが、ここでポイントは、CMOS−EYEの起動に3秒ほど時間がかかるということです。ここは重要です。よって、マイコン側のプログラムを起動する時に、main関数の冒頭で3秒ほどウェイトをかける必要があります。これを行わないと、特に、モード設定などがおかしな値になるので注意して下さい。(3秒以降にモード設定をしなおせばきちんと設定はされますが。)
下はそのmainの冒頭部分と、ウェイト関数です。ウェイト関数はベステクのサンプルそのままです。
行190で、起動直後に3秒待っています。
M0−M2による撮影モード指定ですが、設定を変更した後は設定が反映されるまで100mSほどかかりますので余裕をみて200mSウェイトをかけます。
サンプルプログラム−SRAMへのデータ書き込み
まずはSRAMにアクセスしてなんらかのデータを書き込んで見ます。
CMOS−EYE上のSRAMのアクセス方法についてはCMOS−EYEの紹介ページで詳しく説明しています。
おおまかな流れとしては、
1)SRAMを有効にする
2)書き込むアドレスを指定(出力)する
3)データバスに値を出力する
4)WEをLOWにする
5)WEをHIGHに戻す
という手順になります。
上のプログラムをmainの中に入れて実行すると、SRAMの先頭から11個のアドレスに0,1,2,3...の数値が記録されます。
SRAMの中身を確認するのに、浅草ギ研で配布している CMOS−Viewer を使うのが良いでしょう。このソフトはPCとCMOS−EYEをつないで、シリアル命令を出したり、SRAMの中身を表示したりできます。
実際にCMOS−EYE Viewer で見たのが下の写真になります。
「データ読み取り」ボタンを押すと、アドレスとデータ長で指定した範囲を表示します。意図したとおりの値になっています。
サンプルプログラム−SRAMへのデータ読み込み
次にSRAMの内容を読み込んで見ます。読み込んだデータは、再度、SRAMの中に書き込んで、CMOS−EYE Viewerで確認してみます。
読み込みの流れは
1)SRAMを有効にする
2)読み込むアドレスを指定(出力)する
3)OEをLOWにする
4)データバスに表れるデータを読み込む
5)OEをHIGHに戻す
という手順になります。
今回は読み書きするので、データバスのIO方向も切替ます。プログラムは次の通り、
下は CMOS−EYE Viewer でSRAMの内容を確認した結果です。
読み込んだデータを、+10した結果が20番地以降に記録されていました。
サンプルプログラム−シリアル通信による命令実行
次に、シリアル通信でCMOS−EYE内蔵プログラムを実行させてみます。一番簡単な命令に「撮影」命令があります。これを送るとCMOS−EYEは撮影を行います。シリアル通信命令については「CMOS-EYEの紹介」のページで説明しています。
データの送信ですが、H8の場合はTDRレジスタにデータをセットすると自動的にそのデータがTX端子から送信されます。ポイントですが、送信修了前にデータをセットしないように、送信データをセットしても良いか確認してからセットする必要があります。これはSSRレジスタのTDREビットを監視します。この辺りはデータシートに書いてありますので詳しくはそちらを参照願います。
ということで、10秒おきに撮影を行った結果が次のようになりました。
送信データの配列が17個になってますが、CMOS−EYEへの送信命令は最大でこのぐらいの長さのもありますので一応17個で作っています。この命令送信部分は冗長的なデータが多いので関数化した方が良いでしょう。
撮影時にはCMOS−EYEがBUSYになってLEDが点灯しますので、この直後にCMOS−EYE Viewerで画面を確認したのが次の写真になります。
画面の設定は、起動時のところで設定しているように M0=LOW M1=LOW M2=HIGH としているので80x60カラーで撮影されます。(画面モードの設定値は「CMOS-EYEの紹介」のページで説明しています。)
<撮影風景(カーテンを閉め切った室内)>
<Viewerで確認した結果>
このようにきちんと命令が実行されて、撮影がされました。
この画面ですが、全体的に青っぽくなっています。これは、カメラのオートホワイトバランスが効いている為、画面に赤が多いと、赤が補正されて弱くなるためです。シリアル命令ではオートホワイトバランスをオフにすることもできますので、カラーの判定処理の場合にはオフにした方が良いでしょう。
自動露出も効いているので、少々暗い環境でも画像ははっきりと撮影できます。(ダイナミックレンジが有効に活用される)
このようなことからも、バス接続とシリアル接続両方で接続するのが望ましいです。
おわりに
このように、H8TinyでもIOが足りて入ればCMOS−EYEを動かすことができます。次は色判定について解説します。
2006年8月17日
|
|
|