昨年からFreescaleの動向がちょっと面白い。FreescaleというのはMotorolaの半導体部門が独立した会社で、日本では東京の目黒に本社、仙台に研究開発センター、名古屋に営業所と品質・テストセンター、大坂に営業所をそれぞれ開設している。同社はPowerPC G4に代表されるPowerPC系CPUや、このPowerPCを組み込んだ、ブロードバンドルータに良く使われるPowerQUICCとかその前身のQUICCといったSoC、あるいはPalmに使われているDragonBallシリーズなど、民生機器に向けて幅広く製品を展開している。単にCPUのみならず、フラッシュメモリとかアナログ部品なども盛んで、最近では世界で初めてMRAMの製品化に成功したあたりもちょっとしたトピックである。 ただここまで書けばおわかりな通り、Freescaleは直接的には機器メーカーが商売の相手であり、直接コンシューマに対して製品を売るということはない。まぁいまさらPowerPC G4を入手したところでMacが作れるわけではないし、Apple自体PowerPCを捨ててしまっているから、IntelなりAMDからCPUを購入して自作するといったPCの世界ではあたりまえの動機は、ここでは発生しない。ましてやFreescaleのパーツを使った最終製品(ルータとか民生機器各種、あるいは基地局のシステムなど)をユーザーがどうこうする事はありえないから、コンシューマには無縁の会社といって良かった。 過去形なのは、「やっぱこのまんまではいけない」とどうもFreescaleが考えている模様だからだ。今年に入ってからは電子工作キット制作コンテストを開催したり、九十九電機のロボット王国でも取り扱いを始めたり、と積極的なコンシューマ向けの展開を行なっている。ここで主眼となるのは、やはり「モノ作り」。つまり「電子工作」に目を向けてもらうことで、ここでFreescaleの名前を知ってもらおうという話である。 こうした事もあってか、筆者の手元にFreescaleが本来は開発者向けキットとして提供しているDEMO9S08QG8のキットがやってきた。ちなみにこのキット、上述のロボット王国の他にマルツパーツ館などでも入手可能である。アメリカ国内でのFreescale直販価格は50.00ドル(*1)、国内では6,000~7,000円の値段付けとなっている。で、編集長からは「これ使って夏休みの工作ネタを1つ」というオーダーを頂いたのだが、記事の掲載時期を見ればお分かりのとおり見事に失敗である。どのように失敗したか、という話は後でもう少し詳しく説明したい。 (*1) これは税/送料別。試しに日本までの通販を掛けてみたら、送料込みで75.83ドルとなった。どう考えても国内で購入するほうが安い。 ●環境の用意 さて、パッケージ自体はA4よりもちょっと大きめの箱1つである(写真01)。中をあけると、本体とUSBケーブル、CD-ROMのパッケージと簡単なマニュアルが入っている(写真02)。CD-ROMはCodeWarrior 4.5と5.0、5.0のService Pack、それにAXIOMの製品CD-ROMの4枚が付属している。実はこの評価キットのボードそのものは、米AXIOM manufactureingが製造するAXM-0363という製品である(同社トップページからリンクなし)。そんな事もあって、製品マニュアルやサンプルプログラム、ユーティリティなどはエンベロープに入ったCD-ROMに入っている。マニュアルなどはAXM-0363のサポートページからも入手可能だ。 ボードそのものは75×63mmという非常に小さなもので、ここにUSBポートとシリアルポート、ACアダプタのほか、汎用のI/Oインターフェイスが用意されている(写真04)。汎用I/Oインターフェイスは基盤裏側にソケットが用意されており、簡単にデバイスの接続が可能だ(写真05)。USBはBコネクタ、シリアルポートはD-Subの9ピンが(写真06)、反対側にはACアダプタとボリュームが用意される(写真07)。
さて、まずは環境の作成だ。とりあえずWindowsマシンを1台用意し、まずはCodeWarrior 5.0のインストールである(写真08)。CodeWarriorとは元々MetroWorksという会社がMac上の開発ツールとして発売したIDE(統合開発環境)だが、その後MotorolaがMetroWorks自体を買収し、自社のMCU向けに各種のCodeWarriorを提供している。今回キットに付属しているものはHCS08というMC9S08QG8の中に入っている8bit MCU専用で、多少の機能制限(プログラムサイズが16KB以内など)が付くものの、実用上はほとんど支障がないバージョンである。ちなみに一切機能制限が無い正規版(現状のバージョンは5.1)の場合、Standard Editionの一番安いもので$1,440とかなり高価であり、Special Editionのお得さが身にしみる。インストールの最後で、ネットワークに繋いでいるとにアップデートチェックが実行される(写真09)。アップデートも、全オプションを選択しておくのが便利だ(写真10)。 インストールが完了すると、MC9S08QG8用のUSBドライバも同時にインストールされる。この時点でUSBケーブルを使ってMC9S08QG8をPCに繋ぐ(USBバスパワーで駆動できるので、ACアダプタは必ずしも必要ではない)と、ドライバがロードされ(写真11)、最終的にはUSB Multilink 2.0というデバイスとしてPCから認識される(写真12)。 ●サンプルプログラムのロード さて、環境の準備が出来たらちょっと実際に動作を確認してみたい。まずEMO9S08QG8ボードからUSBケーブルを外し(何しろUSBデバイスではないので、「デバイスの取り外し」は不要だ)、ジャンパを確認する。写真13にジャンパ位置をまとめたが
・User Option Jumper : 全てClose になっていることを確認する。この状態で再びUSBコネクタを差し込むと、“USB”と“USB PWR”、それに“VDD”というLEDが点灯するはずだ。この状態では
・MC9S08QG8そのもの の両方に、USBバスパワーで電力を供給している。電源が供給されると、MC9S08QG8は内蔵しているフラッシュメモリに書き込まれたプログラムを読み出し、自動的に実行を開始する。最初に書き込まれているプログラムは「LED1は、SW1を押すたびにON/OFFを切り替える。LED2は点滅を繰り返す」というシンプルなもの。実際電源を入れると、これがあっさり立ち上がる(動画01)。 ただいつまでもLEDを点滅させていても仕方がないので、もう少し他のこともしてみよう。AXM-0363 CD-ROMの中の\Examples\DEMO9S08QG8\CodeWarriorというディレクトリの中に、Demo_S08QG8_Test.zipとDEMO9S08QG8_APP.zipという2つのzipファイルがある。Demo_S08QG8_Test.zipの方は、工場出荷時に書き込まれているLED点滅プログラムそのものなので、もう1つのDEMO9S08QG8_APP.zipの方を任意のフォルダに展開する(写真14)。 ここで“DEMO9S08QG8_APP.mcp”というファイルをダブルクリックすると、CodeWarriorが立ち上がる(写真15)。このCodeWarriorの画面で“Make”(ソースプログラムを実行可能形式に変換)、ついで“Debug”(デバッガを起動し、MC9S08QG8にプログラムをロードする)を行なう(写真16)。Debugを呼び出すと“True-Time Simulator & Real-Time Debbuger”と呼ばれるツールが立ち上がるが、それに先んじてこんなダイアログ(写真17)が表示される。ここまでの手順に間違いがなければ、USBポート経由でのプログラムロードが選択されており、またCPUにはHCS08が選ばれているはずなので、これを確認して“Connect”ボタンを押す。するとFlash Memoryに書き込むかどうかのダイアログが表示される(写真18)ので、Yesを選択するとUSB経由で今Makeしたプログラムが書き込まれるはずだ。完了すると、デバッガの画面が表示される(写真19)。 ここでデバッガから実行を選択すればプログラムは走り出すのだが、その前にちょっとやっておくべき事がある。RS-232CケーブルでDEMO9S08QG8ボードとPCを繋ぎ、PC側で適当なターミナルソフトを立ち上げておくことだ。MC9S08QG8はシリアルポートの制御も可能であり、これを利用してDEMO9S08QG8_APPにはシリアルポート経由で対話式に処理を行なえる一種のインタープリタが実装されている。そのために、PC側にその相手となるターミナルソフトが必要になる。今回は定番TeraTermのUTF-8/TTSSH2対応版を入手して使ったが、別に普通のTeraTermでもいいし、その他のターミナルソフトでも問題はない。通信パラメータは4800baud 8bit None Parity Stop bit 1に設定しておく(写真20)。ここまでの手順に問題がなければ、デバッガ画面で“Run”を選択するとターミナル画面にメニューが出現するはずだ(写真21)。 ●自分でプログラミングしてみる さて、ここからはC言語の知識が必要になる。さすがにC言語の解説までやってると原稿量が爆発するのでご容赦いただきたい。とりあえず簡単なところで
・LED1が高速(数回/秒)で点滅する といったプログラムを組んでみることにしたい。まずはCodeWarriorを単独で起動する(写真22)。デフォルトではWizardが立ち上がるので(写真23)、ここで“Create New Project”を選ぶ。まず基本設定(写真24)ではC言語を選び、プロジェクト名とディレクトリを入力する。CPUの選択では“HCS08QG Family”から“MC9S08QG8”を、Connectionは“P&E Multilink/Cyclone Pro”を選択する(写真25)。 次は追加ファイルの設定(写真26)だが、新規に作るのだからここは何もなしである(写真26)。問題は次で、デフォルトではここが“None”になっているが、ここで“Processor Expert”を選ぶ必要がある(写真27)。次は言語環境だが、概ねデフォルトのままで良いだろう(写真28)。最後にLintを掛けるかどうかの質問が出てくるが(写真29)、とりあえず作るレベルだからNoのままでよいだろう。 Wizardが終るとまずProcessor Expertが起動する。最初にCPUの選択が出てくるので、ここでは“MC9S08QG8_16”のみをチェックしておく。ついでProjectのビルドをどうするかの選択が出てくる。最終製品であればReleaseビルドのみなのだろうが、今はDebugビルドのみでよい。以上の設定が終ると、やっとCodeWarriorが立ち上がる(写真33)。 さて、まずはLEDの制御である。マニュアルによれば
となっている。つまり6番ピン(ポート名PTB6)をHighにすればLED1が点灯、Lowにすれば消灯という仕組みだ。これはLED2も同じである。そこでまずはBean Selectorで“CPU Internal Peripherals”→“Port I/O”を選び、ここの“BitI/O”をダブルクリックすると、プロジェクトにそのBeanが追加されると共に、Inspectorに詳細設定が出てくる(写真34)。ここではBit1をLED1に割り当てる事にするので、“Pin for I/O”に“PTB6_SDA_XTAL”を(写真35)、“Direction”には“Output”を選択しておく(写真36)。同様にBit2も追加し、こちらは“PTB7_SCL_EXTAL”を割り当てる。こちらもやはり“Output”だ。 これとは別に、一定期間で点滅させるためには、一定期間を通知するための方法が必要である。まずはLED2の方を考えよう。数秒に1回という目的だと、例えば1秒に1回ずつ割り込みを掛け、割り込みルーチンの中でON/OFFを切り替えれば良い。こうした場合にはTimerInterrupt(TimerInt)が有用である。Beans Selectorで“Timer”→“TimerInt”をダブルクリックし、これをプロジェクトに追加する(写真37)。これを使うと、指定した時間間隔毎に割り込みが掛かり、ISR(Interrupt Service Routine)が呼ばれる。で、時間間隔はBeans Inspectorの中で指定を行なう(写真38)。 これでLED2は片付いたがLED1はどうするか? 残念ながらTimerIntは1つしか使えないので、LED1では同じ方法は使えない。よくあるアプローチは、そもそもTimerIntの解像度を思いっきり細かく(例えば1ms)とかにしておき、ISRの中でLED1とLED2の両方を制御する(例えばISRが50回呼ばれるたびにLED1のON/OFFを、1,000回呼ばれるたびにLED2のON/OFFを行なう)なんて方法で、別にこれが悪いわけではないが、折角のサンプルなのでもうひとひねりした。プロジェクトでCPUを展開すると、“Delay100US”という項目がある。デフォルトはDisableだが、これをEnableにすると呼び出せるようになる。これは“100μsの整数倍だけ待機する”という命令で、何倍待機するかはパラメータで渡せる。このDelay100USをLED1のタイマー代わりに使うことにした。 さて、以上でProcessor Expert周りの作業は完了である。この時点で一度Makeを掛けると、必要な初期化コードとコールバックのテンプレートを作成してくれる。 生成されたコードがList1(Test.c)とList2(Event.c)である。
-------------------------------------------------------------------------------
------------------------------------------------------------------------------- 見ればわかるとおり、プログラムはTest.cの先頭から走り始め、そのままぐるぐる回っている。Test.cの最後が /*** Don't write any code pass this line, or it will be deleted during code generation. ***/ となっていることからわかる通り、要するに無限ループでぐるぐる回りっぱなしという代物だ。この部分はCodeWarrior(というか、ProcessorExpert)が勝手に生成するので、書き換えは不可能である。一方Event.cは、こちらも見ればわかるとおり、先のTimerIntの割り込みが入る度にTI1_OnInterrupt()が呼び出されるという訳だ。 さて、これをどう書き換えたかであるが、List3がTest.c、List4がEvent.cである。List3の方は、常識的なプログラマからすると激怒ものなのだろうが、どっちみち最後は無限ループで回ってるだけなので、手前にもう1個無限ループを入れたところで支障はない。で、中ではCpu_Delay100US()を使って200ms待機させてからLEDの状態を反転している。Bit1_GetVal()はLEDが点灯してればTRUE、消灯してればFALSEを返すので、これを反転してBit1_SetVal()するというだけだ。「それなら Bit1_PutVal(~Bit1_GetVal()); でいいじゃないか」とか突っ込みが入りそうだが、Bit1_GetVal()がマクロで実装されてる関係で、これがあまり上手く動かないのでこんなコードとなった。Event.cの方も同様である。こちらはタイマーが勝手にタイミングを決めてくれるので、単にLED2のON/OFFをするだけだ。 -------------------------------------------------------------------------------
void main(void)
/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
-------------------------------------------------------------------------------
void TI1_OnInterrupt(void) このコーディングが終わったら、再びMakeを行ない、エラーがなければDebugを開始する。この手順は先ほどと同じであり、問題なければ点滅する(動画02)。 ●工作の課題に向けて そんなわけで、ここまでは順調であった訳だが、ここからがいけなかった。とりあえず色々作れる目処は立ったが、DEMO9S08QG8ボード単体で出来ることには限界がある。夏休みの工作というからにはやはりもうひとひねりしないと、このまま出したら失格を食らうのは目に見えている。そこで「何かデバイスをつけないと」という事になる。 最初は温度センサーとモーターコントローラでも入れて、PCのファンコントロールをUSB経由でプログラムから出来ないかとか思っていたが、MC9S08QG8がUSBで接続できないのでこの案は放棄。そういうわけで、上述のパーツ王国まで足を伸ばして色々見ていて見つけたのがこの超音波測距センサー(写真40)。浅草ギ研が同社のH8マイコンに接続するためのキットとして販売しているものだが、ぱっと見た限りDEMO9S08QG8ボードでも使えそうである。というわけで、早速購入。これだけだと接続がちょいと面倒なので、ユニバーサル基盤とピンヘッド(写真41)を千石電商で購入した。 さて、まずは動作するかどうかの確認である。超音波測距センサーのページにも説明があるが、センサー自体は5V電源とGND、それにトリガー/信号ピン(以前はこれが別だったが今は一緒になっている)の3本の端子だけで構成されている。トリガー/信号ピンはTTLレベルだから、DEMO9S08QG8のI/O端子に直結しても問題はなさそうだ。で、DEMO9S08QG8の裏面に出ているI/O Port Connectorは写真41のようになっている。1番のVDDから+5V、3番からGNDを取り、あとは適当なピンにトリガー/信号をつなげれば良い、という目論見だったが、試しに測定してみるとVDDに出ているのは+3.3V。USBバスパワー/ACアダプタのどちらの場合でも、電源ラインはすぐにレギュレータ経由で3.3Vに降圧されるようだ。で、3.3Vではやはり超音波センサーが動かない。数秒悩んだ末
・動作は5VのACアダプタを接続した状態で行なう。最終的にはACアダプタの代わりにマンガン電池3本(4.5V)なりニカド電池4本(4.8V)を供給する。 という方針とした。おかげでいきなり超音波測距センサーが物理的にDEMO9S08QG8ボードと一体化する羽目になった。 その超音波測距センサーは写真44のようなな形状である。そこで、ユニバーサル基盤に直立するように脚をまげて取り付け(写真45)、写真43にもちらっと見えているように配線すればOKである。で、ユニバーサル基盤には写真41に映っているピンヘッドをやはりハンダ付けで取り付けた(写真46)。これを組み合わせると、写真47のような構造になる。 さて、ここまでは順調(とかいいながら配線間違えたりしたので、実質1時間強掛かっている)だったが、問題はここからである。作るものとしては、連続的に(例えば毎秒10回とか)距離を測定し、ある閾値(例えば1m)以内だったらLEDを点灯するといったものを想定していた。最終的にはLEDの代わりに圧電ブザーなんかをつなげれば完璧というわけだ。その測距センサーの使い方だが、先の超音波測距センサーのページにもあるが
(1) 信号ピンがLowであることを確認 といった具合になる。このうち
・毎秒10回の部分は、TimerIntを使えば簡単に実現できる。 というわけで、
(a) トリガを5μs以上入れる の2つがネックになる。 実はこれに必要な部品(CodeWarriorで言うところのBean)は既にある。ちょっと写真37に戻ると、FreeCnt8/16/32というBeanがあるのがわかるはずだ。これは8bit/16bit/32bitのカウンタで、解像度は最小1μsである。これを使うと例えばトリガを入れるのは word StartTime, StopTime;
FC161_Reset(); といった具合に記述できる。FC161は16bitのカウンタで、FC161_Reset()はカウンタの初期化、FC161_GetTimeUS()は時刻をμsecで返す関数である。トリガだけなら5μsだから8bitカウンタでも十分だが、距離の測定は最大18.5msec(18500μsec)まで測定できないとまずいので、8bitだとオーバーフローする関係で16bitカウンタとしている。 さて、実は当初このコードで問題なく動いていたのだが、デバッグの途中でいきなりカウンタを読み出すとCPUがハングアップする現象に陥った。ためしに超音波測距センサーを外しても現象は変わらず、どうもMC9S08QG8内部のカウンタ部が壊れた(というか、筆者が壊した)模様だ。前節「自分でプログラミングしてみる」でも、最初はこの16bitカウンタを使ってサンプルを作っていたのだが、途中から動かなくなり、やむを得ずCpu_Delay100US()なんぞを使ってサンプルとしたのが正直なところだ。 まぁこの状態でも、例えば時間測定はTimerIntを使ってISRの中で自分で管理し、距離測定ロジックはmain()の中で廻すという技は使えなくもないが、FreeCntが使えれば不要な作業なだけに、全然参考にならないということであきらめた。そんなわけで、夏休みの課題は失格である。 ●というわけで いきなり失敗しましたというレポートも変な感じではあるが、割と手軽に電子工作が出来るというイメージは理解いただけたかと思う。個人的に気に入ったのは、プログラミングの手軽さだ。なにせ汎用I/Oピンを直接叩けるし、設定も自由自在だ。OSとかが介在しないから余計な事を考える必要もない。あとデバッガもかなり強力である。ソースラインデバッグが可能だし、変数の値も直に読んだり変更したりできる。必要ならポートの操作まで可能であり、かつてクロスプラットフォーム環境で必死こいてデバッグしていたのが嘘のような快適さがある。 今回は超音波センサーを使ってみたが、他にも3軸加速度センサーやモーター制御なども可能だし、組み合わせれば自由度は広がるだろう。さすがに日本語のマニュアルは無いし、C/C++/アセンブラ以外の開発環境はないから、これらに慣れていない人にはちょっと敷居が高いかもしれない。ただ逆にこのあたりが問題にならない人には、とてもよいオモチャになることを保証する。まぁ久々に楽しい日々であった。 □freescaleのホームページ (2006年9月1日) [Reported by 槻ノ木隆]
【PC Watchホームページ】
|
|