はじめに
マイコンボードには表示装置がないので、内部で計算した結果を見ることはできません。しかし、プログラム開発の途中で、途中の計算結果を確認したいという場合がよくあります。ここでは、A33Fのシリアル通信機能を使って計算結果をPCへ送り、PCのモニタに表示させるということを行います。
※このページで紹介する内容はあくまでも一例です。個別の作成のご相談ご質問はお答えできませんのでご了承下さい。このページと同じ内容についてのご質問についてはロボット掲示板にてお願いいたします。
※以下の情報は2007年11月現在のものです。ご注意ください。
注意)
・A33FのUSBコネクタを使用する場合は、USBケーブル(A−miniBタイプ)が必要です。あらかじめご用意下さい。
・USBドライバをインストールする必要がありますが、これは一番最初にケーブルをPCに接続したときに出るウィンドウで行います。よって、まだケーブルは接続しないで下さい。必ず以下の手順にて行ってください。
デバックモニタ
マイコン開発時には途中結果を確認しながら少しづつ開発しないと長いプログラムは書けません。途中結果を確認する作業をデバック(DEBUG)と言います。DE-BUG:虫を取り除く、という意味ですが、昔のコンピュータは大きかったので本当に虫が入って壊れたことがあることからの由来らしいです。デバック作業をする装置をデバッカと言います。デバッカで現在多く使われているものに、ICE、専用デバッカ、JTAGインターフェイスというものがあります。
デバック装置は本格的な開発をする場合にはかかせないものですが、専用の装置が必要になります。A33Fの場合も本格的な開発をする方向けなので専用デバッカであるICD2の使用が前提となっています。ICD2を使ってのでバックについては後のページで説明します。
雑誌の付録でマイコンボードが付いている場合がありますが、上記のようなデバック装置(デバッカという)までを付録にすることができないので、簡易的なモニタをPCとの通信で構成するパターンが多いです。
この場合には、マイコンボード(もしくはCPU)にあらかじめ通信プログラムが書きこまれています。
※シリアル通信については後のページで詳しく説明します。
このパターンですと、”プログラムを組めば”PC上で計算結果を表示することができます。また、この構成があると、例えばロボットではなくて、ずっと何かのデータを取ってPCに送り続ける(データロガーという)ような装置を作ることもできます。
上の図ではCPUの中にUARTとありますが、これはシリアル通信を行うためのCPUの機能の名称です。下の節で簡単に説明します。
最近のノートPCなどはCOMポート(シリアル通信ポート)が無い機種もあります。ということでA33Fはシリアル通信をUSBに変換するチップ「FT232R」を搭載しており、ケーブルがあればPCと直接通信することができます。
※USBドライバのインストールを行っていない場合はこちらのページを参照願います。
まず、図の右の方から見ていきます。sdPIC33FのUART端子とFT232Rがつながっています。送受信されるデータはここでUSBからシリアル通信へ変換されます。USBケーブルを通してPCのUSBポートに接続されており、PCの入り口ではUSBとして送受信されています。PC内部ではVCPの働きによりソフト的にUSBをシリアル通信に変換されます。よって、dsPIC33FとPCは見た目上、シリアル通信でつながっています(上の「シリアル通信ポートでモニタを構成」の図と同じ)。
UARTの概略
FT232RはdsPIC33FのUARTにつながっています。UARTとは Universal
Asynchronous Receiver Transmitter の略で、訳すと「汎用非同期受/送信機」という意味になります。UARTはシリアル通信をおこなう機能で、大抵のマイコンには付いているものです。dsPIC33FJ256GP710にはUARTが2つ付いています。以後、1番目をUART1、2番目をUART2とします。
A33F上のFT232RにはUART1の方がつながっています。
シリアル通信の概略
シリアル通信にはいろいろな種類がありますが、UARTでおこなわれるように信号のHIGH/LOWで1/0を表し、1線(プラスGND)をHIGH/LOWして信号を送るのはかなり昔から使われている方法でした。同期シリアル通信と非同期シリアル通信の2つがあります。マイコンなどで単に「シリアル通信」というと「非同期シリアル通信」をさすことが多いです。
同期シリアル通信は、どのタイミングで値を読むかを伝える信号線がデータ線以外にもあり、パルス状の信号(クロックという)が出ています。よって、送受信間でタイミングがズレるということはあまりありませんが、線の数が1本多くなるという欠点があります。
非同期シリアル通信は、待機状態はHIGHを維持しています。もし、待機状態がLOWだったら断線しているということがわかります。送信する方は、送信初めにHIGH->LOWに信号を変えます。受信側はこのHIGH->LOWの変化の瞬間をデータ受信開始の瞬間と判断し、そこから時間を計測し始めます。送信側も受信側もあらかじめ通信スピードを合わせておきます。受信側は通信スピードから計算し、いつデータを読んだらそれがなんビット目か、というのを判断してデータをうけとっていきます。
UARTは非同期通信です。
非同期通信の代表的なものにRS232(EIA232)というものがあります。sdPICのUARTは0V/3.3V電圧レベルのEIA232の通信をおこなうことができます。これは詳しく知っておいた方がよいかもしれませんので是非詳しく検索して調べてみてください。以下概略です。
RS232(EIA232)コンピュータが出来始めたころからの方式ですので、当初は300bps(bit/Sec:一秒間に何ビット送れるか)とかの非常に低速でした。信号線のHIGH/LOWだけで1/0を判断するのはスピード的に限界があるのであまり高速な通信はできません。パソコンの普通のCOMポート(USBシリアルではなく純粋のCOM)はRS232C仕様(*1)になっていますが、115200bpsぐらいが限界のようです。但し、今回はUARTよりも高速なUSBを経由していますので、実はもっと高速に通信することができました(実験の結果わかった。)。これについては後ほど。
(*1)マイコンとは電圧と極性が違うので注意。詳しくは浅草ギ研のサンプルプログラムページに多数事例が出てます。
USBの概略
USBはUARTと同じようにシリアルデータの送受信を行う通信装置ですが、2本の通信線が一対になっており、2本の線の電圧差で1/0を判定します。2本の線を近づけておけば片方にノイズが乗れば、もう片方の線にも同じようにノイズが乗るので電圧差には影響は出ません。この方がノイズに強くて高速にデータを通信することができます。
また、UARTは単にデータ本体を送るだけですが、USBは1つのUSBラインに複数の装置がつながっても良いようにデータ以外にもいろいろな制御信号も送っています。よってドライバソフトというものが必要になります。また、活線挿入といい、電源が入った状態でコネクタを抜き差ししても良い設計となっており、コネクタの形状もきまっています。コネクタは大抵はPCのようなマスタ側でAタイプ、子機側でBタイプになります。Bタイプは種類がいろいろあり、A33FではminiBというタイプを採用しています。
以上、簡単に通信系の概略を説明しましたが、詳しくは書籍やインターネット情報を検索して深く勉強してください。ここではとりあえず、簡単にPCにデータを送ってみる方法をご紹介します。機会があればPCからのデータを受信する、などの実用的な例の紹介をしようと思います(以後のページ?にて)。
接続図
FT232RとdsPICの接続は次のようになっています。
USB mini-Bコネクタに接続されたUSBはFT232Rを経由してdsPICのUART1に接続されています。U1はUART1を表します。TXは送信、RXは受信を表します。TXとRXはそれぞれクロスして結線されています。
USBの「VBUS」は電源ラインです。USBは5V、数百mAまでの電力を子機に供給することができます。A33Fの場合はノイズカット回路を経由してVCC(電源の意味)につながっています。VCCは別の場所で3.3V電源を生成する回路につながっており、このVSUBをつなげばUSBからの5VでA33Fを駆動する3.3V電源も生成されます。つまり、バッテリなどをつながなくても、USBポートをPCに接続すればA33Fに電源が供給されます。
接続
では実際に実験に入りますのでA33FとPCを接続して下さい。
COM番号の確認
USBドライバのインストールのページですでにUSBドライバをインストールし、COMポートの番号を確認していると思います。ではもう一度、仮想COMポートの番号を確認してみます。
「スタート」−>「マイコンピュータ」−>「システム情報を表示する」 −>「ハードウェア」タブ−>「デバイスマネージャー」ボタンを選択するとデバイスマネージャーが開きます。
この中に「ポート(COMとLPT)」というのがありますのでクリックすると、現在のCOMポートの構成が確認できます。
下は私のPC(デスクトップタイプ)の例です。
A33FのUARTからUSB経由でPCに文字を送ってみる
※このページではC言語の用語が沢山出てきますが、ビギナーの方は各自C言語の初級本なども参照しながら読み進めてください。
では実際にUSB経由でPCと通信してみましょう。ここではA33Fから文字を送信してPCで表示させてみます。これにより、いろいろな計算結果などをPCでモニタすることができます。
A33Fからの送信以外にも、PCから何かデータを送ったものを受信したり、受信割り込み(別なプログラムを中断して受信)を使ったりと、UARTではいろいろなことができますが、このページではとりあえず文字を送信するだけとします。UARTのいろいろな使い方はまた後のページで説明致します。
<標準出力装置とprintf( )関数>
C言語では「標準入出力」という概念があり、printf( ) という代表的な関数があります。これは「標準”出力装置”へ文字を出力する」というものです。それぞれの機器で標準出力装置が何なのかは違います。たとえば、PC上で動くC言語の場合は標準出力装置はモニタになり、printf(
)関数で文字を表示させるプログラムを書くとモニタに文字が出力(表示)されます。dsPICの場合はUART1が標準入出力装置になります。
dsPICの場合は、Cコンパイラ、つまりC30には「よく使われる関数」を用意しています。このよく使われる関数を集めたものを「ライブラリ」といいます。dsPICのprintf(
)関数はC30のライブラリに入っています。よって、C30が無いとprintf関数を使うことはできません。
<printf( )関数を使えるようにする準備>
C30の場合はライブラリが複数に分割されています。ライブラリは使うことを宣言しないとコンパイル時に組み込まれません。printf(
) 関数を使用するための宣言文は uart.h と stdio.h の2つにありますので両方をプログラム中でインクルードする必要があります。具体的にはプログラムの中に次の2行を追加します。
#include<sdtio.h>
#include<uart.h>
これらは後で作成するプログラムの中に書かれていますので後で確認してください。
<プロジェクトの作成>
では実際に文字を送信するプログラムをつくってみましょう。まずはプロジェクトを作成します。まず、MPLABを起動します。今回の説明ではVer7.50の画面になります(このページはVer8より前に書いた記事)。Ver8でも基本的な操作は同じです。
まず、いままでのようにmyProjyectフォルダにこのプロジェクト用のフォルダを作ります。
「Project」->「Project Wizard」を選択してプロジェクトウイザードを開きます。
Welcome!と出ますので「次へ」を押します。
素子の選択になりますのでA33Fに搭載されている「dsPIC33FJ256GP710」を選択し、「次へ」を押します。
次にコンパイラの選択になりますが、通常はC30が選択されているはずです。確認して「次へ」を押します。
プロジェクト名とフォルダを指定します。「Browse」ボタンを押します。
さきほど作ったフォルダ「Hello」を指定し、「ファイル名」にプロジェクト名を入れます。ここではプロジェクト名もHelloにしました。「保存」を押してください。
指定したパスが入ります。「次へ」を押します。
必要なファイルを追加するかを聞かれています。今回のプロジェクトでは下の5つのファイルが必要になります。
libp33FJ256GP710-coff.a
p33FJ256GP710.gld
p33FJ256GP710.h
stdio.h
uart.h
これらのファイルは、MPLABをインストールした時に作られた MicroChipフォルダの中(通常はC:\ProgramFilesの中にある)のMPLAB C30フォルダの中の
srcフォルダとsupportフォルダの中にあります。しかし、これらのフォルダからいちいち探したのでは面倒なのであらかじめ上のファイル5つをプロジェクトフォルダの中にコピー(右クリックで対象を保存)しておいて下さい。
5つをコピーしたら、フォルダの中のファイル名を指定して「Add」ボタンを押します。すると右の枠にファイルが追加されます。「次へ」を押してください。
最後にSummaryが表示されますので「完了」をクリックします。
プロジェクト作成直後はなにも表示されていない状態になります。「View」−>「Project」を選択してプロジェクトウィンドウを表示させてください。
HeaderFiles/LibraryLiles/LinkerScriptが下のようにファイルが追加されていない場合はそれぞれのファイルを探して追加してください。追加はそれぞれのディレクトリを右クリックすると
Add Files というのが出ますのでそれをクリックすると追加するファイルが指定できます。
<ソースプログラムの作成>
実際のプログラム部分をソースプログラムといいます。通常はMPLABのFile->New を選んで新しいファイルを開き、プログラムを書いて
.c 拡張子で保存し、上のプロジェクトウィンドウの Source Files を右クリックしてAdd Files でそのソースプログラムをプロジェクトに追加します。ここでは、まだソースプログラムの書き方についてあまり説明していないので、とりあえず文字を送信するプログラムをこちらで用意しました。下のリンクを右クリックしてプロジェクトフォルダに保存して下さい。(左クリックをすると、ブラウザによっては中身を表示します)
Hello.c
これをプロジェクトに追加してください。プログラムの内容にについては後で説明します。下のようにSourceFilesを右クリックし、Add
Filesで追加します。追加したソースファイル名をダブルクリックすると中身が表示されます。
<ヒープの設定>
printf( )関数を使う場合はヒープを設定する必要があります。ヒープについてはCコンパイラの上級の概念になりますのでここでは詳しく説明しませんが、「printf(
)関数を使う場合は、コンパイルする前に必ずこの作業をする」、と覚えて置いてください。
Project->Build Options->Projectを指定してください。
開いたウィンドウで、MPLAB LINK30のタブを押すとしたの画面になります。ここのHeap Size:のところに 128
と入れてください。OKを押すと設定完了です。
<ビルド>
では作った(コピーした?)プログラムをビルドします。ビルドはソースファイルをマイコンに送れる形式に変換するものです。先のソースファイルをコピーしただけではまだビルドされていない状態、つまりマイコンに送る形式に変換されていないので、かならずビルドします。
ビルドを開始するには、F10キーを押すか、「Project」−>「Make」を選択します。
ビルドすると、Outputウィンドウが開いて結果を表示してくれます。下の結果では最後に「BUILD SUCCEEDED」と出ていますが、これはビルドが成功した、との意味で、これが出れば問題なく変換されたことがわかります。
ビルドに失敗すると「BUILD FAILD」 と出ます。問題のある行はerrorと出ます。下の場合はわざとプログラム中の文字を間違えたものです。72行目にエラーがあるのがわかります。このOutputウィンドウ上でエラーと出ている行をダブルクリックすると、問題のある場所にカーソルが移ります。
<デバッカの接続、書き込み>
それではプログラムを転送してみましょう。ICD2をA33Fのプログラムポートにつないで、Debugger->MPLAB
ICD2を選択します。
※注意:初めてICD2を接続する場合にはICD2に書き込みプログラムが転送されていない場合があります。ICD2は汎用の書き込み機(兼デバッカ)なのでチップによってプログラムを変える必要があり、dsPIC33FはdsPIC33F用の書き込みプログラムがMPLABからダウンロードされます(dsPIC33Fを初めてつないだとき。もしくは他のシリーズを書き込んだ後)。よって、上の操作をした後に、なにやらプログラムをアップデートするようなウィンドウが開いたら、全部OKを押してください。プログラムの書き換えには時間がかかりますのでMPLAB下のプロセスゲージが止まるまで待ちます。
正常に接続されるとOutPutに下のように表示されます。ICD2と接続されていなかったり、電源が入っていない(この場合はPCのUSBポートにつながっていない)とエラーウィンドウが表示されます。この2つが結構多くやるミスです。(プログラムの作成に夢中になるとハードの接続を忘れてしまう)
Outputの英語部分を読んでみると、ICD2に接続されて、デバイス(マイコンの素子)が発見されIDが一致して、ICDのセルフテストが通った、というのがわかります。
ICD2がつながったので書き込んでみます。書き込みはDebugger->Programを選択
又は下の書き込みボタンを押します。
正常に書き込みされるとOutPutに Programming succeeded (下の下から3行目)と表示されます。
<PC側の受信準備(ハイパーターミナルの設定と起動)>
次に、PC側での文字の受信準備をします。受け取った文字を表示するのに、Windowsではハイパーターミナルというソフトが標準でついていますのでこれを起動して設定します。
「スタート」−>「すべてのプログラム」−>「アクセサリ」−>「通信」−>「ハイパーターミナル」を選択してください。するとハイパーターミナルが開いて次のウィンドウが開きます。名前を適当に入れて、アイコンを適当に選んで「OK」を押します。
接続の設定ウィンドウになりますので、先に確認したCOMポートの番号を選びます。私の場合はCOM7でしたのでCOM7を選択します。その後「OK」を押します。
COM?のプロパティ画面が出ますので、下のように設定してください。この設定はソースプログラム内で設定されたA33F側の設定と同じにする必要があります。つまり、先のソースプログラム内では下のような設定になっています。フロー制御はフロー制御線が無いのでなしに設定します。設定が終わったら「OK」を押します。
その後、ハイパーターミナルが動き出します。プロンプトが点滅しているのが受信を待っているところです。ウィンドウ下に設定や接続時間が表示されています。表示時間が動いていないようでしたら接続が切れているので電話マークのアイコンを押して接続(通信状態)します。設定を変える場合は一旦切断する必要があるので、電話の受話器が外れているアイコンを押します。設定を変更するには指マークのアイコンを押します。
<文字の送信>
ではA33Fから文字を送ってみます。先のプログラムでは「Hello」の文字を1秒間隔で送るプログラムが書かれています。プログラムはすでにA33Fに転送されていますのでそれを起動します。プログラムの起動にはMPLAB上のRUNボタンを押します。
又は、「Debugger」−>「Run」を選択する、又はF9キーを押します。
すると、ハイパーターミナルから文字が表示されかたと思います。
このプログラムではずっとHelloを表示しつづけますので、止めたい場合はHaltアイコンを押す
又は「Debugger」−>「Halt」を選択する、又はF5キーを押します。
Haltは一時停止するだけなので、RUNを完全に止めてMPLABを通常状態にしたい場合はResetアイコンを押す
又は「Debugger」−>「Reset」−>「Prosessor Reset」を選択する、又はF6キーを押します。
プログラムの説明
プログラムの説明を簡単に行います。MPLAB上で先のソースファイルを開いてください。プロジェクトウィンドウのソースファイル名(Hello.c)をダブルクリックすると、MPLAB上でソースファイルが開きます。
プログラムはいくつかの部分に分かれていますが、中心部は「メインループ」のところです。
<Include Files>
ヘッダファイルをインクルードしています。今回は今までと違って stdio.h と uart.h というヘッダファイルが必要になります。この2つはC30コンパイラをインストールしたときにPCへコピーされます。(上ですでにプロジェクトに追加しているかと思います。)
<Fuse Setting>
ハードウェアの設定を行っています。これについては後のページで詳しく説明します。
<各種定義>
前のページではLEDの点灯を行いましたが、LEDを点灯させるのにいちいち PORTAbits.RA0 = 0; などと書いているとわかりづらいと思います。 #define
文は、プログラムの中の文字を定義(置き換える)する働きをします。これを使うと長い文字を短い文字に置き換えることができます。構文は #define
置き換え後の文字列 置き換え前の文字列 (最後に;は不要)となります。ここでは
#define LED PORTAbits.RA0
となっていますので、以後、LED と書かれるとコンパイル時には PORTAbits.RA0 に変換されます。また、
#define LED_OFF 1
#define LED_ON 0
としています。前回、LEDを点灯させるときは PORTAbits.RA0 = 0; でしたので、 LED = LED_ON; でも同じ動きになります。この方がプログラムが見やすく、また後で読んでもわかりやすくなります。定義文を使って上手にプログラムしましょう。
<ms wait>
()の中に入れた数値xmSの間なにもしないという関数です。前回も登場しました。マイコンの「タイマ」という機能を使って1mSを測定し、指定した回数だけ繰り返します。タイマの使い方など、詳しくは機能編で説明します。
<LED点滅>
この関数を実行すると、LEDが一回付いて消えます。つまりピカっと光ります。brink();と書くと実行されます。関数の作り方などについては後で説明します。
<メインループ>
行81〜84はdsPICの動作クロック(スピード)を設定しているところです。動作クロックについては後のページで詳しく説明します。
行87でLEDが接続されているRA0端子を出力に設定しています。
行89〜93はUART1の設定です。これについては後のページ(機能編)で詳しく意味を説明します。UART1を使って文字を送る場合はこのように記述するとだけ覚えてください。
行95〜98はLEDを3回点滅させているところです。プログラムが正しく起動しているか確認するためにLEDを点滅させてみました。(浅草ギ研製品は大体このように起動時にLEDが3回光ります。)
今回のポイントは行102のprintf( )関数です。先にも説明しましたとおり、printfは標準出力装置から文字データを出力します。dsPIC33Fの場合は標準出力はUART1です。引数の” ”で囲まれた内容の文字を送信します。\r\nは改行コードです。上の写真で ¥ ではなくバックスラッシュになっているのは、MPLABが英語ソフトだからです。英語ソフトでは¥キーを押すとバックスラッシュになります。このあたりの詳しくは ASCIIコード でインターネットを検索してください。
ASCIIコード で検索
ASCIIコードを見ると、文字の’H’は数字の72(0x48)、文字の’e’は101(0x65)、’l’は108(0x6c)、’o’は111(0x6f)、’w’は119(0x77)となっています。\rと\nは制御文字で、ASCIIコードでは文字を表示するのではなく、改行を表します。
※カッコ内は16進数。16進数については次のページで説明します。
シリアル通信は実際には数値だけを送っています。PC側のハイパーターミナルでは、送られてきた数値に対応する文字を画面に表示します。逆に、printf文はプログラム中の文字を数値に変えてシリアル通信で送るもの、です。
Helloの文字を送っているプログラムは実際には [72] [101] [108] [108] [111] [119] [\r]
[\n] の8個の数値データを送っています。(¥rと¥nが何の数値かは確認できませんでした。0x00-0x1fの中のどれかです)
ためしに、このHelloの文字を別なもの(但し半角英語のみ)に変えてみてください。その文字がハイパーターミナルに表示されると思います。
おわりに
ひきつづき、C言語での四則演算などを行い、その結果をprintf文でモニタしてみます。
2007年11月8日
|