まずはサンプルソフトとしてプロジェクトファイルを含む一括ファイルを下記よりダウンロードできます。筆者と同じ開発環境(MPLAB IDE 8.92 + CCS 4.132)の方はそのまま転用できます。
圧縮ファイルにはマスター側とスレーブ側の両方が入っています。
マルチマイコンのソースに関してはprocess_multipic.cにまとまっており、その中の関数に関してはそれぞれコメントが記述されおり、詳しくはそちらを参照願います。main.cのどこに追加すべきかもソース内で確認願います。
スレーブのマイコンの設定についてだけ特記しますが、ハードウェア編で説明があったようにマスター側にスレーブ側マイコンの設定を行う必要があるという点については、process_multipic.cのmultipic_startup関数内で設定する必要があります。
下のソースの下側8行がそれにあたり、1の値で入力、2の値で出力と設定しています。スレーブ側マイコンの構成を変更する場合はここを編集したうえでスレーブ側も設定変更する必要があります。
また、スレーブ側の設定はソース上ではなく電源を入れてスイッチで行います。
以下はprocess_multipic.c内の抜粋
//マルチマイコンの初期値設定
void multipic_startup(){
int tmp1 = 0;
//端末側の起動を待つ
//ウォッチドッグタイマーリセットとウェイト
restart_wdt(); delay_ms(250);
restart_wdt(); delay_ms(250);
restart_wdt();
//初期値設定
pic_target_add = 1;
for(tmp1=0;tmp1<16;++tmp1){
pic_life[tmp1] = 0;
pic_port3[tmp1] = 0x0000;
pic_port4[tmp1] = 0x0000;
}
//各スレーブのマイコンの仕様を割り当て(スレーブ側の設定と合わせる必要がある)
pic_mode[1] = 0x02;//端末はすべて出力
pic_mode[2] = 0x02;//端末はすべて出力
pic_mode[3] = 0x02;//端末はすべて出力
pic_mode[4] = 0x02;//端末はすべて出力
pic_mode[5] = 0x01;//端末はすべて入力
pic_mode[6] = 0x01;//端末はすべて入力
pic_mode[7] = 0x01;//端末はすべて入力
pic_mode[8] = 0x01;//端末はすべて入力
}
先にプロトコルって何?2進数って何?という人は先にグーグル先生に聞いてから読み進めることをお勧めします。
通信手順としてはマスター側マイコンからの問いかけに対して該当するスレーブ側マイコンが応答する流れとしており、マスター側マイコンは何も接続されていなければひたすら応答依頼のコマンドを送信し続けます。
スレーブ側マイコンは自分に割り当てられたアドレスと一致するコマンドが取得できた場合のみ応答します。
コマンド | 説明 |
---|---|
0x01 | SOH ヘッダ開始 |
0x05 | ENQ 照会 |
0x01 | Address スレーブマイコンアドレス |
0x04 | EOT 転送終了 |
コマンド | 説明 |
---|---|
0x01 | SOH ヘッダ開始 |
0x11 | DC1 装置制御1 |
0x05 | Address スレーブマイコンアドレス |
0x34 | DATA PORT3の下2桁 |
0x12 | DATA PORT3の上2桁 |
0x78 | DATA PORT4の下2桁 |
0x56 | DATA PORT4の上2桁 |
0x04 | EOT 転送終了 |
コマンド | 説明 |
---|---|
0x01 | SOH ヘッダ開始 |
0x06 | ACK 肯定応答 (入力データとしてきた場合は否定応答として0x15 NACを返す) |
0x01 | Address 自機アドレス |
0x00 | NULL 空データ |
0x00 | NULL 空データ |
0x00 | NULL 空データ |
0x00 | NULL 空データ |
0x04 | EOT 転送完了 |
コマンド | 説明 |
---|---|
0x01 | SOH ヘッダ開始 |
0x06 | ACK 肯定応答 (出力データとしてきた場合は否定応答として0x15 NACを返す) |
0x05 | Address 自機アドレス |
0x34 | DATA PORT3の下2桁 |
0x12 | DATA PORT3の上2桁 |
0x78 | DATA PORT4の下2桁 |
0x56 | DATA PORT4の上2桁 |
0x04 | EOT 転送完了 |
シリアルの設定については下記のとおりです。おそらくこのマイコンでは限界かと思います。
マスター側マイコンからのコマンドは10mSec単位で送信されています。
右の図ではマスター側マイコンのUSARTのTXに2ch(水色の線)を接続しています。対して1ch(オレンジの線)はRXに接続しています。
マスター側マイコンからのコマンドに対して各スレーブ側マイコンがすべて応答されている事を表します。
また、スレーブ側マイコンを8個とした場合、80mSec単位(12.5回/秒)で更新されていることになります。
対して1chはそのままマスター側マイコンのUSARTのTXに接続し、2chはスレーブ側マイコンのTXに接続しています。ダイオード1N4148が分岐基板上にあるため、他の信号は影響受けず、自身の出力した信号だけを取得しており、マスター側マイコンからの8回の要求に対して自身のアドレスに該当する1回にだけ応答している事がわかります。
一つのコマンドを見てみると1.5mSec以内に完了しています。マスター側マイコン内でのI2C処理やほかの処理を考えると10mSec間隔で各スレーブ側マイコンに要求を出すのは妥当な数字と思います。
試しに5mSec間隔で試してみましたがデータの取りこぼしが解決できず安定しませんでした。
筆者の場合状況に応じて処理をまとめるためにmode(又はstep)という変数を元に全体の処理を管理しています100未満はスタートアップ処理として例えば各機器が問題なく稼働するかのチェックを行う処理を行い、900以下では異常事態を想定した停止処理を入れたりしています。
サンプルプロジェクトのファイルでメイン処理ではスレーブ側マイコンのアドレス5のデータを1に入れるという感じで全ての入力値を出力側に移しているだけになっています。
実際にはここで複雑な処理を追加していくことでハードウェア編で記述したように多くのスイッチや表示灯の処理が行えます。
以下はmain.cの抜粋
if(mode >= 0 && mode < 100){ mode = 100; }else if(mode >= 100 && mode < 200){ // if(multipic_process_one != 0){ multipic_process_one = 0; //マルチマイコン用 multipic_process(); //テスト用に取得した入力値をそのまま出力値として設定する //※スタートアップのmultipic_startupで入力用、出力用マイコンのアドレスを指定している。 //※1~4は出力用マイコン、5~8は入力用マイコンとして指定している pic_port3[1] = pic_port3[5]; pic_port4[1] = pic_port4[5]; pic_port3[2] = pic_port3[6]; pic_port4[2] = pic_port4[6]; pic_port3[3] = pic_port3[7]; pic_port4[3] = pic_port4[7]; pic_port3[4] = pic_port3[8]; pic_port4[4] = pic_port4[8]; } }else{ }
©ZEATEC co.,ltd.