2003/11/28 【ソフトウエア編TOPに戻る】
今回は、115.PCD4511でステッピングモータ制御のページでH8-3048用に作ったプログラムをPIC16F873用に移植してみましたのでご紹介します。環境はCCSのCコンパイラに適用します。また、シリアル通信によってコマンドを受け取り、ステッピングモータを制御する機能なども付加してみましたので、併せてご紹介します。ハードウエアは9.PIC学習用ボードと14.PCD4511パルスモータテストボードでご紹介しているボードを利用します。
353−1.PIC16F873のピン割り当て
PIC16F873にはRAに6ポート、RBとRCにそれぞれ8ポートの各PIOがあります。今回のプログラムでは、それぞれを以下の役割に割り当ててみました。
|
RA |
用 途 |
RB |
用 途 |
RC |
用 途 |
|
RA0 |
未使用 |
RB0 |
DATA0 |
RC0 |
CSチップセレクト信号 |
|
RA1 |
未使用 |
RB1 |
DATA1 |
RC1 |
RD書き込み信号 |
|
RA2 |
未使用 |
RB2 |
DATA2 |
RC2 |
WR読み出し信号 |
|
RA3 |
未使用 |
RB3 |
DATA3 |
RC3 |
A0アドレス信号 |
|
RA4 |
未使用 |
RB4 |
DATA4 |
RC4 |
A1アドレス信号 |
|
RA5 |
BUSY入力 |
RB5 |
DATA5 |
RC5 |
RSTリセット信号 |
|
|
端子なし |
RB6 |
DATA6 |
RC6 |
RS232C TXD信号 |
|
|
端子なし |
RB7 |
DATA7 |
RC7 |
RS232C RXD信号 |
RA5のBUSY信号だけが入力端子で、その他は全てPCD4511を制御するための出力端子です。RA0〜4は現在未使用ですが、今後はRS485通信を行う際のアドレス情報として利用しようと考えています。また、CSチップセレクト信号やRSTリセット信号は、ソフトウエアを介さずに完全にハードウエアで処理してしまうことも可能ですが、今の所はPIOに割り当てておきます。
353−2.主要部分はヘッダファイルにする
PCD4511を制御する上で作ったいくつかの関数類は、ヘッダファイルとしてひとつにまとめてしまったほうが取り扱いが楽です。ここではH8版からの移植と同時にヘッダファイルにしました。
ここをクリックするとダウンロードできます。pcd4511.H ダウンロードしたヘッダファイルは、CCS CコンパイラをインストールしたファイルのDevicesというフォルダに入れて使います。関数は今後必要に応じて増やしたり修正を加えて行くことになるかと思いますが、その都度、ここのファイルを更新することにしましょう。
以下にヘッダファイルの内容を掲載します。
|
///////////////////////////////////////////////////////// |
ここではヘッダファイル内部のプログラムについての解説は省略させて頂きます。ステッピングモータコントローラPCD4511の設定動作に深く関係する内容ですので、115.PCD4511でステッピングモータ制御のページをご参照下さい。
353−3.ステッピングモータ制御用プログラム例1 npm102.C
次に、上のヘッダファイルを利用したプログラム事例をご紹介します。正転方向に480パルス分回転して3秒停止します。次に逆転方向に480パルス分回転して再び3秒停止します。これの繰り返しです。正転後の停止は通電状態の静止なので、強い静止トルクが得られ、逆転後の停止は無通電状態の停止なので、フリーの状態です。
ここをクリックするとダウンロードできます。npm102.c
|
/******************************************************** |
プログラムの動作はコメント分を参照して下さい。頭にpcd_と付いている関数は、全て上でご紹介しているヘッダファイルpcd4511.hに記載しているものです。プログラムの始めに#include <pcd4511.h>と宣言している点にご注意下さい。
353−4.ステッピングモータ制御用プログラム例2 npm103.C
せっかくなので、もう少しだけ高度なプログラムも作ってみましょう。パソコンからシリアル通信でコマンドとパラメータを受け取り、ステッピングモータの動作を制御します。パソコン側はハイパーターミナルを利用してコマンドを送信します。ハイパーターミナルの通信条件は以下の通りです。

使用できる制御コマンドは以下の通りです。
| No | コマンド | 意 味 | パラメータ |
| 1 | s | 回転開始 | なし |
| 2 | e | 回転停止 | なし |
| 3 | c | 回転方向 | 0:正転 1:逆転 |
| 4 | p | 回転速度 | pps(1秒あたりのパルス数)で設定 |
| 5 | r | 回転角度 | 回転パルス数 |
| 6 | o | OTSビット | 0:ドライバハイインピーダンス(無効) 1:ドライバ動作(有効) |
例 ) r480 と入力してEnter → 回転角度を480パルス分にプリセット。(まだ回転しない)
p200と入力してEnter → 回転速度を200ppsにプリセット。(まだ回転しない)
s と入力してEnter → 200ppsで回転を開始して、480パルス後に停止する。
注意)
OTSビットでモータドライバの動作を有効か無効に設定しています。無効の場合はモータのコイルをドライブする出力がハイインピーダンス状態となり、モータはフリー状態となり動作しません。有効状態でモータドライバが動作します。有効状態でモータが停止している場合は通電状態なので強い停止トルクが得られます。
ここをクリックするとダウンロードできます。npm103.C
|
/******************************************************** シリアル通信でコマンドを受け取り、ステッピングモータの |
プログラムの説明
以下に要点だけをご説明します。
■1.PICでのシリアル通信設定
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7)
上記のプリプロセッサで、RS232C通信のボーレート9600bpsと、送信端子RC-6ピンと受信端子RC−7ピンの設定をしています。CCS Cコンパイラでは、シリアル通信機能(USART)を持たないPICでも、ソフト的にシリアル通信機能を持たせることができますが、今回はPIC16F873のUSART機能を利用する形とします。
■2.ステッピングモータの初期設定
pcd_init(); //PCD4511の初期化
pcd_ots(0);
//OTS出力なし
pcd_cw(0); //正転
pcd_speed(200); //200ppsを回転速度に設定
ここでは、ステッピングモータを制御するためのデバイスPCD4511に、基本的な情報を書き込んでいます。
■3.コマンドの受信と返信
printf("Input Command and Enter \r\n");
gets(rxdata);
puts(rxdata);
CCS Cコンパイラでは、printf文を利用して簡単に外部へのデータ送信が可能になっていて便利です。ここではハイパーターミナルにコマンド入力を促すメッセージを送信しています。
その後gets(rxdata);でハイパーターミナルからのコマンド入力を受け付けます。gets( );関数はシリアルポートからCRコード(Enterキー)が入力されるまで文字列を受信し、最後にNULLコード'\0'を付け加えます。受信した文字列は、ここではrxdata[10]の配列変数に格納されることになります。
そして、利用者が入力したコマンドを、puts(rxdata);でハイパーターミナルに返信します。本当は利用者が1文字入力するごとに返信したいところですが、今回はこれらの関数を使って文字列ごとに受信/返信を行って簡単にすませているので、利用者がコマンドを入力し終わってEnterキーを押すまで返信されません。
CCS Cコンパイラを使うと、シリアル通信のプログラムがこんなに簡単に組めてしまいます。
■4.パラメータ部分の抽出
for(i=0;i<9;i++){
para[i] = rxdata[i+1];
if(rxdata[i+1] == '\0') i = 9;
}
利用者がハイパーターミナルから入力するのは、先頭の1文字が動作の種類を決めるコマンドで、それに続く数値が動作の範囲や内容を決めるパラメータという取り決めをしています。なので、パラメータ部分は必ず2文字目以降ということになり、それをpara[9]という配列変数に格納することによってパラメータ部分だけを抽出しています。
■5.パラメータの数値化
p_data = atol(para);
抽出したパラメータは文字列なので数字としての意味を持っていません。ここではatol( );関数を使って、文字列をlong型の数値に変換しています。atol( );関数はC言語の標準関数ですが、これを利用するためにプログラムの先頭部分で #include <stdlib.h> を追加している点に注意して下さい。
■6.コマンドごとの処理
残りのswitch文の部分では、受信した1文字目のコマンドごとにその処理内容を変えて、ステッピングモータの実際の制御を行っています。
■動作上の注意
今回、pcd_init( );関数内でPCD4511の初期設定を行っていますが、数ある動作モードの中でS字加減速で指定パルス分回転したら自動的に停止するプリセット動作としています。この場合、回転開始を始める前に、必ずプリセット値(回転パルス数→ここでは回転角度に相当)を設定しないと動作しません。
今回の事例では、必ず r コマンドでパルス数を指定してから s コマンドで回転を開始させる必要があります。それ以外には特に制約事項はなく、 e コマンドで停止させたり、c コマンドで回転方向を変えたり、p コマンドで回転速度を変えたりという操作は、モーター回転途中でも実行させることが可能です。
353−5.実験風景
![]() |
ごちゃごちゃしてて分かり辛いと思いますが、左の写真が実験風景です。左側からステッピングモータ、中央がドライバ用テスト基板、そして右側がPIC用実験基板です。その上にある小さな基板は、PICとドライバを接続するためのコネクタ変換を行っています。 ドライバ用テスト基板は、もともとH8と直接接続することを前提としているため、PIC用実験基板とはちょっと合わない部分があるためです。変換基板は以下のような接続になっています。 |
![]() |
単純に言うと、RAポート側に行ってしまったBUSY信号の入力端子を、その他の制御用出力信号と一緒のコネクタにまとめてから、ドライバ用テスト基板に接続するためのものです。 |
今回の実験をもとに、次の段階ではRS485制御による多ノード間の通信へ発展させようと思います。
PCD4511の持つS字加減速動作は、非常に短い時間内での指定しかできません。なので、見るからに関節を滑らかに動かすといった比較的長い時間をかけてのS字加減速はできません。自然な加減速でロボットアームを動かすような場合は、CPU側から断続的に回転速度の制御を行ってあげる必要があるかもしれません。
今のところ、PCD4511に対してはコマンドやパラメータの書き込み制御しか行っていません。しかしデバイスとしては内部状態の読み出しにも対応しているため、ソフトウエアの組み方次第によっては、もっと木目の細かい制御が可能ではないかと思います。