DEMO9S08QG8評価ボードには、 フォトトランジスタ一個とLED二個が実装されています。 これらを使って、デジタル太陽計(照度計)を作ってみましょう。 ここにもProcessor Expertの出番です。
プログラムの開発には、CodeWarriorを使います。 CodeWarriorでは、 一つのプログラムの単位を「プロジェクト」と呼んでいます。 ここでは、新規にプロジェクトを作成します。 ここでは、V5.0を使って説明します。
スタートメニューからCodeWarriorを起動するとCodeWarriorが起動します。
初めてCodeWarriorを起動したときには、 下のような"Startup"ダイアログが出てきますが、 今はこのダイアログは使用しませんので、 をクリックしてダイアログを閉じます。
この後、"Tip of the Day"ダイアログが出てくるかも知れませんが、 これも をクリックして閉じてしまいましょう。
メニューから"File → New Project..."を選ぶと、 "HC(S)08 New Project"ダイアログが開きます。 まずは、"Project Parameters"(プロジェクトのパラメータ)を設定します。
使用する言語に"C"を選び、 プロジェクトを作成する場所を設定します。 この例では、"C:\Projects\CW\TaiyouKei"というディレクトリに "TaiyouKei.mcp"というプロジェクトファイルを作成しています。 設定を終えたら、「次へ」をクリックします。
画面が変わって、 "Device and Connection"(デバイスと接続方法)の設定に移ります。
デバイスには"HCS08 → HCS08QG Family → MC9S08QG8"を選び、 デフォルトの接続方法には"P&E Multilink/Cyclone Pro"を選び、 「次へ」をクリックします。
3枚目の画面は、 "Add Additional Files"(追加するファイル)の設定です。 プロジェクトで使用するソースコードなどがあれば、 ここで設定します。
今回は、追加するファイルはありませんので、 そのまま「次へ」をクリックします。
4枚目の画面は、 "Processor Expert"(プロセッサエキスパート)の設定です。
"Processor Expert"を選んでこの機能の使用を宣言します。 さらに、「次へ」をクリックします。
5枚目の画面は、"C/C++ Options"の設定です。
すべて、デフォルトのままの設定にします。
startup code | ANSI |
memory model | Small |
floating point format | None |
設定を確認して 「次へ」をクリックします。
最後の画面は、"PC-Lint"の設定です。 PC-lint™というのは、 プログラムの書式を検査するためのプログラムです。 今回は使用しません。
"No"をチェックして 「完了」をクリックすると、 新規プロジェクトの作成が始まります。
MC9S08QG8マイコンには、 いくつかの異なる種類のパッケージが存在します。 その中から、今から使おうとしているパッケージが どのパッケージなのかを指定するのが次のウィンドウです。
今回は、評価ボードに搭載されている 16PIN-DIPパッケージを使いますので、 "MC9S08QG8_16"だけを選択して「OK」をクリックします。
これが、新規プロジェクトのための 最後の設定です。 "Select Configurations"(設定を選べ)というのは、 実にあいまいですが、 ここでは、アプリケーション開発の結果を何に使うかを指定します。 もちろん、独立した製品に仕上げるのが最終目的には 違いないのですが、 プログラムの開発中には、デバッガを接続した状態で プログラムを実行する必要もあります。
"Debug"設定は、このようなデバッガを接続した状態を考慮した 設定を行います。 このため、BKGD端子には、デバッガが接続されアプリケーションでは 使用できなくなります。
一方、"Release"設定は、最終製品での使用を考慮した設定を行うため、 すべての端子がアプリケーションに開放されます。
今回は、デバッグ環境である評価ボードでアプリケーション開発を 行いますので、 "Debug"だけを選択して「OK」をクリックします。
以上で、プロセッサエキスパートを使用する 新規プロジェクトができました。
ここから、 プロセッサエキスパートのプロパティを設定していきます。
まず、 A/Dコンバータ (A/D Converter: ADC) というブロックの設定をします。
CodeWarriorのウィンドウの中央下には、 "Bean Selector"(ビーン選択)というサブウィンドウがあります。
プロセッサエキスパートでは、 マイコンの機能を抽象化した物を「Bean」(ビーン:豆)と 呼んでいます。
ADCビーンを使用するためには、 このウィンドウの "CPU Internal Peirpherals → Converter → ADC → ADC"を 見つけ出してダブルクリックします。 すると、 中央上にある"Target CPU"というサブウィンドウの "PTB3"に"ADC"ビーンが付き、 右側にある"Bean Inspector"(ビーン検査官)というサブウィンドウに ADCの設定項目が現れます。
以下、この"Bean Inspector"を使用してビーンの設定を行っていきます。
"ADC"ビーンは、初期状態では"PTB3"からアナログ入力を行うように 設定されています。 今回のアプリケーションでは、 "PTA1"につながったフォトトランジスタの出力を使用するので、 アナログ入力端子を"PTA1"に変更します。
A/Dチャンネル(端子名を選べ)
ペリフェラルの詳細: 汎用入出力ポートAのビット1、 キーウェイクアップ端子1、 A/Dコンバータチャンネル1、 コンパレータ反転入力
"Bean Inspector"の 項目"A/D Channels → Channel0 → A/D Channel (pin)"を "PTA1_KBIP1_ADP1_ACMPMINUS"に設定すると、 "Target CPU"のADCビーンが"PTA1"に移動します。
後は、なるべく初期状態のまま使いたいのですが、 もう一つ設定しなくてはならない箇所があります。
プロセッサエキスパートでは、 必須設定項目あるいは問題のある設定には、 マークが現れます。 現状、項目"Conversion Time"(A/D変換時間)に マークが 表示されていますので、この設定だけを行います。
"Bean Inspector"の項目"Conversion Time"に カーソルを移動するとこの項目が何を意味し、 どうして問題が起こっているのかが表示されます。
一変換あたりの時間。 ここには、数値と単位を一緒に記入する必要があります。 (時間設定文法を参照してください。) ボタン"..."をクリックすると開く タイミングダイアログボックスの助けを借りて 設定することもできます。
選択された実行時設定:固定値
エラー:タイミング未設定
お言葉に甘えて、 タイミングダイアログボックスを使ってみましょう。 "Bean Inspector"の項目"Conversion Time"の を クリックすると、A/D変換時間を設定するダイアログが現れます。
ダイアログの下半分には、 "Possible Setting:"という説明が現れます。
可能な設定:
最も近い値:なし
可能な値:5.750µs, 11.500µs, 23µs, 46µs
"Latin-1"の"µ"のフォントが "Shift-JIS"では、半角の"オ"に割り当てられているため、 文字が正しく出ていませんが、 設定自体は正しく"µs=マイクロ秒"になります。
A/D変換時間とは、 プログラムがA/DコンバータにA/D変換の開始を指令した後、 どのくらいの時間で変換結果が戻ってくるかという時間です。 一般的にこの時間は、長いほうが精度が高くなります。 このアプリケーションでは、精度も反応速度も必要ないのですが、 最長の変換時間を選びます。 "Possible Setting:"の"46µs"の付近をクリックすると プルダウンメニュが出てきて、簡単に値を設定することができます。
「OK」をクリックすると、 ダイアログボックスは閉じます。
これで、ADCビーンの設定は終了です。 変更したのは、二箇所だけでした。
このアプリケーションでは、A/Dコンバータの出力に従って、 汎用ポートに接続された二つのLEDを点灯・消灯させます。 ここでは、汎用ポートの設定を行います。
A/Dコンバータの時と同じように 汎用ポートのビーンを呼び出します。
汎用多ビット入出力(1から8ビット)
ビーンのレベル:高レベルビーン
このビーンを現在のプロジェクトに挿入するにはダブルクリックせよ。
汎用ポートのビーンは、 "Bean Selector"ウィンドウの "CPU Internal Peirpherals → Port I/O → BitsIO"に ありますので、 見つけ出してダブルクリックします。 すると、 "Target CPU"サブウィンドウの"PTA0"に"BitsIO"ビーンが付き、 右側にある"Bean Inspector"サブウィンドウに BitsIOの設定項目が現れます。
"BitsIO"ビーンは、複数の端子と関連付けることができます。 このアプリケーションでも、 "PTB7"と"PTB6"の二つの端子を関連付けます。
まずは、二つの端子に関連付ける設定にします。 項目"Pins"の をクリックすると、 端子の数が二つに増えます。
LEDが接続されている端子は、"PTB"なので、 項目"Port"を"PTB"に設定します。
そして、最後に項目"Pin1"と"Pin0"に "PTB7"と"PTB6"を関連付けます。
このビーンに関連付けた端子は、すべて出力として定義します。 端子の入出力の設定は、 項目"Direction"(方向)で行います。
ビーンの入出力方向: input(入力), output(出力), input/output(入出力) (端子の入出力方向は、実行時に切り替え可能です。 SetDir, SetInput, SetOutputメソッドを参照してください。)
端子の方向を出力(output)に設定したら、端子の設定は終わりです。
プロセッサエキスパートの設定が終わったら、 プログラムのコーディングを行います。 第一段階として、 A/Dコンバータに変換を指示して、 変換された値を取り出すプログラムを作成し、 デバッガで動作を確認します。
プロセッサエキスパートの設定を行っただけでは ソースコードは生成されません。 ソースコードを生成させるには、 CodeWarriorのウィンドウの左側にあるプロジェクトペインの ボタンを クリックします。
すると、コード生成、コンパイル、リンクが行われます。 生成されたソースコードは、 プロジェクトペインの "Generated Modules"(生成されたモジュール)フォルダの中に 収納されます。
"AD1.c"と"Bits1.c"が、 プロセッサエキスパートの設定を行ったことによって 生成されたソースコードです。 また、"Cpu.c"は、マイコンの基本的な設定を行うコードです。
この時に"TaiyouKei.c"というファイルも同時に生成されています。
このファイルには、 マイコンがリセットされた後で実行される "main()"関数が記述されています。 ここをダブルクリックすると、 "TaiyouKei.c"ファイルを編集するテキストエディタが開きます。
メインルーチンのうち、変更する箇所は、 以下の通りです。
A/Dコンバータからは、16ビットのデータを受け取ります。 この時に使用する受け渡し場所を変数といい、 以下のように宣言して場所を確保します。
word value; // converted value.
wordは、 宣言する変数が16ビットの変数であることを示します。 valueは、変数の名前です。 変数宣言文は、";"(セミコロン)で終わります。 残りの"converted value"(変換された値)と 記述された部分は、コメントです。
変数を"main()"関数の外で宣言すると「大域変数」と言って、 すべての関数から参照可能になります。 小さいプログラムの場合には、問題にならないのですが、 多くのプログラムが絡み合うような場合には、 このファイルで宣言された変数を他のファイルのプログラムからは 見えないようにして保護しなくてはならない場合があります。
一方、"main()"関数の中で変数を宣言すると、「自動変数」と言って、 "main()"関数が呼び出された時に変数の場所が確保されて"main()"関数の 内部でしか参照できなくなります。
安全なのは、他のプログラムからの干渉を受けない自動変数の方です。 しかし、自動変数は、"main()"関数の実行まではアドレスが定まらないので、 デバッグの際には、場所を特定しづらくなります。
このアプリケーションでは、デバッグのしやすさを考えて、 「大域変数」として定義しているため、 プログラムがリンクされた時点でアドレスが決定します。
このプログラムの処理は、 繰り返し処理を続ける無限ループで出来ています。 無限ループを記述するには、for文を使います。
/* Write your code here */ for (;;) { : }
「for(;;) 文」という構文は、無限ループを示します。 他に 「while(1) 文」という構文で記述する方法もありますが、 こちらの記述は、 「ループから抜ける事ができない」という警告が発せられてしまいます。
コードを書く場所は、 "Write your code here"(あなたのコードをここに書きなさい)と 書いてある行の下です。 これ以外の場所に書く事は、 プロセッサエキスパートに受け入れられません。
プログラムを良く見ると、 改造を加えようとしている場所のすぐ下にfor文による 無限ループがあります。 「ラッキー、ここに処理を書いちゃえ。」 と思ってこの部分を書き換えないようにしてください。 この無限ループは、「メインルーチンの最後を示す印」として プロセッサエキスパートが生成したコードです。
このため、この無限ループを書き換えてからコンパイルをさせると、 プロセッサエキスパートは元通りのコードに書き換えてくれます。 つまり、修正したコードは、きれいに消えてしまうのです。
その解決方法が、別の場所に無限ループを書く方法です。 このコードでは、二つ目の無限ループには絶対にたどり着けませんので、 エラーか警告が発せられると思っていたのですが、 私がやってみた限りでは、警告も出ないようです。
プロセッサエキスパートでのA/D変換は、 変換開始指令と結果の受け取りの二つの部分に分けて記述されます。 これは、変換を行っているときに 他の処理を行わせたい場合などに便利だからです。 このアプリケーションでは、変換開始指令と結果の受け取りを 続けて記述しています。
変換開始指令は、以下の部分で発せられます。
(void)AD1_Measure(TRUE); // wait for conversion.
プロセッサエキスパートが生成した関数を オブジェクト指向の流れから メソッドと呼んでいます。 この文書でもそれに習って、メソッドという言葉を使います。
このメソッドは、引数を一つ取ります。 この引数にTRUEを指定した場合、 変換開始指令をA/Dコンバータに発した後、 A/D変換が終わって結果が確定してからメソッドを抜けます。
反対にFALSEを指定した場合は、 変換開始指令をA/Dコンバータに発した直後に メソッドから戻ってきます。 この時には、A/D変換の結果が確定しているかどうかがわかりませんが、 A/D変換が終わるまで他の処理を行うことが出来ます。
今回の用途では、変換結果が確定するのを待つことによって、 確実に変換結果が得られるようにしています。
メソッド呼び出しの前に(void)という 記述があります。 これは、「メソッドから返ってきた値を使用しない」という 宣言です。
実は、
どんなエラーが返ってくるかは、 次のコラムを読むとわかります。
自分ではコードを記述せず、 プロセッサエキスパートが生成した関数を使うのが この方法の長所です。 そのためには、プロセッサエキスパートがどんな関数を生成するのかを 知る必要が有ります。 この情報は、プロジェクトペインの中から得られます。 プロジェクトペインの "Beans → AD1:ADC"を開くとA/Dコンバータのために 生成されたメソッドが並んでいます。 それぞれのメソッドのそばにカーソルを移動すると メソッドについてのヘルプが現れます。
ここでは、詳しくは説明しませんが、このヘルプには、 このメソッドの振る舞いと使い方が書いてあります。
また、プロジェクトペインのメソッドを「ドラッグ&ドロップ」して テキストエディタに落とすと、メソッドの記述が追加されます。 このような便利な機能を駆使すると、 ますますアプリケーション開発が早くなることでしょう。
A/D変換の結果は、以下のメソッドで受け取ることができます。
(void)AD1_GetValue16(&value); // get converted value.
このメソッドは、A/D変換の値を16ビットの値として受け取ります。 値が戻ってくる場所は、引数で示されるアドレスです。 この例では、valueという変数の アドレスを示す"&value"という表現が使われているので、 value変数の中に変換結果が入ります。
このメソッドもエラーコードを返します。 ところが、A/D変換終了直後に呼び出されるため、 エラーになる可能性がありません。 このため、エラー処理を省略しています。
以上で、A/D変換の結果を受け取るプログラムが出来ました。 受け取った結果を表示するプログラムまでは作成していませんが、 ここでプログラムを書き込んでみて、 A/D変換の動作をデバッガで調べてみます。
さて、いよいよマイコンにプログラムを書き込みます。 使用する開発ツールは、 DEMO9S08QG8評価ボードにすでに搭載されています。
まず、DEMO9S08QG8評価ボードをUSBケーブルで接続します。
最初に評価ボードを接続したときには、 「新しいハードウェアの検索ウィザードの開始」 というダイアログが表示されます。 この時には、 「ソフトウェアを自動的にインストールする」を選択して "USB Multilink"のデバイスドライバをインストールします。
CodeWarriorのプログラム書き込み機能は、 デバッガやシミュレータと兼用のツールから利用します。
ドロップダウンリストが"P&E Multilink/Cyclone Pro"になっているのを 確認して、 アイコンをクリックすると コード生成、コンパイル、リンクの後、 デバッガが立ち上がります。
デバッガの初期化が終わると "ICD - Connection Manager"(In-Circuit Debuggerの接続マネージャ) ウィンドウが現れます。 ここでは、USBインターフェースの設定を行います。
"Interface:"と"Port:"の項目は、 自動的に認識されて正しい値が入っているはずです。 "Port:"に"DEMO9S08QG8"が表示されているのを確認して、 "Connect"をクリックします。
先の画面でボタンをクリックすると、 "Erase and Program Flash?"(フラッシュを消去、書き込みするか?)という ウィンドウが現れます。
今回は、プログラムの書き込みが目的ですので、 「Yes」をクリックします。 もし、デバッグだけの目的でしたら、 「No」をクリックします。
今度は、"CPROGHCS08 Programmer"(CPROGHCS08プログラマ)という ウィンドウが現れ、 瞬く間にフラッシュの消去、書き込み、確認を行い、 自動的に消滅します。
これで、マイコンへの書き込みは終了です。
マイコンへの書き込みが終わると、 デバッガの初期画面が現れます。
デバッガの初期画面は、このようになっています。
ソースコードウィンドウには、 プログラムのソースコードが表示され、 プログラムが停止している場所がハイライトされています。
この例では、 プログラムは、"PE_low_lecel_init()"という関数に入る手前で 止まっていることがわかります。
データウィンドウ1には、 大域変数とその値が表示されています。
この例では、 valueというunsigned intで 宣言された変数があり、 その値が"0"であることがわかります。
デバッガのツールバーには、ツールボタンが並んでいます。
ここには、ステップ動作などデバッグに使用される機能が並んでいます。
まずは、ステップ動作をさせてみましょう。
ツールボタンの
もう一度、
この動作を繰り返すことで、プログラムの動きを調べることができます。
"AD1_GetValue16(&value)"の所で停止している時に ステップ動作を行うと、 A/D変換された値が変数valueに格納されます。 格納された値は、データウィンドウ1で確認することができます。
数値が赤くなっているのは、 ステップ動作の前後で値が変化したことを示しています。
この値は、フォトトランジスタが捕らえた光の強さを表しています。 明るくしたり、暗くしたりして、値の変化を確認してください。 私の評価ボードのフォトトランジスタは、 蛍光灯よりも白熱灯の方が感度が高いようです。 私が懐中電灯を照らしたときの値の変化は以下のようになりました。
明るい | 3712 |
: | 18560 |
暗い | 65344 |
この値は、LED表示プログラムを作成するときに使用しますので、 控えておいてください。
これで、A/Dコンバータの動作確認はおしまいです。 実験が終わったら、 デバッガを閉じてCodeWarriorに戻ります。 また、評価ボードからUSBコネクタを抜いて電源を切っておきます。
次は、表示プログラムを作成します。
LEDの表示には、評価基板上に搭載された"LED1"と"LED2"を使用します。 これらのLEDは、以下のように配置されています。
これを使って、明るさを表す棒グラフ風の表示にするため、 以下のような表示にします。 また、その時に"Bits1"汎用出力ビーンに設定する値も決まります。
表示 | 最小値 | 代表値 | 最小値 | LED1 | LED2 | VDD | Bits1の値 |
---|---|---|---|---|---|---|---|
明るい | 0 | 3712 | 9999 | ■ | ■ | ■ | 11 |
: | 10000 | 18560 | 29999 | ■ | ■ | ■ | 01 |
暗い | 30000 | 65344 | 65535 | ■ | ■ | ■ | 00 |
最小値と最大値は、 A/D変換の値を確認したときに控えた値(代表値)をもとにして 調整された値になっています。 皆さんが、作成される場合には、個々の環境に従って、 値を調整してみてください。
上で決めた仕様に従って、プログラムを記述していきます。 書き加える場所は、 無限ループの中のA/Dコンバータから値を受け取った直後です。
書き加えたルーチンでは、 A/D変換の値valueの値によって 三つの処理に分岐しています。
メソッド"Bits1_PutVal()"は、汎用出力ポートの値を決定します。 引数は、8ビットのbyte型ですが、 このうちLSBの2ビットしか効力をもちません。 2ビットのうち、上位1ビットがPTB7に、下位1ビットがPTB6に相当します。
プログラムが完成したら、いよいよ自律制御をさせます。
先ほどと同じようにマイコンにプログラムを書き込みます。 手順は、ほとんど同じです。
DEMO9S08QG8評価ボードをUSBケーブルで接続します。
ドロップダウンリストが"P&E Multilink/Cyclone Pro"になっているのを 確認して、 アイコンをクリックすると コンパイル、リンクの後、デバッガが立ち上がります。
USBインターフェースの設定を確認したら、 "Connect"をクリックします。
「Yes」をクリックして、マイコンに書き込みます。
A/D入力の確認では、ステップ動作をさせましたが、
今回は、そのまま走らせて見ます。
ツールボタンの
下の写真のように、 フォトダイオードにあたる光の強さによって LEDのバーの長さが変わったら、完成です。
このプログラムは、無限ループの中で実行されているため、 常にフルスピードでプログラムを実行しています。
LEDの表示を見るのは人間なので、そんなに忙しくLEDの表示を 更新する必要はありません。 どのようにしたら、適当にサボりながら表示を更新していくことが できるでしょうか。
このアプリケーションは、LED二つで三つの値を表現しています。 もっと、多くの状態を表現するためには、 数値を表示させたほうがわかりやすくなります。
2006-02-14 STEP1として再構成。
2006-01-23 発行。