Comments
Description
Transcript
Visual C++によるPPI入門書
チュートリアル Visual C++によるPPI入門書 www.interface.co.jp 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。 保障の内容と制限 弊社はドキュメント内の情報の正確さに万全を期しています。万一、誤記または誤植等があった 場合、弊社は予告なく改訂する場合があります。ドキュメントまたはドキュメント内の情報に起 因するいかなる損害に対しても弊社は責任を負いません。 製品に含まれるバグ、あるいは製品の供給(納期遅延),性能、もしくは使用に起因する付帯的損害 もしくは間接的損害に対して、弊社に全面的に責がある場合でも、弊社はその製品に対する改良 (正常に動作する)、代品交換までとし、金銭面での賠償の責任は一切負わないものとしますので、 予めご了承ください。 ドキュメント内の図や表は説明のためであり、ユーザ個別の応用事例により変化する場合があり ます。 著作権,知的所有権 弊社は本製品に含まれるおよび本製品に対する権利や知的所有権を保持しています。 本製品はコンピュータ ソフトウェア(プログラム),図,文章,写真等を含んでいます。 複製の禁止 弊社の許可なく、本製品(ドキュメント含む)の全て、または一部に関わらず、複製,改変等を行う ことはできません。 責任の制限 弊社は、弊社または再販売者の予見の有無に関わらず、発生したいかなる特別損害,偶発的損害, 間接的な損害,重大な損害について、責任を負いません。 補償の内容 本ドキュメントで使用している弊社製品の補償については、各製品のマニュアルを参照してくだ さい。 本書の内容の一部または全部を、無断で転載することを禁止します。 本書の内容は、将来予告なく変更することがありますので、予めご了承ください。 © 2001, 2007 Interface Corporation. All rights reserved. www.interface.co.jp TUT-0034 改訂履歴 年 月 Ver. 1.1 2007年5月 1.0 2001年3月 改 訂 内 容 ●対象型式追加。 ●製品紹介削除。 ●インストール説明更新。 ●技術資料一覧追加。 ●フォーマット変更。 新規作成 本チュートリアルをご使用の際は、必ず各製品型式の最新のドキュメント(USER'S MANUAL,Help)を併せて参照してください。また、最新のドライバソフトウェアをご使用くださ い。 USER'S MANUAL,ドライバソフトウェアは弊社Web site(www.interface.co.jp)からダウンロードで きます。(Helpはドライバソフトウェアに含まれています) -1- Interface Corporation TUT-0034 目 次 第1章 1.1 1.2 1.3 第2章 PPI概要 6 ポート ............................................................................................................................................. 6 グループ制御................................................................................................................................. 7 動作モード ..................................................................................................................................... 7 PPI製品のインストール 8 2.1 コンピュータへの設置方法......................................................................................................... 8 2.1.1 デバイスドライバのインストール.................................................................................. 9 ■Windows Vistaをご使用の場合 ......................................................................................... 9 ■Windows XP Embedded,Windows XP,Windows Server 2003 をご使用の場合............ 12 ■Windows 2000 をご使用の場合....................................................................................... 14 2.2 サンプルプログラム,Help,ヘッダファイル,インポートライブラリ,最新情報ドキュメン トファイルのインストール................................................................................................................ 16 第3章 3.1 3.2 3.3 第4章 Visual C++によるPPI制御 17 ピンアサインメント................................................................................................................... 18 DLLプロシージャ呼び出しによるプログラミング(概要).................................................... 20 PPI製品制御概略 ......................................................................................................................... 20 チュートリアル 21 4.1 モード 0 入力/出力...................................................................................................................... 23 Step1.メインウィンドウ作成...................................................................................................... 24 Step2.DLL関数宣言 ...................................................................................................................... 25 Step3.初期化処理と終了処理...................................................................................................... 28 Step4.モード 0 入出力 .................................................................................................................. 32 4.2 モード1入力............................................................................................................................... 38 Step1.プロジェクトの作成(モード 1 入力側)........................................................................... 40 Step2.モード 1 入力 ...................................................................................................................... 40 Step3.プロジェクトの作成(モード 0 出力側)........................................................................... 46 Step4.モード 0 出力 ...................................................................................................................... 47 4.3 モード1出力............................................................................................................................... 50 Step1.プロジェクトの作成(モード 1 出力側)........................................................................... 53 Step2.モード1出力 ...................................................................................................................... 53 Step3.プロジェクトの作成(モード 0 入力側)........................................................................... 55 Step4.モード 0 入力 ...................................................................................................................... 55 4.4 モード 2 入力............................................................................................................................... 60 Step1.プロジェクトの作成(モード2入力側)........................................................................... 62 Step2.モード 2 入力 ...................................................................................................................... 62 Step3.プロジェクトの作成(モード0出力側)........................................................................... 66 Step4.モード 0 出力 .................................................................................................................... 67 Interface Corporation -2- TUT-0034 4.5 モード 2 出力............................................................................................................................... 69 Step1.プロジェクトの作成(モード 2 出力側)........................................................................... 69 Step2.モード 2 出力 ...................................................................................................................... 70 Step3.プロジェクトの作成(モード 0 入力側)........................................................................... 72 Step4.モード 0 入力 ...................................................................................................................... 72 4.6 割り込み処理............................................................................................................................... 77 Step1.プロジェクト作成 .............................................................................................................. 81 Step2.モード1出力(割り込み処理) ........................................................................................... 81 第5章 FbiPpi.DLLリファレンス 87 PpiOpen .......................................................................................................................................... 88 PpiClose .......................................................................................................................................... 88 PpiControl....................................................................................................................................... 88 PpiInputPort.................................................................................................................................... 89 PpiOutputPort ................................................................................................................................. 89 PpiSetEventMask............................................................................................................................ 90 PpiGetEventMask........................................................................................................................... 90 PpiSetEventConfig ......................................................................................................................... 91 PpiGetEventConfig......................................................................................................................... 92 PpiSetTimerConfig......................................................................................................................... 93 PpiGetTimerConfig ........................................................................................................................ 94 PpiGetTimerCount ......................................................................................................................... 95 PpiGetResetInStatus ....................................................................................................................... 95 PpiEventRequestPending ............................................................................................................... 96 PpiCommonGetPciDeviceInfo....................................................................................................... 97 エラーコード一覧 ........................................................................................................................ 98 第6章 6.1 6.2 6.3 8255 PPIコントローラ説明 99 ポートA,B,C................................................................................................................................. 99 グループA制御,グループB制御 ............................................................................................. 99 各ビットの対応......................................................................................................................... 100 技術資料紹介 110 -3- Interface Corporation TUT-0034 はじめに 平素は格別のご高配を賜り、厚く御礼申し上げます。本冊子は、初めて弊社PPI製品を利用し、Visual C++にて制御プログラムの作成を行われる方を対象に、製品の導入からプログラム作成までに関 し説明したものです。プログラム初心者の方が弊社製品をご利用頂き、またVisual C++にてプログ ラムの開発を行われる際の手助けになればと考えております。 記述する内容に関しましては、基本的なことにとどまっております。 また、弊社Web site(www.interface.co.jp)ではFAQ,製品マニュアル,および本チュートリアル記載の サンプルプログラムのソース(BPC-0810)の公開を行っておりますので、こちらも併せてご覧頂け ますと、より一層ご理解を深めて頂けるものと思います。 注意事項 本冊子では、使用する環境をWindows Vista/XP/XP Embedded/Server 2003/2000+Visual C++を想定 し記載しております。 Windows NT/Me/98/95をご利用の場合、I/Oモジュールのインストール方法が本冊子に記載した内 容とは異なりますのでご注意ください。こちらに関しましては、弊社製品マニュアルをご確認く ださい。 対応OSはI/Oモジュール型式によって異なりますので、対応ソフトウェア(GPC-2746C)のReadme もしくはHelpでご確認ください。 対象環境 本チュートリアルは以下の制約事項があります。 PCI-2746C PCI-2747A 対象型式 (PCI) CPZ-2746 対象型式 (CPZ) CTP-2746 対象型式 (CTP) 対象ユーザ 制御用電子機器および、コンピュータ等に関して基本的な知識を有している方。 ※ 本冊子は上記の弊社製品型式のみに対応しています。 製品の詳細は弊社Web siteを参照してください。 Interface Corporation -4- TUT-0034 本チュートリアルを行うにあたり、別途以下の製品が必要となります。 <CTP-2746,PCI-2746Cを使用する場合> ・TNS-9601×1台: 垂直96ピンネジ変換端子台 ・ECO-66xx×1本: 96ピンハーフピッチケーブル <CPZ-2746を使用する場合> ・TBZ-960x×1台: 垂直96ピン変換端子台 ・WRZ-66xx×1本: 96ピンハーフピッチコネクタ接続ケーブル <PCI-2747Aを使用する場合> SET-LP01(PCI-2747A,TRM-2601*1,CAB-9816ME*2 各一点のセット)が2点必要です。 ※1 TRM-2601×2台: 30点スモールタップ端子台 ※2 CAB-9816ME×2本: 34ピンフラットコネクタ両端コネクタケーブル(1.6m) 尚、PCI-2747Aは2枚必要になります。 -5- Interface Corporation TUT-0034 第1章 PPI概要 PPIとはProgrammable Peripheral Interfaceの略で、コンピュータ(CPU)と周辺機器間の制御とデータ 転送を行うための8255という型番のICのことです。8255は、パラレルI/Oインタフェースデバイス で、8ビット単位で入出力が行えるポートが3つあり、プログラムによる制御でデータ入力,データ 出力,ステータス信号入力,コントロール信号出力に使用することができます。 Intel 8255(相当品) (NEC:μPD8255AC-5) 8255は、8ビット単位のデータをパラレル方式で転送できるデバイスで、単なる入出力,単方向の ハンドシェーク入出力,双方向のハンドシェーク入出力の3つの動作が行えます。そのため、セン トロニクス・インタフェースといったような、パラレル方式の通信製品として使用することもで きます。 8255には8ビットの入出力ポートが3個あり、それらのポートの性質をうまく使うことで、通常の デジタル入出力製品よりもきめ細かなハンドシェーク入出力が行えます。また、先程説明したよ うに、単なるデジタル入出力としても使用することができます。 その3つの入出力ポート,制御方法,動作について詳しく説明していきます。 1.1 ポート 8255には8ビットの入出力ポートが3個あり、それぞれをポートA,ポートB,ポートCと呼びます。ま た各ポートごとに独特の性質を持っていますので、ポートの選択によって8255の適応性が生かさ れます。 ポートA ポートB ポートC 入力時 ラッチ入力あるいはバッファ入力動作 出力時 ラッチ出力動作 入力時 ラッチ入力あるいはバッファ入力動作 出力時 ラッチ出力動作 入力時 バッファ入力動作(ラッチされません) 出力時 ラッチ出力動作 ポートCはモードによって2つの4ビットポートに分割して使用することができま す。また、ポートA,Bのコントロール信号の出力ポート、あるいはステータス信 号の入力ポートとして用いることができます。 ラッチ:変化する入出力信号を特定の時点で、その状態を保持すること。 バッファ:入出力信号を一時的に蓄積すること。 Interface Corporation -6- TUT-0034 1.2 グループ制御 8255を使用するにあたっては、入出力ポートをA,B,Cの3つに分けると同時に、ポートAとポートC の半分、ポートBとポートCの半分といった、2つのグループに分けて考えることもできます。 このとき、それぞれをグループA,グループBと呼びます。 8255 ポート C ポート A 上位 4 ビット 下位 4 ビット ポート B グループ B 制御 グループ A 制御 1.3 動作モード 8255はその使用方法によって次の3つのモードより動作を選択することができます。 モード0 基本的な入出力ポート モード1 コントロール信号,ステータス信号による制御を伴う入出力ポート モード2 双方向データを扱う入出力ポート ポートA ポートC ポートC 上位4ビット 下位4ビット モード0 8255 OR 入力 ポートB モード1 モード2 8255 8255 OR 出力 入力 出力 制御信号 入出力 制御信号 また、使用する目的に合わせて、各グループごとにモードを設定することができます。可能なモー ドの組み合わせは次の6通りです。 グループA (1) モード0 (2) モード0 (3) モード1 (4) モード1 (5) モード2 (6) モード2 グループB モード0 モード1 モード0 モード1 モード0 モード1 -7- Interface Corporation TUT-0034 第2章 PPI製品のインストール 作成するアプリケーションからアナログ入力制御を行う場合、当然のことながらアプリケーショ ンを実行するコンピュータにPPI製品が組み込まれていなければなりません。 ここではWindowsVista/XP/Server 2003/2000+Ver. 5.0またはVer. 6.0環境における、弊社PPI製品のイ ンストール方法を記載します。Windows NT/Me/98/95ではインストール方法がここに記載する内容 とは異なります。こちらに関しては、製品マニュアルまたはオンラインドキュメントをご確認く ださい。 2.1 コンピュータへの設置方法 ※ 写真は実物と異なる場合があります。 ①コンピュータ本体の電源が“OFF”であることを確認し、電源ケーブルをACコンセントから外しま す。その後、外装カバー,スロットカバーを外します。 ②拡張用スロットへI/Oモジュールを差し込みます。 <例> PCI コネクタ ビス留め I/O モジュール 金メッキ端子がコネクタに隠れていることを確認する。 コンピュータ 基板の左右の端に力を入れ、カツンとショックがある まで押し込む。 ! 注意 製品は正しい向きに実装してください。間違った向きに実装した場合、コンピュータ,I/Oモジ ュールを破損する恐れがあります。 ③パネルをコンピュータ本体とビス留めしてください。 ④本体へ外装カバーを元通り取り付け、電源ケーブルをACコンセントに接続します。その後、コ ンピュータを起動します。 以上でI/Oモジュールの設置は完了です。次にドライバのインストールを行います。 Interface Corporation -8- TUT-0034 2.1.1 デバイスドライバのインストール ■Windows Vistaをご使用の場合 Administratorsのグループに所属しているユーザが、インストールを行ってください。 ※ 「続行するにはあなたの許可が必要です」と警告が表示されることがあります。その場合、 「続行」をクリックしてください。 ①Windows Vistaが起動すると、「新しいハードウェアが見つかりました」が表示されます。 ②「ドライバソフトウェアを検索してインストールします(推奨)」をクリックします。 ③「オンラインで検索しません」をクリックします。 -9- Interface Corporation TUT-0034 ④「ディスクはありません。他の方法を試します」をクリックします。 ⑤「コンピュータを参照してドライバソフトウェアを検索します(上級)」をクリックします。 ⑥ドライバ保存先の「¥Win2000」フォルダを指定し、「次へ」をクリックします。 Interface Corporation - 10 - TUT-0034 ⑦ファイルのコピーが始まります。 ※ 「ドライバソフトウェアの発行元を検証できません」と表示された場合、「このドライバ ソフトウェアをインストールします」をクリックします。 ⑧インストールが完了した旨のダイアログボックスが表示されるので、「閉じる」ボタンをクリッ クします。 以上で、Windows Vista用のドライバインストールは完了です。 - 11 - Interface Corporation TUT-0034 ■Windows XP Embedded,Windows XP,Windows Server 2003をご使用の場合 Administratorsのグループに所属しているユーザが、インストールを行ってください。 ※ Windows XP Embeddedは、Windows XPと同様の手順で、ドライバのインストールができます。 (ただし、OSイメージにデバイスの検出に必要なコンポーネントが含まれている必要がありま す。) ①Windows XP Embedded,Windows XP,Windows Server 2003が起動すると、 「新しいハードウェアの 検出ウィザード」が表示されます。 ②「一覧または特定の場所からインストールする(詳細)」が選択されていることを確認し、「次へ」 をクリックします。 ③「次の場所で最適のドライバを検索する」を選択し、「次の場所を含める」にチェックをつけ、 ドライバ保存先の「¥Win2000」フォルダを指定し、「次へ」をクリックします。 ドライバ保存先の「¥Win2000」フォルダを 指定します。 ④ファイルのコピーが始まります。 Interface Corporation - 12 - TUT-0034 ⑤インストールが完了した旨のダイアログボックスが表示されるので、「完了」ボタンをクリッ クします。 以上で、Windows XP Embedded,Windows XP,Windows Server 2003用のデバイスドライバのインス トールは完了です。デバイスドライバのインストール完了後以降は、システム起動時に上記②の ように「新しいハードウェアの検索ウィザード」が起動することはありません。 • Windows XP Embedded 用ハードウェア情報ファイルのインポートをする場合 ・ドライバダウンロード方法 ①弊社Web siteよりGPC-2746CのDriver Disk [Windows Vista,XPe,XP,2003,2000]をダウン ロードします。 ②ダウンロードしたプログラムを実行すると、「Win2000」フォルダが作成されます。 ・ドライバインストール方法 ①Windows XP Embedded 開発環境の Component Database Manager を起動します。 ②弊社製品のハードウェア情報ファイルをインポートします。作成した「Win2000」フォ ルダ内の拡張子がSLDのファイルを、画面の指示に従ってインポートしてください。 ③以上で、ハードウェア情報のインポートは完了です。 - 13 - Interface Corporation TUT-0034 ■Windows 2000をご使用の場合 Administratorsのグループに所属しているユーザが、インストールを行ってください。 ①Windows 2000が起動すると、「新しいハードウェアの検出ウィザード」が表示されるので、「次 へ」ボタンをクリックします。 ②「デバイスドライバに最適なドライバを検索する(推奨)」を選択し、「次へ」ボタンをクリック します。 ③「検索場所のオプション」で「場所を指定」を選択し、「次へ」ボタンをクリックします。 ④「参照」ボタンをクリックし、「製造元のファイルのコピー元」にドライバ保存先の「¥Win2000」 フォルダを指定します。その後、「OK」ボタンをクリックします。 Interface Corporation - 14 - TUT-0034 ⑤デバイスドライバが見つかった旨のダイアログボックスが表示されるので、「次へ」ボタンを クリックします。 ⑥ファイルのコピーが始まります。 ⑦インストールが完了した旨のダイアログボックスが表示されるので、「完了」ボタンをクリッ クします。 以上で、Windows 2000用のデバイスドライバのインストールは完了です。 デバイスドライバのインストール完了後以降は、システム起動時に上記②のように「新しいハー ドウェアの検索ウィザード」が起動することはありません。 インストールを完了したら、リソース(I/Oアドレス,割り込みレベル)の設定,競合の有無の確認を行 ってください。 ドライバのインストールが正常に行われると、システムプロパティのデバイスマネージャに表示 されます。 ここに I/O モジュールが追加 されます。 - 15 - Interface Corporation TUT-0034 2.2 サンプルプログラム,Help,ヘッダファイル,インポートライブラリ,最新情報ドキュメントファイル のインストール 1. 弊社Web siteよりGPC-2746CのUtility Diskをダウンロードします。 2. ダウンロードしたプログラムを実行すると、「SETUP」フォルダが作成されます。 3.「SETUP」フォルダ内のSETUP.EXEを実行して下さい。プログラムが起動しインストールが開 始されます。 インストールが完了すると、「スタート」メニューの「プログラム」に、「Interface GPC-2746C」 が追加されます。 Interface Corporation - 16 - TUT-0034 第3章 Visual C++によるPPI制御 Visual C++より、PPI製品を制御するには、DLLを利用します。Windowsアプリケーションプログ ラムおいては直接I/Oやメモリにアクセスすることは禁止されています。従って、PPI製品に対し て直接制御を行うことができません。そこで、Visual C++ではI/Oモジュールに対して制御を行う プログラム(DLL)から必要なプロシージャ(関数)を呼び出し、このDLLを介してI/Oモジュールの制 御を行います。 Visual C++ アプリケーション ダイナミックリンクライブラリ (DLL) Win32 API 仮想デバイスドライバ (CP2746Cxx.sys) 入力 PPI製品 出力 - 17 - Interface Corporation TUT-0034 3.1 ピンアサインメント PPI製品への信号入力、またはPPI製品からの信号出力は、I/Oモジュールのコネクタ部分より行わ れますが、使用する製品型式によって、各ピンに割り当てられた役割が異なります。配線時には、 これらピンアサインメントをよく確認の上、配線してください。 以下、弊社PCI-2746Cのピンアサインメントを一例として記載します。 CN1:96ピンハーフピッチコネクタ(オス) (PCR-E96LMDC(本多通信工業製)(相当品)) −COM1 −COM1 1PA0 1PA1 1PA2 1PA3 1PA4 1PA5 1PA6 1PA7 1PB0 1PB1 1PB2 1PB3 1PB4 1PB5 1PB6 1PB7 +COM1 +COM1 −FCOM NC IR.IN1 NC NC +FCOM −RCOM1 RSTOUT/P.OUT −COM2 −COM2 1PC0 1PC1 1PC2 1PC3 1PC4 1PC5 1PC6 1PC7 NC NC NC NC NC NC NC NC +COM2 +COM2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 NC: 本製品内部で未接続 Interface Corporation - 18 - −COM3 −COM3 2PA0 2PA1 2PA2 2PA3 2PA4 2PA5 2PA6 2PA7 2PB0 2PB1 2PB2 2PB3 2PB4 2PB5 2PB6 2PB7 +COM3 +COM3 −FCOM NC NC NC IR.IN2 +FCOM −RCOM2 RSTIN −COM4 −COM4 2PC0 2PC1 2PC2 2PC3 2PC4 2PC5 2PC6 2PC7 NC NC NC NC NC NC NC NC +COM4 +COM4 TUT-0034 ●コネクタの+COM1∼4,+FCOM端子からPCIバスの+5V電源が出力されています。 ●入出力信号はそれぞれ対応したCOMをご使用ください。 <COMの対応> 信 号 1PA0∼1PA7 1PB0∼1PB7 1PC0∼1PC7 2PA0∼2PA7 2PB0∼2PB7 2PC0∼2PC7 IR.IN1,IR.IN2 RSTOUT/P.OUT RSTIN COM −COM1,+COM1 −COM2,+COM2 −COM3,+COM3 −COM4,+COM4 −FCOM,+FCOM −RCOM1 −RCOM2 PCI-2747A,CTP-2746,CPZ-2746に関しましては、製品マニュアルまたは弊社製品カタログを参照し てください。 - 19 - Interface Corporation TUT-0034 3.2 DLLプロシージャ呼び出しによるプログラミング(概要) Visual C++よりDLLプロシージャ呼び出しプログラミングを行うには、弊社PPI制御用ソフトウェ ア(FBIPPI.DLL)をダイナミックリンクし、使用します。DLLとはダイナミックリンクライブラリ (Dynamic Link Library)の略でアプリケーションの実行時に動的にリンクして利用できる関数のラ イブラリです。関数とは実行時に1つの単位として処理されるコードの集まりを意味します。 Visual C++にてDLL関数を利用するには、FBIPPI.LIBファイルをリンクしてDLL関数のアドレスを 指定します。(リンクの方法は後で記載しています) 3.3 PPI製品制御概略 PPI製品への制御を行う場合、基本的に下記の制御シーケンス(順番)で行います。 1 I/Oモジュール初期化 プログラム起動 2 I/Oモジュール設定 8255の設定 3 各種処理 データの入出力 4 終了処理 プログラム終了 ①I/Oモジュールの初期化 Visual C++で作成されたアプリケーションがPPI製品への操作を行う場合、まずアプリケーショ ンは、PPI製品を利用可能な状態にする必要があります。 この処理がI/Oモジュールの初期化です。I/Oモジュールの初期化を行うと、プログラムはPPI製 品へのアクセスが可能となります。本処理が行われないとPPI製品へのアクセスは行えません。 ②I/Oモジュールの設定 I/Oモジュールに搭載された8255の各ポートに対し、モードの設定や各ポートをコンピュータか ら見て入力/出力のどちらで使うかを設定します。 ③各種処理 データ・ポートより信号の入力または出力を行います。 ④終了 I/Oモジュールの使用終了を行うための手続きです。プログラム終了時には必ず必要です。 Interface Corporation - 20 - TUT-0034 第4章 チュートリアル ここでは、実際に弊社PPI製品を用いて、I/Oモジュールへの信号入力およびI/Oモジュールからの 信号出力を行います。本チュートリアルを行うにあたっては、ご使用になるI/Oモジュールにより 以下の準備を行ってください。 CTP-2746,PCI-2746Cをご使用の場合 CTP-2746,PCI-2746Cにてチュートリアルを行う場合、以下の製品が必要になります。 CTP-2746,PCI-2746C 1枚:PPI製品 TNS-9601 1台:垂直96ピンネジ変換端子台 ECO-66xx 1本:96ピンハーフピッチコネクタ両端ケーブル コンピュータにPPI製品(CTP-2746,PCI-2746C)を実装し、ケーブル(ECO-66xx)を用いて端子台 (TNS-9601)に接続してください。 CPZ-2746をご使用の場合 CPZ-2746にてチュートリアルを行う場合、以下の製品が必要になります。 CPZ-2746 1枚:PPI製品 TBZ-960x 1台:垂直96ピン変換端子台 WRZ-64xx,WRZ-66xx 1本:96ピンハーフピッチケーブル コンピュータにPPI製品(CPZ-2746)を実装し、ケーブル(WRZ-66xx)を用いて端子台(TBZ-960x)に接 続してください。 INPUT/OUTPUT 端子台 PPI製品 - 21 - Interface Corporation TUT-0034 PCI-2747Aをご使用の場合 PCI-2747Aにてチュートリアルを行う場合、以下の製品が必要になります。 SET-LP01(工業高校向けラーニングパック)×2点 PCI-2747A PPI製品×2枚 TRM-2601 30点端子台×2台 CAB-9816ME 34ピンフラットコネクタ両端ケーブル×2本 コンピュータにPPI製品(PCI-2747A)を2枚実装し、それぞれケーブル(CAB-9816ME)を用いて端子 台(TRM-2601)に接続してください。 端子台 INPUT/OUTPUT PPI製品 Interface Corporation - 22 - TUT-0034 4.1 モード0入力/出力 PCI-2746Cには8255が2個実装されています。ここでは、その2個の8255のうち一方をモード0の出 力に、もう一方をモード0の入力に設定し、簡単な通信を行うプログラムを作成します。 8255① 通信 8255② PCI-2747Aを使用する場合は、一方の製品から、もう一方のボートに対し通信を行います。 本チュートリアルでは便宜上製品に実装された8255をそれぞれ「8255①」,「8255②」と表記して います。 では、使用する製品型式に応じて、下図のように対応するピンを接続してください。 <PCI-2746Cを使用する場合> 8255①側(入力) 信号 ピン 1PA0 3 1PA1 4 8255②側(出力) 信号 ピン 2PA0 51 2PA1 52 ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ 1PA7 10 2PA7 58 -COM1 -COM2 1 29 -COM3 -COM4 49 77 +COM1 +COM2 19 47 +COM3 +COM4 67 95 ※ ピン番号はTNS-9601のものです。 <PCI-2747Aを2枚使用する場合> 8255①側(入力) 信号 ピン 1PA0 3 1PA1 4 8255②側(出力) 信号 ピン 2PA0 51 2PA1 52 ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ 1PA7 10 2PA7 58 -COM1 -COM2 1 29 -COM3 -COM4 49 77 +COM1 +COM2 19 47 +COM3 +COM4 67 95 ※ ピン番号はTRM-2601のものです。2台のTRM-2601を接続するように配線してください。 ※ 製品番号「0」のPCI-2747Aを8255(1)の端子台に、製品番号「1」のPCI-2747Aを8255(2)の端子 台に接続してください。 - 23 - Interface Corporation TUT-0034 Step1.メインウィンドウ作成 ここでは、これから作成するプログラムの画面作成を行います。 Visual C++を起動し、新しいプロジェクトを作成します。 1. 「ファイル」メニューより「新規作成」を選択します。 2. 新規作成ダイアログが表示されますので、「プロジェクト」タブを選択します。 ・MFC AppWizard(exe)を選択し、「プロジェクト名」に“PpiMode0_InOut”と記入します。 ・「位置」には作業するフォルダを指定してください。その後「OK」をクリックします。 プロジェクト名を書き込みます MFC AppWizard (exe) を選択します 作業するフォルダを指定します 3. 作成するアプリケーションの種類は「ダイアログベース」、リソースで使用する言語の指定は 「日本語」を選択し、「次へ」をクリックします。 ダイアログベースを 選択します 4. ステップ2,ステップ3では「次へ」をクリックし、ステップ4で「終了」をクリックします。 Interface Corporation - 24 - TUT-0034 5. 新規プロジェクト情報というダイアログが表示されますので「OK」をクリックします。 ここまでで、新規プロジェクトの作成は完了です。 Step2.DLL関数宣言 DLL関数を利用するには、FBIPPI.LIBファイルを使って関数の位置を指定し、関数の呼び出しに 使う引数の識別を行わなければなりません。 ここで一度宣言したDLL関数は、Visual C++の関数と同じようにコードで呼び出すことが可能とな ります。 1. プロジェクトにFBIPPI.LIB, FBIPPI.Hのパス設定を行います。 ・「ツール」→「オプション」を選択し、「ディレクトリ」タブを選択します。 - 25 - Interface Corporation TUT-0034 ・表示するディレクトリを「インクルードファイル」にします。 ・空白の部分をダブルクリックします。 ダブルクリックします インクルードファイルにします クリックします ・ディレクトリの追加を行います。ディレクトリ先を <ProgramFiles>¥Interface¥Gpc2746C¥includeに設定して「OK」をクリックします。 include を選択します Interface Corporation - 26 - TUT-0034 ・下図のようにディレクトリが追加されます 追加されたディレクトリ ・次に、表示するディレクトリを「ライブラリファイル」にします。 ・ディレクトリの追加を行います。ディレクトリ先を <Program Files>¥Interface¥Gpc2746C¥libと設定して「OK」をクリックします。 lib を選択します ・下図のようにディレクトリが追加されます。 追加されたディレクトリ - 27 - Interface Corporation TUT-0034 2.プロジェクトにFBIPPI.LIBファイルをリンクします。 ・「プロジェクト」→「設定」を選択し、「リンク」タブを選択します。 ・設定の対象を「全ての構成」に設定し、「オブジェクト/ライブラリモジュール」に“fbippi.lib” と書き込み「OK」をクリックします すべての構成にします fbippi.lib をリンクします “FBIPPI.LIB”,“FBIPPI.H”は、Setupでインストールされる<インストール先>¥lib. <インストール先>¥includeにあります。(インストール先:<Program Files>¥Interface¥Gpc2746C) Step3.初期化処理と終了処理 ここでは、実際のプログラム作成を行う前に、PPI製品の初期化処理と終了処理に関して、知って おかなければならないこと、および制約事項について記載します。 PPI製品の制御を行うには、まず製品の初期化を行わなければなりません。製品の初期化は以下の コードにより行います。 (List 1-1:製品の初期化) //製品の初期化を行います。(1 軸目の初期化) HANDLE hDeviceHandle; //デバイスハンドル hDeviceHandle = PpiOpen(“FBIPPI1”, FBIPPI_FLAG_SHARE); この時、FBIPPI1に設定する値は、使用する製品のデバイス名を指定します。デバイス名は、「コ ントロールパネル」より「システム」を選択し「システムのプロパティ」の「デバイスマネージ ャ」タブを選択すると確認できます。 ここにデバイス名が表示されます。 Interface Corporation - 28 - TUT-0034 製品の初期化はPpiOpen関数により行います。 「使用例」 使用する製品のデバイス名を指定します。 HANDLE hDeviceHandle; hDeviceHandle = PpiOpen(“FBIPPI1”, PPI_FLAG_SHARE); デバイスハンドルを格納する HANDLE型の変数を指定します。 同じデバイスを重複(共有)してオープ ンすることを許可するフラグです。 また、アプリケーションの終了時、もしくは処理の終了時に、オープンした軸に対して必ず終了 処理を行わなければなりません。 製品の終了処理は以下のコードにより行います。 (List 1-2:製品の終了処理) //終了処理 INT nRet; //関数の実行結果 nRet = PpiClose(hDeviceHandle); 製品の終了処理はPpiClose関数より行います。ここで、注意しなければならないのは、設定する 引数のhDeviceHandleです。hDeviceHandle には製品の初期化の際に取得した、PpiOpen関数の戻り 値を指定します。PpiOpen 関数実行時、その戻り値であるhDeviceHandleには有効なハンドル(番 号)が格納されています(上記List参照)。ハンドルとは使用するデバイスの接続に関する情報が格納 されたメモリ領域を、識別するための値を示します。 プログラム作成時、終了処理を行うデバイスのhDeviceHandleの値が、PpiOpen実行時に取得され た値となるように、PpiOpenとPpiCloseは必ず組になるよう注意してください。 ハンドル PpiOpen 「使用例」 製品のオープン時に取得 したデバイスハンドルを 指定します。 nRet = PpiClose(hDeviceHandle); 関数が失敗するとエラーコードが 格納されます。 PpiClose - 29 - Interface Corporation TUT-0034 では実際に製品の初期化と終了を行うプログラムを作成します。 1. 表示メニューからClassWizardを起動します。 2. 「メッセージマップ」タブを選択し、以下のように設定します。 プロジェクト Ppi_Mode0_InOut クラス名 CPpi_Mode0_InOutDlg オブジェクト CPpi_Mode0_InOutDlg メッセージ WM_CREATE PpiMode0_InOut を指定します CPpiMode0_InOutDlg を指定します WM_CREATE を指定します 関数の追加をクリックします CPpiMode0_InOut を指定します 3. 「関数の追加」をクリックします。 4. 同様にメッセージに「WM_DESTROY」を選択し、「関数の追加」をクリックします。 5. 「OK」をクリックし、ClassWizardを終了します 6. ワークスペースの「FileView」タブをクリックし、「Source Files」フォルダを展開します。 「PpiMode0_InOutDlg.cpp」をダブルクリックしてファイルを開き、(List1-3)の網掛け部分を記 述します。 (List 1-3:PpiMode0_InOutDlg.cpp の変更コード) // PpiMode0_InOutDlg.cpp : インプリメンテーション ファイル // #include "stdafx.h" #include "PpiMode0_InOut.h" #include "PpiMode0_InOutDlg.h" #include "fbippi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif HANDLE ghDeviceHandle1; //☆PCI-2747A 使用時のみ追加します //HANDLE ghDeviceHandle2; Interface Corporation - 30 - TUT-0034 7. ワークスペースの「ClassView」タブをクリックし、「CPpiMode0_InOutDlg」フォルダを展開 します。 8. フォルダの下の「OnCreate」をダブルクリックし、OnCreate関数に(List 1-4)を記述します。 (List 1-4:CppiMode0_InOutDlg クラスの OnCreate 関数のコード) int CPpiMode0_InOutDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: この位置に固有の作成用コードを追加してください //PCI-2746C(PCI-2747A 使用時は 1 枚目)の製品をオープンします ghDeviceHandle1 = PpiOpen( "FBIPPI1", FBIPPI_FLAG_SHARE); if (ghDeviceHandle1 == INVALID_HANDLE_VALUE) { MessageBox("製品 1 のオープンに失敗しました"); exit(0); } //☆PCI-2747A を使用する場合の追加コード //PCI-2747A の 2 枚目の製品をオープンします //ghDeviceHandle2 = PpiOpen( "FBIPPI2", FBIPPI_FLAG_SHARE); //if (ghDeviceHandle2 == INVALID_HANDLE_VALUE) { // MessageBox("製品 2 のオープンに失敗しました"); // exit(0); //} return 0; } 9. 同様に、「OnDestroy」をダブルクリックし、OnDestroy関数に(List 1-5)を記述します。 (List 1-5:CppiMode0_InOutDlg クラスの OnDestory 関数のコード) void CPpiMode0_InOutDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください INT nRet; //関数の実行結果 //PCI-2746C(PCI-2747A 使用時は 1 枚目)の製品をクローズします nRet = PpiClose(ghDeviceHandle1); if(nRet != FBIPPI_ERROR_SUCCESS) { MessageBox("製品 1 のクローズに失敗しました"); exit(0); } //☆PCI-2747A を使用する場合の追加コード //PCI-2747A の 2 枚目の製品をクローズします //nRet = PpiClose(ghDeviceHandle2); //if(nRet != FBIPPI_ERROR_SUCCESS) { // MessageBox("製品 2 のクローズに失敗しました"); // exit(0); //} } プログラムの入力が終わったら、保存した後、プログラムを実行してみてください。何もエラー が表示されなければ、製品の初期化および終了処理部分のプログラムは完成です。 - 31 - Interface Corporation TUT-0034 Step4.モード0入出力 では、実際に通信プログラムの作成を行います。ここでは8255②のポートAから出力したデータ を8255①のポートAより入力します。 ※ PCI-2747Aを2枚使用する場合は1枚目の8255のポートAから出力したデータを2枚目の8255の ポートAより入力します。 1. まず8255①と8255②に対して入力,出力の設定を行います。OnCreate関数に(List 1-6)の網掛け部 分のコードを追加してください。 (List 1-6:CppiMode0_InOutDlg クラスの OnCreate 関数の追加コード) int CPpiMode0_InOutDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: この位置に固有の作成用コードを追加してください INT nRet; //関数の実行結果 //PCI-2746C(PCI-2747A 使用時は 1 枚目)の製品をオープンします ghDeviceHandle1 = PpiOpen( "FBIPPI1", FBIPPI_FLAG_SHARE); if (ghDeviceHandle1 == INVALID_HANDLE_VALUE) { MessageBox("製品 1 のオープンに失敗しました"); exit(0); } //☆PCI-2747A を使用する場合の追加コード //PCI-2747A の 2 枚目の製品をオープンします //ghDeviceHandle2 = PpiOpen( "FBIPPI2", FBIPPI_FLAG_SHARE); //if (ghDeviceHandle2 == INVALID_HANDLE_VALUE) { // MessageBox("製品 2 のオープンに失敗しました"); // exit(0); //} //8255①をモード 0 全点入力に設定 nRet = PpiControl(ghDeviceHandle1, FBIPPI_8255_CONTROLLER1,0x9b); if (nRet != FBIPPI_ERROR_SUCCESS) { MessageBox("8255①のモード設定に失敗しました"); PpiClose(ghDeviceHandle1); exit(0); } //8255②をモード 0 全点出力に設定 //PCI-2747A を使用する場合は ghDeviceHandle2,FBIPPI_8255_CONTROLLER1 に変更してください nRet = PpiControl(ghDeviceHandle1, FBIPPI_8255_CONTROLLER2,0x80); if (nRet != FBIPPI_ERROR_SUCCESS) { MessageBox("8255②のモード設定に失敗しました"); PpiClose(ghDeviceHandle1); exit(0); } return 0; } 2. ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE0_INOUT_DIALOGをダブ ルクリックします。 Interface Corporation - 32 - TUT-0034 ダブルクリックします 3. ダイアログボックスの必要のないボタン,スタティックテキストを削除します。 「OK」ボタン,「キャンセル」ボタン,「TODO:ダイアログのコントロールをここに配置」とい うスタティックテキストをそれぞれ選択し、Deleteキーを押してください。 それぞれ選択して Delete キーで削除します 4. ダイアログ上に、①出力データを書き込むエディットボックスと②入出力を行うボタンと③ 入力データを表示するエディットボックスを配置します。それぞれのオブジェクトにマウス カーソルをあわせ、右クリック→「プロパティ」で以下のように設定してください。 ①出力データを書き込むエディットボックス ID IDC_OUTDATA_WINDOW 「スタイル」タブを選択し複数行にチェック ②入出力を行うボタン ID IDC_INOUT キャプション モード0入出力 ③入力データを表示するエディットボックス ID IDC_INDATA_WINDOW 「スタイル」タブを選択し、複数行にチェック ① 出力データを書き込 むエディットボック スを配置します ② 入出力を行うボタン を配置します ③ 入力データを表示す るエディットボック スを配置します - 33 - Interface Corporation TUT-0034 5. ①出力データを書き込むエディットボックスにデータを格納するメンバ変数の追加設定を行 います。 ・エディットボックス①にマウスカーソルをあわせ右クリックし、「ClassWizard」を選択して「メ ンバ変数」タブを表示します。 ・次のように設定し、「変数の追加」をクリックします。 プロジェクト名 PpiMode0_InOut クラス名 PpiMode0_InOut コントロール IDC_OUTDATA_WINDOW ・さらに以下のように設定し、「OK」をクリックします。 メンバ変数 m_szOutData カテゴリ 値 変数のタイプ Cstring 6. ③同様に入力データを表示するエディットボックスにデータを格納するメンバ変数の追加 を行います。以下のように設定します。 プロジェクト名 PpiMode0_InOut クラス名 CPpiMode0_InOut コントロール IDC_INDATA_WINDOW メンバ変数 m_szInData カテゴリ 値 変数のタイプ CString 以下のようにメンバ変数が追加されます。 追加したメンバ変数 7. 先程作成した「モード0入出力」ボタンにマウスカーソルをあわせ、右クリックし 「ClassWizard」を選択します。「メッセージマップ」を選択し、以下のように設定した後、 「関数の追加」をクリックします。 プロジェクト PpiMode0_InOut クラス名 CPpiMode0_InOut オブジェクト IDC_INOUT メッセージ BN_CLICKED Interface Corporation - 34 - TUT-0034 関数の追加をクリックします ・メンバ関数名を決定するダイアログが表示されますので、”OnInOut”となっていることを確認し、 「OK」をクリックします。その後ClassWizardを終了します。 ・OnInOut関数を記述します(ワークスペースのClassViewを表示し、CInOutDlgクラスを展開して OnInOut()をダブルクリックすると、OnInOut関数が編集できる位置にカーソルがジャンプして くれます)。プログラムリストの説明については後述します。 (List 1-7:CPpiMode0_InOutDlg クラスの OnInOut 関数のコード) void CPpiMode0_InOutDlg::OnInOut() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; //関数の実行結果 INT SendNum; //出力回数 INT nLen; //出力文字数 BYTE bSend; //出力データ char SendBuf[32]; //出力バッファ BYTE bRecv[32]; //入力データ UpdateData(TRUE); strcpy(SendBuf,m_szOutData); nLen = strlen(SendBuf); for(SendNum = 0; SendNum < nLen; SendNum++){ bSend = (BYTE)SendBuf[SendNum]; //8255②のポートAからデータ(1 文字)を出力します。 //PCI-2747A を使用する場合は ghDeviceHandle2,FBIPPI_8255_CONTROLLER1 に変更してください nRet = PpiOutputPort(ghDeviceHandle1,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_A ,bSend); if(nRet != FBIPPI_ERROR_SUCCESS) { MessageBox("8255②ポート A の出力に失敗しました"); PpiClose(ghDeviceHandle1); exit(0); } //8255①のポートAからデータ(1 文字)を入力します。 nRet = PpiInputPort(ghDeviceHandle1,FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_A,&bRecv[SendNum]); if(nRet != FBIPPI_ERROR_SUCCESS) { MessageBox("8255②ポート A の出力に失敗しました"); PpiClose(ghDeviceHandle1); exit(0); } } bRecv[SendNum] = NULL; m_szInData.Format("%s", bRecv); UpdateData(FALSE); } 以上で、プログラムの作成は完了です。 では、保存した後実行してください。 - 35 - Interface Corporation TUT-0034 プログラムを実行し出力データを書き込むエディットボックスに「HELLO」と入力し、「モード 0入出力」ボタンをクリックしてください。 入力データを表示するエディットボックスに「HELLO」と表示されます。 8255②より出力されたデータが、端子台を介し8255①に入力され、その入力されたデータが表示 されています。 端子台 HELLO HELLO PPI 製品 サンプルプログラムでは半角32文字以下のメッセージが入出力できます。 では、(List 1-6)の処理を読み取ってみましょう。製品の初期化処理後プログラムは8255の設定を 行っています。8255の設定にはPpiControl関数を使用します。 「使用例」 8255に設定するコマン ドです。 設定する8255を指定します。 nRet = PpiControl(ghDeviceHandle1, FBIPPI_8255_CONTROLLER1, 0x9B); 関数が失敗するとエラー コードが格納されます。 Interface Corporation 製品のオープン時に取得したデバイスハン ドルを指定します。 - 36 - TUT-0034 第3引数に設定する8255 PPIコントローラ制御レジスタへの制御データですが、下図のように決め られています。 制御レジスタ D7 D6 D5 D4 D3 D2 D1 D0 グループB ポートC下位 1=入力 0=出力 ポートB 1=入力 0=出力 ここでは、8255①をモード0の全点入 力に、8255②をモード0の全点出力に 設定しますので、それぞれの制御レ ジスタには「10011011」と「10000000」 を設定します。 プログラム中ではこれらを16進数表 記にしていますので「0x9B」と「0x80」 を設定しています。 モード選択 1=モード1 0=モード0 グループA ポートC上位 1=入力 0=出力 ポートA 1=入力 0=出力 モード選択 00=モード0 01=モード1 1X=モード2 機能制御 1=モード選択 0=ビットセット/リセット 次に、(List 1-7)ではデータの出力を行うわけですが、Forループにて出力文字列を1文字(1バイト) ずつアスキーコードに変換し順に8255②のポートAより出力しています。データの出力には PpiOutputPort関数を使用します。 「使用例」 設定する 8255 を指定します。 nRet = PpiOutputPort(ghDeviceHandle1, FBIPPI_8255_CONTROLLER2, FBIPPI_PORT_A, bSend); 関数が失敗するとエラー コードが格納されます。 出力する 1 バイトのデータを 指定します。 出力するポートを指定します。 製品のオープン時に取得したデ バイスハンドルを指定します。 データを8255②のポートAより出力した直後、今度はそのデータを8255①のポートAより入力して います。データの入力にはPpiInputPort関数を使用します。 「使用例」 設定する 8255 を指定します。 nRet = PpiInputPort(ghDeviceHandle1, FBIPPI_8255_CONTROLLER1, FBIPPI_PORT_A, &bRecv[SendNum]); 関数が失敗すると エラーコードが格 納されます。 製品のオープン時に取 得したデバイスハンド ルを指定します。 入力する 1 バイトのデータ を格納する変数へのポイ ンタを指定します。 入力するポートを指定し ます。 最後に製品の終了処理を行ってプログラムは終了します。 - 37 - Interface Corporation TUT-0034 4.2 モード1入力 ここでは、PPI製品の8255①をモード1入力に設定し、8255②より出力されるデータを入力する制 御信号を用いた簡単な通信プログラムの作成を行います。 では、まずこの制御信号について見てみます。 8255は設定されたモードにより、定められた動作をします。この定められた動作を示しているタ イミングチャートを下図に記載します。タイミングチャートとは信号線に与える信号の手順を示 す図のことです。 H L STB IBF REIをセットしなければ、INTは Hレベルのままです。 L H INT L H RD 外部からの データ H L ラッチされたデータ 時間の経過 制御信号線は必ず5Vか0Vのどちらかの状態になります。それぞれをH(High)レベル,L(Low)レベル といいます。コンピュータ上のデータとしては「1」と「0」に相当します※2。各制御信号の名称 に関しては『99ページ 第6章 8255 PPIコントローラ説明』を参照してください。 では、このタイミングチャートを解読してみましょう。 まず、入力ポートには外部の接続機器からデータが入力されているとします。この時、接続され た外部機器よりSTBをLレベル,Hレベルの順に変化させると、入力データがラッチされ、同時にINT 信号がHレベルに変化します※3。また、STBをLレベルにした際にはIBFがHレベルに変化していま す。 そして、ラッチされたデータを読み込む(RD)とIBFがHレベルからLレベルに変化します。 ※2 PPI製品は正論理で動作しています。 ※3 INT信号を有効にするためには、ビット操作命令でREIに「1」をセットします。 以上のことから、以下のハンドシェ−ク通信が可能であると考えられます。またここでは、便宜 上通信の終了時には出力側が入力側に通信終了コードを送信するものとします。 入力側 出力側 ①INT信号がHレベルになるまで待機する ②データを読み込む ③通信終了コードが送られてくるまで①から 繰り返す Interface Corporation - 38 - ①データを出力する ②入力側のSTBをLレベル,Hレベルの順に 変化させる ③入力側のIBF信号を確認しLレベルになるま で待機する ④次のデータがある場合は①から繰り返す TUT-0034 これらのことをフローチャートにまとめると下図のようになります。 入力側(8255①) 出力側(8255②) 開始 開始 データ出力 INT は H レベル? 入力側の STB を L レベル, H レベルの順に変化させる NO YES データ読み込み 入力側の IBF は L レベル? NO NO YES 通信終了コード を受信した? YES NO 通信終了 コード? YES 終了 終了 では、下図のように対応するピンを接続してください。 <PCI-2746Cを使用する場合> 8255①側(入力) 信号 ピン 1PA0 3 1PA1 4 ・ ・ ・ ・ ・ ・ 1PA7 8255②側(出力) 信号 ピン 2PA0 51 2PA1 52 ・ ・ ・ ・ ・ ・ ・ ・ ・ 10 2PA7 58 1PC5(IBF) 1PC4(IBF) 1PC3(INT) 36 35 34 2PB7 2PC2 66 81 1PB7 18 -COM1 -COM2 1 29 -COM3 -COM4 49 77 +COM1 +COM2 19 47 +COM3 +COM4 67 95 ※ ピン番号はTNS-9601のものです <PCI-2747Aを2枚使用する場合> 8255①側(入力) 信号 ピン PA0 3 PA1 4 ・ ・ ・ ・ ・ ・ PA7 8255②側(出力) 信号 ピン PA0 51 PA1 52 ・ ・ ・ ・ ・ ・ ・ ・ ・ 10 PA7 58 PC5(IBF) PC4(IBF) PC3(INT) 28 27 26 PB7 PC2 20 25 1PB7 20 -COM1 11 -COM 11 -COM2 1 -COM 1 ※ ピン番号はTRM-2601のものです。2台のTRM-2601を接続するように配線してください。 ※ 製品番号「0」のPCI-2747Aを8255(1)の端子台に、製品番号「1」のPCI-2747Aを8255(2)の端子 台に接続してください。 - 39 - Interface Corporation TUT-0034 Step1.プロジェクトの作成(モード1入力側) 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode1_Recv)を作成します。を作 成します。(『23ページ 4.1 モード0入力/出力』でのStep1のメインウィンドウの作成を参照し てください。) 2. プロジェクトにFbiPpi.Libファイル,FbiPpi.Hファイルのパス設定を行い、ライブラリファイ ル”FpiPpi.lib”をリンクさせます。(『23ページ 4.1 モード0入力/出力』でのStep2のDLL関数宣 言を参照してください。) 3. 初期化処理と終了処理を行う関数を追加します。(『23ページ 4.1 モード0入力/出力』での Step3の初期化処理と終了処理を参照してください。) ・“FbiPpi.H”ファイルのインクルード,デバイスハンドルの変数宣言を行います。 『23ページ 4.1 モード0入力/出力』における(List1-3)と同様にコードの追加を行います。(ただし、 PCI-2746C,PCI-2747Aにおける使用製品に対応したデバイスハンドル変数の区別を行う必要 はありません。) 「MFC ClassWizard」で以下のように設定し、メッセージ「WM_CREATE」,「WM_DESTROY」に 対する関数に初期化,終了コードをそれぞれ実装します。(モード0入力/出力の(List 1-4,List1-5) を参照してください。ただし、使用製品に対応したコード変更,追加を行う必要はありません。) プロジェクト PpiMode1_Recv クラス名 CPpiMode1_RecvDlg オブジェクト CPpiMode1_RecvDlg Step2.モード1入力 次に、モード1で入力を行うためのプログラムの作成を行います。 1. データ入力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE1_RECV_DIALOG」をダブ ルクリックします。 ・表示されたダイアログボックスから、必要のないボタン、スタティックテキストを削除します。 「OK」ボタン,「キャンセル」ボタン,「TODO:ダイアログのコントロールをここに配置」という スタティックテキストをそれぞれ選択し、Deleteキーを押してください。 それぞれ選択して Delete キーで削除します Interface Corporation - 40 - TUT-0034 ・コントロールから「ボタン」と「エディットボックス」を選択し、ダイアログに貼り付けます。 ボタンとエディットボッ クスを貼り付けます ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDRECV PPIモード1 入力 IDC_CMDRECV にします 「PPI モード 1 入力」にします ・同様にして、エディットボックスにカーソルを合わせ、右クリック→「プロパティ」を選択し て以下のように設定します。 ID IDC_TXTMON IDC_TXTMON にします ・「スタイル」タブを選択し、「複数行」と「改行を許可」のチェックボックスにチェックを入 れます。 「複数行」と「改行を許可」にチェックを入れます - 41 - Interface Corporation TUT-0034 2. 受信データを表示するためのメンバ変数“m_TxtMon”を作成します。 ・先程作成した「エディットボックス」にカーソルを合わせ、右クリック→「Class Wizard」を選 択します。「メンバ変数」タブを選択し、以下のように設定した後、「変数の追加」をクリッ クします。 PpiMode1_Recv CPpiMode1_RecvDlg IDC_TXTMON プロジェクト クラス名 コントロールID それぞれの値を設定します 変数の追加をクリックします ・メンバ変数を決定するダイアログが表示されますので、以下のように設定し、「OK」をクリッ クします。これでメンバ変数“m_TxtMon”が追加されました。 メンバ変数 m_TxtMon カテゴリ 値 変数のタイプ CString それぞれの値を設定します OK をクリックします Interface Corporation - 42 - TUT-0034 3. データ受信のポーリングを行うためにTimer関数を作成します。 再びClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数 の追加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode1_Recv CPpiMode1_RecvDlg CPpiMode1_RecvDlg WM_TIMER それぞれの値を設定します 関数の追加をクリックします ・CPpiMode1_RecvDlgにタイマ識別変数の追加を行います。ワークスペースの「FileView」を表示 し、「PpiMode1_Recv ファイル」下の「Resource Files」フォルダを展開します。 “CPpiMode1_RecvDlg.c”をダブルクリックしてを開き、(List 2-1)の網掛けの部分の記述を追加し ます。 (List 2-1 CPpiMode1_RecvDlg.c のコード) // PpiMode1_RecvDlg.cpp : インプリメンテーション ファイル // #include #include #include #include "stdafx.h" "PpiMode1_Recv.h" "PpiMode1_RecvDlg.h" "fbippi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif HANDLE UINT ghDeviceHandle; timerID = 0; // デバイスハンドル // タイマ ID - 43 - Interface Corporation TUT-0034 4. データ入力処理を開始するためのメンバ関数“OnCmdRecv”の作成を行います。 ・ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の 追加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode1_Recv CPpiMode1_RecvDlg IDC_CMDRECV WM_CLICKED それぞれの値を設定します 変数の追加をクリックします ・メンバ変数名を決定するダイアログが表示されますので、“OnCmdRecv”となっていることを確 認し、「OK」をクリックします。 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 2-2)のコードを記述します。 (List 2-2 CPpiMode1_RecvDlg クラスの OnCmdRecv 関数のコード) void CPpiMode1InDlg::OnCmdRecv() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // 8255①の設定を行います // グループ A = Mode1 入力 // グループ B = Mode0 入力 // [制御データ = 10111011] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,0xbb); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // INT 信号を有効にするため、8255①グループ A の RIE に 1 をセットします // [制御データ = 00001001] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,0x09); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のビットセットに失敗しました","制御データ設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // もし Timer が作成されていなければ Timer を作成して受信を開始する if(timerID==0){ timerID=SetTimer(1, 10, NULL); if(timerID==0){ MessageBox("タイマの作成に失敗しました","Timer 設定エラー", MB_ICONERROR); } } } Interface Corporation - 44 - TUT-0034 5. ポーリング処理をTimer関数に追加します。 ワークスペースの「ClassView」を表示し、CPpiMode1_RecvDlgクラスを展開します。「OnTimer()」 をダブルクリックしてソースコードを開き、“OnTimer”関数に(List 2-3)のコードを記述します。 (List 2-3 CPpiMode1_RecvDlg クラスの OnTimer 関数のコード) void CPpiMode1_RecvDlg::OnTimer(UINT nIDEvent) { // TODO: この位置にメッセージ ハンドラ用のコードを追加するか またはデフォルトの処理を呼び出してください INT nRet; // 関数の実行結果 BYTE bRecv; // 受信データ BOOL fReadOk; // 制御信号監視用フラグ // タイマ処理 if(nIDEvent==timerID){ // 1PB7 の状態を監視し High になるまで待機します fReadOk = false; while(fReadOk == false){ nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_B,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート A の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x80){ fReadOk = true; } } // 8255①ポート A よりデータ(1 文字)を入力します nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_A,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート A の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 入力されたデータをエディットボックスに表示します m_TxtMon.Format("%d", bRecv); UpdateData(FALSE); // 受信が終了していればタイマを破棄して受信を終了する if(bRecv == 255){ KillTimer(timerID); // タイマの破棄 timerID=0; // timerID を初期化する } } CDialog::OnTimer(nIDEvent); } - 45 - Interface Corporation TUT-0034 ・次に、Timer関数の終了処理を記述します。「ClassView」で「OnDestroy」関数をダブルクリッ クして表示し、(List 2-4)の網掛け部分を追加します。 (List 2-4 OnTimer 関数の終了処理のコード) void CPpiMode1_RecvDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // タイマが作成されていれば、破棄を行う if(timerID!=0) KillTimer(timerID); // 製品クローズ nRet = PpiClose(ghDeviceHandle); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("FBIPPI1 のクローズに失敗しました","製品クローズエラー", MB_ICONERROR); } } 以上でモード1データ入力のプログラムは完成です。 Step3.プロジェクトの作成(モード0出力側) モード1での入力確認用にモード0でのデータ出力プログラムの作成を行います。 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode0_Send)を作成します。 2. プロジェクトにFBIPPI.LIBファイル,FBIPPI.Hファイルのパス設定を行い、ライブラリファイル “Fbippi.lib”をリンクさせます。 3. 作成したプログラムに、PPI製品の初期化と終了処理を行う関数を追加します。 (ここまでの手順は『23ページ 4.1 モード0入力/出力』のStep1∼Step3と同様になりますので、 そちらを参照してください。ただし、PCI-2747Aを使用する場合はデバイス名を2枚目の製品のも のに変更し、コントローラの番号を1(FBIPPI_8255_CONTROLLER1)に変更してください。) Interface Corporation - 46 - TUT-0034 Step4.モード0出力 1. データ出力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE0_SEND_DIALOG」をダブ ルクリックします。 ・表示されたダイアログボックスから、必要のないボタン,スタティックテキストを削除します。 「OK」ボタン,「キャンセル」ボタン,「TODO:ダイアログのコントロールをここに配置」とい うスタティックテキストをそれぞれ選択し、Deleteキーを押してください。 ・コントロールから「ボタン」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDSEND PPIモード0 出力 IDC_CMDSEND にします 「PPI モード 0 出力」にします 2. データ出力処理を開始するためのメンバ関数“OnCmdSend”の作成を行います。 ・ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の 追加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode0_Send CPpiMode0_SendDlg IDC_CMDSEND WM_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、“OnCmdSend”となっていることを 確認し、「OK」をクリックします。 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表 示し、(List 2-5)のコードを記述します。 - 47 - Interface Corporation TUT-0034 (List 2-5 CPpiMode0_SendDlg クラスの OnCmdSend 関数のコード) void CPpimode0_SendDlg::OnCmdSend() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 INT nLoop; // for ループ用 BYTE bRecv; // 受信データ BYTE bSend; // 送信データ BOOL fNextSend; // 制御信号監視用フラグ // 8255②の設定を行います // Mode = 0 // PortA = OUT // PortB = IN // PortC = OUT // [制御データ = 10000010] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,0x82); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); } // 8255②より 0∼255 の数値データを出力します for(nLoop=0;nLoop<=255;nLoop++){ bSend = nLoop; // 8255②のポート A からデータを出力します nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_A,bSend); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート A の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②の STB に Low パルスを送信します // 8255②の 2PC2 を Low にセットし入力側のデータをラッチします nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_C,0xfb); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②の 2PC2 を High にセットし入力側のデータラッチを終了します nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_C,0xff); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②の 2PB7 の状態を監視し、Low になるまで待機します fNextSend = false; while(fNextSend == false){ nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_B,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート B の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x00){ fNextSend = true; } } } MessageBox("送信完了","データ送信確認", MB_ICONINFORMATION); } 以上でモード0データ出力のプログラムは完成です。 Interface Corporation - 48 - TUT-0034 プログラムの入力が終わったら、保存した後、入力側/出力側のプログラムをそれぞれ実行してく ださい。まず入力側の「PPI モード1入力」ボタンをクリックしてください。まだ、なにもおきま せん。今度は出力側の「データ出力」ボタンをクリックしてください。入力側のテキストボック ス(txtMon)に下図のよう表示されます。 1∼255 まで表示され、255 が表示されると 通信が終了します。 これは、入力側/出力側、それぞれのプログラムが特定の条件を満たさない限りデータの入力/出力 を行わないようにしているためです。 また、このことによりデータの取りこぼし等を防ぎ、安定した通信を行うことが可能になります。 D0~D7 8255 STB IBF INT - 49 - Interface Corporation TUT-0034 4.3 モード1出力 ここでは、モード1出力に設定した8255(1)からデータを出力し、8255(2)よりデータを入力する 『38ページ 4.2 モード1入力』とは逆の動作をする、制御信号を用いた簡単な通信プログラム の作成を行います。 下図にモード1出力設定時のタイミングチャートを示します。 WR OBF INTR WEI をセットしなければ、 INTR は H レベルのままです。 ACK H L H L H L H L 外部への 出力データ 出力される新しいデータ 時間の経過 では、このタイミングチャートを解読してみましょう。 まず、INTR信号がHレベルのとき出力データの書き込み(WR)を行うと、INTR信号がHレベルから Lレベルに変化します※。データの書き込みが完了すると、接続された外部機器にデータが出力さ れ、OBF信号がHレベルからLレベルに変化します。この後、接続された外部機器よりACK信号を Lレベル,Hレベルの順に変化させると、OBF信号,INTR信号がもとの状態(Hレベル)に変化します。 ※ INTR信号を有効にするためには、ビット操作命令でWEIに「1」をセットします。 以上のことから、以下のハンドシェーク通信が可能であると考えられます。またここでは、便宜 上通信の終了時には出力側が入力側に通信終了コードを送信するものとします。 「出力側」 (1)データを出力する (2)INTRを確認しHレベルになるまで待機する (3)次のデータがある場合は(1)から繰り返す 「入力側」 (1)出力側のOBF信号がLレベルになるまで待機する (2)データを読み込む (3)出力側のACKをLレベル,Hレベルの順に変化させる (4)通信終了コードが送られてくるまで(1)から繰り返す Interface Corporation - 50 - TUT-0034 これらのことをフローチャートにまとめると下図のようになります。 出力側(8255(1)) 出力側(8255(2)) 開始 出力側のOBF はLレベル? Yes データ入力 出力側のACKを Lレベル,Hレベル の順に変化させる 通信終了 コード? Yes 終了 では、端子台上で下図のように対応するピンを接続してください。 -COM1~ -COM4はI/Oモジュール内で接続されていますので、接続は不要です。 ただし、外部回路との接続時は、必ず接続してください。 <PCI-2746C,CTP-2746を使用する場合> 8255(1) 側 信号 ピン 1PA0 3 1PA1 4 ・ ・ ・ ・ ・ ・ 1PA7 10 1PC7(IBF) 1PC6(STB) 1PC3(INT) 38 37 34 1PB7 18 ・ ・ ・ 8255(2) 側 信号 ピン 2PA0 51 2PA1 52 ・ ・ ・ ・ ・ ・ 2PA7 58 2PB7 2PC2 66 81 ※ ピン番号はTNS-9601のものです。 - 51 - Interface Corporation TUT-0034 <PCI-2747Aを2枚使用する場合> 8255(1) 信号 PA0 PA1 ・ ・ ・ PA7 側 ピン CNA2 CNA3 ・ ・ ・ CNA9 PC7(IBF) PC6(STB) PC3(INT) CNC9 CNC8 CNC5 PB7 CNB9 ・ ・ ・ 8255(2) 信号 PA0 PA1 ・ ・ ・ PA7 PB7 PC2 側 ピン CNA2 CNA3 ・ ・ ・ CNA9 CNB9 CNC4 ※ ピン番号はTRM-2601のものです。2台のTRM-2601を接続するように配線してください。 ※ 製品番号「0」のPCI-2747Aと製品番号「1」のPCI-2747Aを接続してください。 CPZ-2746を使用する場合 8255(1) 側 信号 ピン 1PA0 46 1PA1 45 ・ ・ ・ ・ ・ ・ 1PA7 39 1PC7(IBF) 1PC6(STB) 1PC3(INT) 11 12 15 1PB7 31 ・ ・ ・ 8255(2) 側 信号 ピン 2PA0 94 2PA1 93 ・ ・ ・ ・ ・ ・ 2PA7 87 2PB7 2PC2 79 64 ※ ピン番号はTBZ-960xのものです。 これより、プログラムの作成を行います。まず、出力側のプログラムから作成します。 Interface Corporation - 52 - TUT-0034 Step1.プロジェクトの作成(モード1出力側) 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode1_Send)を作成します。 2. プロジェクトにFBIPPI.LIBファイル,FBIPPI.Hファイルのパス設定を行い、ライブラリファイル “Fbippi.lib”をリンクさせます。 3. 作成したプログラムに、PPI製品の初期化と終了処理を行う関数を追加します。 (ここまでの手順は『23ページ 4.1 モード0入力/出力』のStep1∼Step3と同様となりますので、 そちらを参照してください。ただし、このプログラムでは出力側の処理のみを行いますので、 PCI-2747Aを使用する場合でも初期化と終了処理は一度だけ行います。) Step2.モード1出力 1. データ出力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE1_SEND_DIALOG」をダブ ルクリックします。 ・表示されたダイアログボックスから、必要のないボタン,スタティックテキストを削除します。 「OK」ボタン,「キャンセル」ボタン,「TODO:ダイアログのコントロールをここに配置」とい うスタティックテキストをそれぞれ選択し、Deleteキーを押してください。 ・コントロールから「ボタン」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDSEND PPIモード1 出力 2. データ出力処理を開始するためのメンバ関数“OnCmdSend”の作成を行います。 ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の追 加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode1_Send CPpiMode1_SendDlg IDC_CMDSEND WM_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、“OnCmdSend”となっていることを確 認し、「OK」をクリックします。 - 53 - Interface Corporation TUT-0034 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 3-1)のコードを記述します。 (List 3-1 CPpiMode1_SendDlg クラスの OnCmdSend 関数のコード) void CPpiMode1_SendDlg::OnCmdSend() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 INT nLoop; // for ループ用 BYTE bRecv; // 受信データ BYTE bSend; // 送信データ BOOL fNextSend; // 制御信号監視用フラグ // 8255①の設定を行います // グループ A = Mode1 出力 // グループ B = Mode0 入力 // [制御データ = 10100011] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,0xa3); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); } // INT 信号を有効にするため、8255①グループ A の WIE に 1 をセットします // [制御データ = 00001101] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,0x0d); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のビットセットに失敗しました","制御データ設定エラー", MB_ICONERROR); } for(nLoop=0;nLoop<=255;nLoop++){ bSend = nLoop; // 8255①のポート A からデータを出力します nRet = PpiOutputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_A,bSend); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート A の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255①の 1PB7 の状態を監視し、High になるまで待機します fNextSend = false; while(fNextSend == false){ nRet = PpiInputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_B,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート B の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x80){ fNextSend = true; } } } MessageBox("送信完了","データ送信確認", MB_ICONINFORMATION); } 以上で、モード1データ出力のプログラムは完成です。 Interface Corporation - 54 - TUT-0034 Step3.プロジェクトの作成(モード0入力側) モード1での出力確認用にモード0でのデータ入力プログラムの作成を行います。 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode0_Recv)を作成します。 2. プロジェクトにFBIPPI.LIBファイル,FBIPPI.Hファイルのパス設定を行い、ライブラリファイル “Fbippi.lib”をリンクさせます。 3. 作成したプログラムに、PPI製品の初期化と終了処理を行う関数を追加します。 (ここまでの手順は『23ページ 4.1 モード0入力/出力』のStep1∼Step3と同様になりますので、 そちらを参照してください。ただし、PCI-2747Aを使用する場合はデバイス名を2枚目の製品の ものに変更し、コントローラの番号を1(FBIPPI_8255_CONTROLLER1)に変更してください。) Step4.モード0入力 1. データ入力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE0_RECV_DIALOG」をダブ ルクリックします。 ・表示されたダイアログボックスから、必要のないボタン,スタティックテキストを削除します。 「OK」ボタン,「キャンセル」ボタン,「TODO:ダイアログのコントロールをここに配置」とい うスタティックテキストをそれぞれ選択し、Deleteキーを押してください。 ・コントロールから「ボタン」と「エディットボックス」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDRECV PPIモード0 入力 ・同様にして、エディットボックスにカーソルを合わせ、右クリック→「プロパティ」を選択し て以下のように設定します。 ID IDC_TXTMON ・「スタイル」タブを選択し、「複数行」と「改行を許可」のチェックボックスにチェックを入 れます。(ダイアログボックスへのコントロールの配置は『38ページ 4.2 モード1入力』の モード1入力を参照してください) - 55 - Interface Corporation TUT-0034 2. 受信データを表示するためのメンバ変数“m_TxtMon”を作成します。 ・先程作成した「エディットボックス」にカーソルを合わせ、右クリック→「Class Wizard」を選 択します。「メンバ変数」タブを選択し、以下のように設定した後、「変数の追加」をクリッ クします。 プロジェクト クラス名 コントロールID PpiMode0_Recv CPpiMode0_RecvDlg IDC_TXTMON ・メンバ変数を決定するダイアログが表示されますので、以下のように設定し、「OK」をクリッ クします。これでメンバ変数“m_TxtMon”が追加されました。 メンバ変数 m_TxtMon カテゴリ 値 変数のタイプ Cstring 3. データ受信のポーリングを行うためにTimer関数を作成します。 再びClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数 の追加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode0_Recv CPpiMode0_RecvDlg CPpiMode0_RecvDlg WM_TIMER ・CPpiMode0_RecvDlgにタイマ識別変数の追加を行います。ワークスペースの「FileView」を表示 し、「PpiMode0_Recv ファイル」下の「Resource Files」フォルダを展開します。 “CPpiMode0_RecvDlg.c”をダブルクリックしてを開き、(List 3-2)の網掛けの部分の記述を追加し ます。 (List 3-2 CPpiMode0_RecvDlg.c のコード) // PpiMode0_RecvDlg.cpp : インプリメンテーション ファイル // #include #include #include #include "stdafx.h" "PpiMode1_Recv.h" "PpiMode1_RecvDlg.h" "Fbippi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif HANDLE UINT ghDeviceHandle; timerID = 0; Interface Corporation // デバイスハンドル // タイマ ID - 56 - TUT-0034 4. データ入力処理を開始するためのメンバ関数“OnCmdRecv”の作成を行います。 ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の追 加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode0_Recv CPpiMode0_RecvDlg IDC_CMDRECV WM_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、“OnCmdRecv”となっていることを確 認し、「OK」をクリックします。 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 3-3)のコードを記述します。 (List 3-3 CPpiMode0_RecvDlg クラスの OnCmdRecv 関数のコード) void CPpiMode0_RecvDlg::OnCmdRecv() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // 8255②の設定を行います // Mode = 0 // PortA = OUT // PortB = IN // PortC = OUT // [制御データ = 10010010] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,0x92); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②のポート C からデータを出力します nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_C,0xff); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポートの出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // もし Timer が作成されていなければ Timer を作成して受信を開始する if(timerID==0){ timerID=SetTimer(1, 10, NULL); if(timerID==0){ MessageBox("タイマの作成に失敗しました","Timer 設定エラー", MB_ICONERROR); } } } - 57 - Interface Corporation TUT-0034 5. ポーリング処理をTimer関数に追加します。 ・ワークスペースの「ClassView」を表示し、CPpiMode0_RecvDlgクラスを展開します。「OnTimer()」 をダブルクリックしてソースコードを開き、“OnTimer”関数に(List 3-4)のコードを記述します。 (List 3-4 CPpiMode0_RecvDlg クラスの OnTimer 関数のコード) void CPpiMode0_RecvDlg::OnTimer(UINT nIDEvent) { // TODO: この位置にメッセージ ハンドラ用のコードを追加するか // またはデフォルトの処理を呼び出してください INT nRet; // 関数の実行結果 BYTE bRecv; // 受信データ BOOL fReadOk; // 制御信号監視用フラグ // タイマ処理 if(nIDEvent==timerID){ // 1BP7 の状態を監視し High になるまで待機します fReadOk = false; while(fReadOk == false){ nRet = PpiInputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_B,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート A の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x00){ fReadOk = true; } } // 8255②ポート A よりデータ(1 文字)を入力します nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_A,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート A の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255①に DAK の Low パルスを送信します nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_C,0xfb); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); } nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_C,0xff); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); } // 入力されたデータをエディットボックスに表示します m_TxtMon.Format("%d", bRecv); UpdateData(FALSE); // 受信が終了していればタイマを破棄して受信を終了する if(bRecv == 255){ KillTimer(timerID); // タイマの破棄 timerID=0; // timerID を初期化する } } CDialog::OnTimer(nIDEvent); } ・次に、Timer関数の終了処理を記述します。「ClassView」で「OnDestroy」関数をダブルクリッ クして表示し、(List 3-5)の網掛け部分を追加します。 Interface Corporation - 58 - TUT-0034 (List 3-5 OnTimer 関数の終了処理のコード) void CPpiMode0_RecvDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // タイマが作成されていれば、破棄を行う if(timerID!=0) KillTimer(timerID); // 製品クローズ nRet = PpiClose(ghDeviceHandle); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("FBIPPI1 のクローズに失敗しました","製品クローズエラー", MB_ICONERROR); } } 以上で、モード0データ入力のプログラムは完成です。 プログラムの入力が終わったら、保存した後、入力側/出力側のプログラムをそれぞれ実行してく ださい。まず出力側の「PPI モード1出力」ボタンをクリックしてください。まだ、なにもおきま せん。今度は入力側の「データ入力」ボタンをクリックしてください。入力側のテキストボック ス(txtMon)に下図のように表示されます。 ※ 1∼255まで表示され、255が表示されると通信が終了します。 これも、入力側/出力側、それぞれのプログラムが特定の条件を満たさない限りデータの入力/出力 を行わないようにしているためです。 D0~D7 8255 ACK OBF INTR 以上が、モード1による制御信号を用いた簡単な通信プログラムです。 - 59 - Interface Corporation TUT-0034 4.4 モード2入力 ここでは、PPI製品の8255(1)をモード2に設定し、8255(2)より出力されるデータを入力する制御信 号を用いた簡単な通信プログラムの作成を行います。 下図にモード2設定時のタイミングチャートを示します。 H L H L H L H L H L H L WR OBF INTR ACK STB IBF データ 出力データ 入力データ H L RD タイミングチャートを見る限りでは、データ・ポートが双方向であること以外、入出力時におけ る制御信号の変化は、モード1の入力,モード1の出力時におけるそれと変わりはありません。 そこで、通信プログラムは『38ページ 4.2 モード1入力』で使用したものを流用し、端子台の 結線を変更することで、動作の検証を行ってみます。 では、下図のように対応するピンを接続してください。 -COM1~ -COM4はI/Oモジュール内で接続されていますので、接続は不要です。 ただし、外部回路との接続時は、必ず接続してください。 <PCI-2746C,CTP-2746を使用する場合> 8255(1) 側 信号 ピン 1PA0 3 1PA1 4 ・ ・ ・ ・ ・ ・ 1PA7 10 1PC7(OBF) 1PC6(ACK) 1PC5(IBF) 1PC4(STB) 1PC3(INT) 38 37 36 35 34 1PB7 18 ・ ・ ・ 8255(2) 側 信号 ピン 2PA0 51 2PA1 52 ・ ・ ・ ・ ・ ・ 2PA7 58 2PB7 2PC2 2PB6 2PC3 ※ ピン番号はTNS-9601のものです。 Interface Corporation - 60 - 66 81 65 82 TUT-0034 <PCI-2747Aを2枚使用する場合> 8255(1) 信号 PA0 PA1 ・ ・ ・ PA7 側 ピン CHA2 CHA3 CHA9 PC7(OBF) PC6(ACK) PC5(IBF) PC4(STB) PC3(INT) CHC9 CHC8 CHC7 CHC6 CHC5 PB7 CNB9 ・ ・ ・ 8255(2) 信号 PA0 PA1 ・ ・ ・ PA7 側 ピン CHA2 CHA3 PB7 PC2 PB6 PC3 CHA9 CNB9 CHC4 CNB8 CHC5 ※ ピン番号はTRM-2601のものです。2台のTRM-2601を接続するように配線してください。 ※ I/Oモジュール番号「0」のPCI-2747Aを8255(1)の端子台に、I/Oモジュール番号「1」のPCI-2747A を8255(2)の端子台に接続してください。 <CPZ-2746を使用する場合> 8255(1) 側 信号 ピン 1PA0 46 1PA1 45 ・ ・ ・ ・ ・ ・ 1PA7 39 1PC7(OBF) 1PC6(ACK) 1PC5(IBF) 1PC4(STB) 1PC3(INT) 11 12 13 14 15 1PB7 31 ・ ・ ・ 8255(2) 側 信号 ピン 2PA0 94 2PA1 93 ・ ・ ・ ・ ・ ・ 2PA7 87 2PB7 2PC2 2PB6 2PC3 79 64 80 63 ※ ピン番号はTBZ-960xのものです。 これより、プログラムの作成を行います。まず、入力側のプログラムから作成します。 - 61 - Interface Corporation TUT-0034 Step1.プロジェクトの作成(モード2入力側) 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode2_Recv)を作成します。 『モー ( ド0入力/出力』でのStep1のメインウィンドウの作成を参照してください。) 2. プロジェクトにFbiPpi.Libファイル,FbiPpi.Hファイルのパス設定を行い、ライブラリファイ ル”FpiPpi.lib”をリンクさせます。(『23ページ 4.1 モード0入力/出力』でのStep2のDLL関数 宣言を参照してください。) 3. 初期化処理と終了処理を行う関数を追加します。 『23ページ ( 4.1 モード0入力/出力』 でのStep3 の初期化処理と終了処理を参照してください。) ・“FbiPpi.H”ファイルのインクルード,デバイスハンドルの変数宣言を行います。『モード0入力/ 出力』における(List 1-3)と同様にコードの追加を行います。(ただし、PCI-2746C,PCI-2747Aにお ける使用製品に対応したデバイスハンドル変数の区別を行う必要はありません。) ・「MFC ClassWizard」で以下のように設定し、メッセージ「WM_CREATE」,「WM_DESTROY」に対 する関数に初期化,終了コードをそれぞれ実装します。(『23ページ 4.1 モード0入力/出力』の List1-4,List1-5を参照してください。ただし、使用製品に対応したコード変更,追加を行う必要は ありません。) プロジェクト クラス名 オブジェクト PpiMode2_Recv CPpiMode2_RecvDlg CPpiMode2_RecvDlg Step2.モード2入力 これよりモード2入力部分のプログラムを作成するわけですが、実際は『38ページ 4.2 モード 1入力』のプログラムコードを流用して行きます。 1. データ入力を行うダイアログボックスの設定を行います。『38ページ 4.2 モード1入力』の Step2の1を参照してください。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE2_RECV_DIALOG」をダブ ルクリックします。表示されたダイアログボックスから、必要のないボタン,スタティックテキ ストを削除します。 ・コントロールから「ボタン」と「エディットボックス」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDRECV PPIモード2入力 ・同様にして、エディットボックスにカーソルを合わせ、右クリック→「プロパティ」を選択し て以下のように設定します。 ID IDC_TXTMON ・「スタイル」タブを選択し、テキストの配置を「右端」に変更し、「複数行」にチェックを入 れます。 Interface Corporation - 62 - TUT-0034 2. 受信データを表示するためのメンバ変数"m_TxtBox"を作成します。『38ページ 4.2 モード1 入力』のStep2の2を参照してください。 ・先程作成した「エディットボックス」にカーソルを合わせ、右クリック→「Class Wizard」を選 択します。「メンバ変数」タブを選択し、以下のように設定した後、「変数の追加」をクリッ クします。 プロジェクト クラス名 コントロールID PpiMode2_Recv CPpiMode2_RecvDlg IDC_TXTBOX ・メンバ変数を決定するダイアログが表示されますので、以下のように設定し、「OK」をクリッ クします。これでメンバ変数"m_TxtBox"が追加されました。 3. Timer関数を作成します。『38ページ 4.2 モード1入力』のStep2の3を参照してください。 再びClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数 の追加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode2_Recv CPpiMode2_RecvDlg CPpiMode2_RecvDlg WM_TIMER ・CPpiMode2_RecvDlgにタイマ識別変数の追加を行います。"CPpiMode2_RecvDlg.Cpp"ファイルを 開き、(List 4-1)の網掛けの部分の記述を追加します。 (List 4-1:PpiMode2_RecvDlg.cpp の変更コード) // PpiMode2_RecvDlg.cpp : インプリメンテーション ファイル // #include "stdafx.h" #include "PpiMode2_Recv.h" #include "PpiMode2_RecvDlg.h" #include "fbippi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif HANDLE ghDeviceHandle; UINT m_timerID = 0; //デバイスハンドル //タイマ ID - 63 - Interface Corporation TUT-0034 4. データ入力処理を開始するためのメンバ関数"OnCmdRecv"の作成を行います。『38ページ 4.2 モード1入力』のStep2の4を参照してください。 ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の追 加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode2_Recv CPpiMode2_RecvDlg IDC_CMDRECV BM_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、"OnCmdRecv"となっていることを確 認し、「OK」をクリックします。 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 4-2)のように記述します。 (List 4-2:CPpiMode2_RecvDlg クラスの OnCmdrecv 関数のコード void CPpiMode2_RecvDlg::OnCmdrecv() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // 8255①の設定を行います // グループ A = Mode2 入力 この部分が変更箇所です。 // グループ B = Mode0 入力 // [制御データ = 11000011] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,0xC3); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // INT 信号を有効にするため、8255①グループ A の RIE に 1 をセットします // [制御データ = 00001001] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,0x09); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のビットセットに失敗しました","制御データ設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // もし Timer が作成されていなければ Timer を作成して受信を開始する if(m_timerID==0){ m_timerID=SetTimer(1, 10, NULL); if(m_timerID==0){ MessageBox("タイマの作成に失敗しました","Timer 設定エラー", MB_ICONERROR); } } } Interface Corporation - 64 - TUT-0034 5. ポーリング処理をTimer関数に追加します。『38ページ 4.2 モード1入力』のStep2の5を参 照してください。 ・ワークスペースの「ClassView」を表示し、CPpiMode1_RecvDlgクラスを展開します。「OnTimer()」 をダブルクリックしてソースコードを開き、"OnTimer"関数に(List 4-3)のコードを記述します。 (List 4-3:CPpiMode2_RecvDlg クラスの OnTimer 関数のコード void CPpiMode1InDlg::OnTimer(UINT nIDEvent) { // TODO: この位置にメッセージ ハンドラ用のコードを追加するか // またはデフォルトの処理を呼び出してください INT nRet; // 関数の実行結果 BYTE bRecv; // 受信データ BOOL fReadOk; // 制御信号監視用フラグ // タイマ処理 if(nIDEvent==m_timerID){ // 1BP7 の状態を監視し High になるまで待機します fReadOk = false; while(fReadOk == false){ nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_B,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート A の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x80){ fReadOk = true; } } // 8255①ポート A よりデータ(1 文字)を入力します nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_A,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート A の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 入力されたデータをエディットボックスに表示します m_TxtBox.Format("%d", bRecv); UpdateData(FALSE); // 受信が終了していればタイマを破棄して受信を終了する if(bRecv == 255){ KillTimer(m_timerID); // タイマの破棄 m_timerID=0; // m_timerID を初期化する } } } - 65 - Interface Corporation TUT-0034 ・次に、Timer関数の終了処理を記述します。「Class View」で「OnDestroy」関数をダブルクリックし て表示し、(List4-4)の網掛け部分を追加します。 (List 4-4 OnTimer 関数の終了処理のコード) void CPpiMode2_RecvDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // タイマが作成されていれば、破棄を行う if(m_timerID!=0) KillTimer(m_timerID); // ボードクローズ nRet = PpiClose(ghDeviceHandle); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("FBIPPI1 のクローズに失敗しました","製品クローズエラー", MB_ICONERROR); } } 以上で、モード2データ入力のプログラムは完成です。 Step3.プロジェクトの作成(モード0出力側) モード2での入力確認用にモード0でのデータ出力プログラムの作成を行います。 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名)を作成します。(プロジェクト 名:PpiMode0_Send )を作成します。(『23ページ 4.1 モード0入力/出力』でのStep1のメインウ ィンドウの作成を参照してください) 2. プロジェクトにFbiPpi.Libファイル,FbiPpi.Hファイルのパス設定を行い、ライブラリファイ ル”FpiPpi.lib”をリンクさせます。(『23ページ 4.1 モード0入力/出力』でのStep2のDLL関数 宣言を参照してください) 3. 初期化処理と終了処理を行う関数を追加します。(『23ページ 4.1 モード0入力/出力』での Step3の初期化処理と終了処理を参照してください) ・“FbiPpi.H”ファイルのインクルード,デバイスハンドルの変数宣言を行います。『23ページ 4.1 モード0入力/出力』と同様にコードの追加を行います。(ただし、PCI-2746C,PCI-2747Aにおける 使用製品に対応したデバイスハンドル変数の区別を行う必要はありません。) ・「MFC ClassWizard」で以下のようにプロジェクト,クラス名,オブジェクトを設定し、メッセージ 「WM_CREATE」,「WM_DESTROY」に対する関数に初期化,終了コードをそれぞれ実装します。 (ただしPCI-2747Aは2枚使用するためOpen処理の場合、モード2出力で使用する製品とモード0 入力で使用する製品をデバイス名で区別する必要があります。) プロジェクト PpiMode0_Send クラス名 CPpiMode0_SendDlg オブジェクト CPpiMode0_SendDlg Interface Corporation - 66 - TUT-0034 Step4.モード0出力 これよりモード0出力部分のプログラムを作成するわけですが、実際は『38ページ 4.2 モード 1入力』で作成した「モード0出力」のプログラムを流用して行きます。 1. データ出力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE0_SEND_DIALOG」をダブ ルクリックします。表示されたダイアログボックスから、必要のないボタン,スタティックテキ ストを削除します。「コントロールから「ボタン」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDSEND PPIモード0出力 2. データ出力処理を開始するためのメンバ関数"OnCmdSend"の作成を行います。 ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の追 加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode0_Send CPpiMode0_SendDlg IDC_CMDSEND BM_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、"OnCmdSend"となっていることを確 認し、「OK」をクリックします。 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 4-5)のコードを記述します。網掛けの部分が変更箇所です。 (List 4-5:CPpiMode0_SendDlg クラスの OnCmdsend 関数のコード void CPpiMode0_SendDlg::OnCmdsend() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 INT nLoop; // for ループ用 BYTE bRecv; // 受信データ BYTE bSend; // 送信データ BOOL fNextSend; // 制御信号監視用フラグ // // // // PCI-2746C の場合は" FBIPPI_8255_CONTROLLER2 " PCI-2747A の場合は" FBIPPI_8255_CONTROLLER1 " で設定してください。 以下からのコードは PCI-2746C で設定しています // 8255②の設定を行います // Mode = 0 // PortA = OUT // PortB = IN // PortC = OUT // [制御データ = 10000010] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,0x82); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②より 0∼255 の数値データを出力します for(nLoop=0;nLoop<=255;nLoop++){ bSend = nLoop; - 67 - Interface Corporation TUT-0034 // 8255②のポート A からデータを出力します nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_A,bSend); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート A の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②の STB に Low パルスを送信します // 8255②の 2PC3 を Low にセットし入力側のデータをラッチします nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_C,0xf7); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②の 2PC3 を High にセットし入力側のデータラッチを終了します nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_C,0xff); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②の 2PB6 の状態を監視し、Low になるまで待機します fNextSend = false; while(fNextSend == false){ nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_B,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート B の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x40)==0x00){ fNextSend = true; } } } MessageBox("送信完了","データ送信確認", MB_ICONINFORMATION); } プログラムの入力が終わったら、保存し、入力側/出力側のプログラムをそれぞれ実行してくださ い。『38ページ 4.2 モード1入力』と同一の結果が得られることが確認できます。 Interface Corporation - 68 - TUT-0034 4.5 モード2出力 ここでは、モード2に設定した8255(1)からデータを出力し、8255(2)よりデータを入力する『60ペー ジ 4.4 モード2入力』とは逆の動作をする、制御信号を用いた簡単な通信プログラムの作成を 行います。 配線は、端子台上で対応するピンをビニール被覆線で接続します。 では、出力側のプログラムから作成します。 Step1.プロジェクトの作成(モード2出力側) 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode2_Send)を作成します。 (『23ページ 4.1 モード0入力/出力』でのStep1のメインウィンドウの作成を参照してくださ い。) 2. プロジェクトにFbiPpi.Libファイル,FbiPpi.Hファイルのパス設定を行い、ライブラリファイ ル”FpiPpi.lib”をリンクさせます。(『23ページ 4.1 モード0入力/出力』でのStep2のDLL関数宣 言を参照してください。) 3. 初期化処理と終了処理を行う関数を追加します。(『23ページ 4.1 モード0入力/出力』での Step3の 初期化処理と終了処理を参照してください。) ・“FbiPpi.H”ファイルのインクルード,デバイスハンドルの変数宣言を行います。『23ページ 4.1 モード0入力/出力』におけるプログラム作成と同様にコードの追加を行います。(ただし、 PCI-2746C,PCI-2747Aにおける使用製品に対応したデバイスハンドル変数の区別を行う必要は ありません。) ・「MFC ClassWizard」で以下のようにプロジェクト,クラス名,オブジェクトを設定し、メッセージ 「WM_CREATE」,「WM_DESTROY」に対する関数に初期化,終了コードをそれぞれ実装します。 プロジェクト PpiMode2_Send クラス名 CPpiMode2_SendDlg オブジェクト CPpiMode2_SendDlg - 69 - Interface Corporation TUT-0034 Step2.モード2出力 これよりモード0出力部分のプログラムを作成するわけですが、実際は『69ページ 4.5 モード2 出力』に作成した『69ページ 4.5 モード2出力』のプログラムを流用して行きます。 1. データ出力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE2_SEND_DIALOG」をダブ ルクリックします。表示されたダイアログボックスから、必要のないボタン,スタティックテキ ストを削除します。「コントロールから「ボタン」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDSEND PPIモード2出力 2. データ出力処理を開始するためのメンバ関数"OnCmdSend"の作成を行います。 ・ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の 追加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode2_Send CPpiMode2_SendDlg IDC_CMDSEND BM_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、"OnCmdSend"となっていることを確 認し、「OK」をクリックします。 Interface Corporation - 70 - TUT-0034 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 5-1)のコードを記述します。網掛けの部分が変更箇所です。 (List 5-1:CPpiMode2_SendDlg クラスの OnCmdsend 関数のコード void CPpiMode2_SendDlg::OnCmdsend() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 INT nLoop; // for ループ用 BYTE bRecv; // 受信データ BYTE bSend; // 送信データ BOOL fNextSend; // 制御信号監視用フラグ // 8255①の設定を行います // グループ A=Mode2 // グループ B=Mode0 入力 // [制御データ = 11xxx011] nRet = PpiControl(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, 0xC3); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // INT 信号を有効にするために 8255①グループ A の WIE に 1 をセットします // [制御データ = 00001101] nRet = PpiControl(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, 0x0d); // 8255①より 0∼255 の数値データを出力します for(nLoop=0;nLoop<=255;nLoop++){ bSend = nLoop; // 8255①のポート A からデータを出力します nRet = PpiOutputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,FBIPPI_PORT_A,bSend); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート A の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255①の 1PB7 の状態を監視し High になるまで待機します fNextSend = false; while(fNextSend == false){ nRet = PpiInputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, FBIPPI_PORT_B, &bRecv); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート B の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x80){ fNextSend = true; } } if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート A の出力に失敗しました","データ送信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } } MessageBox("送信完了","データ送信確認", MB_ICONINFORMATION); } - 71 - Interface Corporation TUT-0034 Step3.プロジェクトの作成(モード0入力側) モード2での出力確認用にモード0でのデータ入力プログラムの作成を行います。 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode0_Recv)を作成します。 (『モード0入力/出力』でのStep1のメインウィンドウの作成を参照してください) 2. プロジェクトにFbiPpi.Libファイル,FbiPpi.Hファイルのパス設定を行い、ライブラリファイ ル”FpiPpi.lib”をリンクさせます。(『23ページ 4.1 モード0入力/出力』でのStep2のDLL関数宣 言を参照してください) 3. 初期化処理と終了処理を行う関数を追加します。(『23ページ 4.1 モード0入力/出力』での Step3の 初期化処理と終了処理を参照しながら追加してください) ・“FbiPpi.H”ファイルのインクルード,デバイスハンドルの変数宣言を行います。『23ページ 4.1 モード0入力/出力』におけるプログラム作成と同様にコードの追加を行います。 (ただし、PCI-2746C,PCI-2747Aにおける使用製品に対応したデバイスハンドル変数の区別を行 う必要はありません。) ・「MFC ClassWizard」で以下のように設定し、メッセージ「WM_CREATE」,「WM_DESTROY」に対 する関数に初期化,終了コードをそれぞれ実装します。(ただし、PCI-2747Aは2枚使用するため Open処理の場合、モード2出力で使用する製品とモード0入力で使用する製品をデバイス名で区 別する必要があります。) プロジェクト クラス名 オブジェクト PpiMode0_Recv CPpiMode0_RecvDlg CPpiMode0_RecvDlg Step4.モード0入力 これよりモード0入力部分のプログラムを作成するわけですが、実際は『50ページ 4.3 モード 1出力』のモード0入力のプログラムを流用して行きます。 1. データ入力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIMODE0_RECV_DIALOG」をダブ ルクリックします。表示されたダイアログボックスから、必要のないボタン,スタティックテキ ストを削除します。 ・コントロールから「ボタン」と「エディットボックス」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID キャプション IDC_CMDRECV PPIモード0入力 ・同様にして、エディットボックスにカーソルを合わせ、右クリック→「プロパティ」を選択し て以下のように設定します。 ID IDC_TXTBOX ・「スタイル」タブを選択し、テキストの配置を「右端」に変更し、「複数行」にチェックを入 れます。 Interface Corporation - 72 - TUT-0034 2. 受信データを表示するためのメンバ変数"m_TxtBox"を作成します。 先程作成した「エディットボックス」にカーソルを合わせ、右クリック→「Class Wizard」を選 択します。「メンバ変数」タブを選択し、以下のように設定した後、「変数の追加」をクリッ クします。 プロジェクト クラス名 コントロールID PpiMode0_Recv CPpiMode0_RecvDlg IDC_TXTBOX ・メンバ変数を決定するダイアログが表示されますので、以下のように設定し、「OK」をクリッ クします。これでメンバ変数"m_TxtBox"が追加されました。 3. データ受信のポーリングを行うためにTimer関数を作成します。 ・再びClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数 の追加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode0_Recv CPpiMode0_RecvDlg CPpiMode0_RecvDlg WM_TIMER ・CPpiMode1_RecvDlgにタイマ識別変数の追加を行います。"CPpiMode0_RecvDlg.Cpp"ファイルを 開き、(List5-2)の網掛けの部分の記述を追加します。 (List 5-2:PpiMode0_RecvDlg.cpp の変更コード) // PpiMode0_RecvDlg.cpp : インプリメンテーション ファイル // #include #include #include #include "stdafx.h" "PpiMode0_Recv.h" "PpiMode0_RecvDlg.h" "FbiPpi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif HANDLE ghDeviceHandle; UINT m_timerID; 4. データ入力処理を開始するためのメンバ関数"OnCmdRecv"の作成を行います。 ・ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の追 加」をクリックします。 プロジェクト クラス名 オブジェクト メッセージ PpiMode0_Recv CPpiMode0_RecvDlg IDC_CMDRECV BM_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、"OnCmdRecv"となっていることを確 認し、「OK」をクリックします。 - 73 - Interface Corporation TUT-0034 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 5-3)のコードを記述します。 (List 5-3:PpiMode0_RecvDlg クラス OnCmdrecv 関数のコード) void CPpiMode0_RecvDlg::OnCmdrecv() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // // // // PCI-2746C の場合は" FBIPPI_8255_CONTROLLER2 " PCI-2747A の場合は" FBIPPI_8255_CONTROLLER1 " で設定してください。 以下からのコードは PCI-2746C で設定しています // 8255②の設定を行います // Mode = 0 // PortA = IN // PortB = IN // PortC = OUT // [制御データ = 10010010] nRet = PpiControl(ghDeviceHandle,FBIPPI_8255_CONTROLLER2,0x92); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255②のモード設定に失敗しました","制御データ設定エラー", MB_ICONERROR); } // 8255②のポート C からデータを出力します nRet = PpiOutputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, FBIPPI_PORT_C, 0xff); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポートの出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // もし Timer が作成されていなければ Timer を作成して受信を開始する if(m_timerID==0){ m_timerID=SetTimer(1, 10, NULL); if(m_timerID==0){ MessageBox("タイマの作成に失敗しました","Timer 設定エラー", MB_ICONERROR); } } } Interface Corporation - 74 - TUT-0034 5. ポーリング処理をTimer関数に追加します。 ・ワークスペースの「ClassView」を表示し、CPpiMode0_RecvDlgクラスを展開します。「OnTimer()」 をダブルクリックしてソースコードを開き、"OnTimer"関数に(List 5-4)のコードを記述します。 (List 5-4:PpiMode0_RecvDlg クラスの OnTimer 関数のコード) void CPpiMode0_RecvDlg::OnTimer(UINT nIDEvent) { // TODO: この位置にメッセージ ハンドラ用のコードを追加するか // またはデフォルトの処理を呼び出してください INT nRet; // 関数の実行結果 BYTE bRecv; // 受信データ BOOL fReadOk; // 制御信号監視用フラグ // タイマ処理 if(nIDEvent == m_timerID){ // 2PB7 の状態を監視し High になるまで待機します(OBF のポーリング) fReadOk = false; while(fReadOk == false){ nRet = PpiInputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, FBIPPI_PORT_B, &bRecv); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート A の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x00){ fReadOk = true; } } // 8255②に DAK の Low パルスを送信します nRet = PpiOutputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, FBIPPI_PORT_C, 0xfb); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 8255②ポート A よりデータ(1 文字)を入力します nRet = PpiInputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, FBIPPI_PORT_A, &bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート A の入力に失敗しました", "データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // 入力されたデータをエディットボックスに表示します m_TxtBox.Format("%d", bRecv); UpdateData(FALSE); // 8255②に DAK の High パルスを送信します nRet = PpiOutputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER2, FBIPPI_PORT_C, 0xff); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255②ポート C の出力に失敗しました","データ送信設定エラー", MB_ICONERROR); } // 受信が終了していればタイマを破棄して受信を終了する if(bRecv == 255){ KillTimer(m_timerID); // タイマの破棄 timerID=0; // m_timerID を初期化する } } CDialog::OnTimer(nIDEvent); } - 75 - Interface Corporation TUT-0034 ・次に、Timer関数の終了処理を記述します。「ClassView」で「OnDestroy」関数をダブルクリックし て表示し、(List5-5)の網掛け部分を追加します。 (List 5-5 OnTimer 関数の終了処理のコード) void CPpiMode0_RecvDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください INT nRet; // 関数の実行結果 // タイマが作成されていれば、破棄を行う if(m_timerID!=0) KillTimer(m_timerID); // 製品クローズ nRet = PpiClose(ghDeviceHandle); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("FBIPPI1 のクローズに失敗しました","製品クローズエラー", MB_ICONERROR); } } 以上でモード2データ入力のプログラムは完成です。 ※ モード2ではDAK信号がLレベルの時のみデータの出力がされます。 プログラムの入力が終わったら、保存した後、入力側/出力側のプログラムをそれぞれ実行してく ださい。『50ページ 4.3 モード1出力』と同一の結果が得られることが確認できます。 Interface Corporation - 76 - TUT-0034 4.6 割り込み処理 ここでは、割り込み処理の方法に関し、記載します。 PPIの割り込みは、 ・8255①のポートC接点3(ピン名:1PC3) ・8255①のポートC接点0(ピン名:1PC0) ・8255②のポートC接点3(ピン名:1PC3) ・8255②のポートC接点0(ピン名:1PC0) の4つの割り込みを設定することができます。今回は、『50ページ 4.3 モード1出力』(List3-1) を例にしてみます。つまり、上記の1番目にある“8255①のポートC接点3(ピン名:1PC3)”の割り込 みを使用します。 List 3-1の中に以下のコードがあります。 // 8255①の 1PB7 の状態を監視し、High になるまで待機します fNextSend = false; while(fNextSend == false){ nRet = PpiInputPort(ghDeviceHandle,FBIPPI_8255_CONTROLLER1,FBIPPI_PORT_B,&bRecv); if(nRet!=FBIPPI_ERROR_SUCCESS){ MessageBox("8255①ポート B の入力に失敗しました","データ受信エラー", MB_ICONERROR); nRet = PpiClose(ghDeviceHandle); exit(0); } // ビット判定 if((bRecv & 0x80)==0x80){ fNextSend = true; } } この処理は、8255①のINT信号の出力をポートBより入力し、INT信号が上がる(Hレベル)のをwhile 文によるループ処理で待っています。いわゆるINT信号のポーリングを行っているわけです。 ところで、このINT信号はPCIの割り込み信号線に対しても出力されています。つまり、内部的に コンピュータ上で検出できるわけです。『50ページ 4.3 モード1出力』では割り込み信号入力 用に1PB7を利用し、接続された1PC3のINT信号の変化を検知していたわけですが、Win32APIを利 用した割り込み処理を使うことでこの結線は不要となります。 - 77 - Interface Corporation TUT-0034 「モード 1 出力」(『モード 1 出力』参照) ① データを出力する ② INT 信号を確認し H レベルになるまで待機する ③次のデータがある場合は①から繰り返す 「割り込みを使用しない」(List 3-1) 8255①の INT 信号が H レベルになるのを、while 文によ るループ処理を行って待つ。 「割り込みを使用する」(List 6-1) 8255①の INT 信号が H レベルになるのを、Win32API の 割り込み処理を使って待つ。 WR H L H L H L OBF INT WEI をセットしなければ、INT は H レベルのままです。 ACK 外部への 出力データ H L 出力される新しいデータ 時間の経過 INTR 信号が H になる割り込み 処理で待ちます Interface Corporation - 78 - TUT-0034 接続を下図のように変更します。 <PCI-2746C,CTP-2746を使用の場合> 8255(1) 側 信号 ピン 1PA0 3 1PA1 4 ・ ・ ・ ・ ・ ・ 1PA7 10 1PC7(OBF) 1PC6(ACK) ・ ・ ・ 38 37 8255(2) 側 信号 ピン 2PA0 51 2PA1 52 ・ ・ ・ ・ ・ ・ 2PA7 58 2PB7 2PC2 66 81 ※ ピン番号はTNS-9601のものです。 <PCI-2747Aを2枚使用の場合> 8255(1) 側 信号 ピン PA0 CNA2 PA1 CNA3 ・ ・ ・ PA7 CNA9 PC7(OBF) PC6(ACK) ・ ・ ・ CNC9 CNC8 8255(2) 信号 PA0 PA1 ・ ・ ・ PA7 側 ピン CNA2 CNA3 PB7 PC2 CNA9 CNB9 CNC4 ※ ピン番号はTRM-2601のものです。2台のTRM-2601を接続するように配線してください。 ※ 製品番号「0」のPCI-2747Aを8255(1)の端子台に、製品番号「1」のPCI-2747Aを8255(2)の端子 台に接続してください。 <CPZ-2746を使用の場合> 8255(1) 側 信号 ピン 1PA0 46 1PA1 45 ・ ・ ・ ・ ・ ・ 1PA7 39 1PC7(OBF) 1PC6(ACK) ・ ・ ・ 11 12 8255(2) 側 信号 ピン 2PA0 94 2PA1 93 ・ ・ ・ ・ ・ ・ 2PA7 87 2PB7 2PC2 79 64 ※ ピン番号はTBZ-960xのものです。 - 79 - Interface Corporation TUT-0034 次に『50ページ 4.3 モード1出力』のモード1での出力プログラムを割り込み信号を利用した ものに書き換えてみます。 割り込み処理における非同期I/O処理を実現するために、ここではWin32 APIに定義される以下の 関数、および構造体を使用しています。 ・CreateEvent関数 イベントオブジェクトの作成を行います。 ・Overlapped構造体 非同期I/O制御に必要な構造体です。 ・WaitForSingleObject関数 オブジェクトがシグナル状態になるまで待機します ・CloseHandle関数 オブジェクトハンドルのクローズを行います。 各関数および構造体の詳細はMicrosoft社提供のWin32 APIリファレンスか、もしくはその他専門書 籍を参照してください。 Interface Corporation - 80 - TUT-0034 Step1.プロジェクト作成 1. Visual C++を起動し、新しいプロジェクト(プロジェクト名:PpiMode1_Send)を作成します。 2. プロジェクトにFBIPPI.LIBファイル,FBIPPI.Hファイルのパス設定を行い、ライブラリファイル “Fbippi.lib”をリンクさせます。 3. 作成したプログラムに、PPI製品の初期化と終了処理を行う関数を追加します。 (ここまでの手順は『23ページ 4.1 モード0入力/出力』のStep1∼Step3と同様となりますので、 そちらを参照してください。ただし、このプログラムでは出力側の処理のみを行いますので、 PCI-2747Aを使用する場合でも初期化と終了処理は一度だけ行います。) Step2.モード1出力(割り込み処理) 基本的には、モード1出力とプログラム作成手順は同じです。 1. 初期化処理処理で記述したPpiIntr_SendDlg.cppファイルの“HANDLE ghDeviceHandle”の後に、 “OVERLAPPED glpOverlapped “というコードを付け加えます。 2. 終了処理にイベントオブジェクト終了のコードを追加します。(下記の網掛け部分) (List 6-1 CPpiIntr_SendDlg クラスの OnDestroy 関数のコード) void CPpiIntr_SendDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください INT nRet; //関数の実行結果 //PCI-2746C(PCI-2747A 使用時は 1 枚目)の製品をクローズします nRet = PpiClose(ghDeviceHandle); if(nRet != FBIPPI_ERROR_SUCCESS) { MessageBox("製品 1 のクローズに失敗しました"); exit(0); } // 作成したイベントを終了します CloseHandle(glpOverlapped.hEvent); } 3. データ出力を行うダイアログボックスの設定を行います。 ・ResourceViewを表示し、Dialogフォルダを展開して「IDD_PPIINTR_SEND_DIALOG」をダブル クリックします。 ・表示されたダイアログボックスから、必要のないボタン,スタティックテキストを削除します。 「OK」ボタン,「キャンセル」ボタン,「TODO:ダイアログのコントロールをここに配置」とい うスタティックテキストをそれぞれ選択し、Deleteキーを押してください。 ・コントロールから「ボタン」を選択し、ダイアログに貼り付けます。 ・配置したボタンにカーソルを合わせ、右クリック→「プロパティ」を選択して以下のように設 定します。 ID IDC_CMD_SEND キャプション PPIモード1 出力 - 81 - Interface Corporation TUT-0034 4. データ出力処理を開始するためのメンバ関数“OnCmdSend”の作成を行います。 ClassWizardを表示し、「メッセージマップ」タブを選択し、以下のように設定して「関数の追 加」をクリックします。 プロジェクト PpiIntr_Send クラス名 CPpiIntr_SendDlg オブジェクト IDC_CMD_SEND メッセージ BN_CLICKED ・メンバ変数名を決定するダイアログが表示されますので、“OnCmdSend”となっていることを確 認し、「OK」をクリックします。 ・次に、そのままClassWizardで「コード編集」ボタンをクリックして関数のソースコードを表示 し、(List 6-2)のコードを記述します。 プログラムの流れは、『50ページ 4.3 モード1出力』の(List 3-1)と同じです。変更点は、割り込み 処理に関する部分(下記List)の網掛け部分になります。 (List 6-2 CPpiIntr_SendDlg クラスの OnCmdSend 関数のコード) void CppiIntr_SendDlg::OnCmdSend() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の戻り値 DWORD dwEventBuf; // イベント内容を格納する変数 BYTE bySend; // 送信データ // 8255①のモード設定を行う // グループ A :モード 1、ポート A とポート C の上位 = 出力 // グループ B :モード 0、ポート B とポート C の下位 = 入力 nRet = PpiControl(ghDeviceHandle, FBIPPI_8255_CONTROLLER1, 0xa3); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のモード設定に失敗しました", "実行エラー", MB_ICONERROR); PpiClose(ghDeviceHandle1); exit(0); } // INT 信号を有効にするために、8255①のグループ A の WIE に"1"をセットします // ポート C をコントロール信号の出力、ステータス信号の入力として使用する(bit7 = 0) // 制御データ = 0x00001101 nRet = PpiControl(ghDeviceHandle, FBIPPI_8255_CONTROLLER1, 0x0d); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①の W ビットセットに失敗しました", "実行エラー", MB_ICONERROR); PpiClose(ghDeviceHandle); exit(0); } // 8255①の割り込み要因の割り当て、割り込み発生論理を設定する // 設定値(0x11) = 1PC3 入力信号が L → H を設定 nRet = PpiSetEventConfig(ghDeviceHandle, 0xf0); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①の割り込み設定に失敗しました", "実行エラー", MB_ICONERROR); PpiClose(ghDeviceHandle1); exit(0); } // 8255①の割り込みマスク状態を設定する // 1PC3 の入力による割り込みだじぇ検知する nRet = PpiSetEventMask(ghDeviceHandle, 0x01); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①の割り込みマスク設定に失敗しました", "実行エラー", MB_ICONERROR); PpiClose(ghDeviceHandle1); exit(0); } Interface Corporation - 82 - TUT-0034 // 8255①より 0∼255 の数値データを出力する for(int count = 0; count <= 255; count++){ bySend = count; // 8255①のポート A からデータを出力 nRet = PpiOutputPort(ghDeviceHandle, FBIPPI_8255_CONTROLLER1, FBIPPI_PORT_A, bySend); if(nRet != FBIPPI_ERROR_SUCCESS){ MessageBox("8255①のポート A からのデータ出力に失敗しました", "実行エラー", MB_ICONERROR); break; } // イベントオブジェクトの作成 glpOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // 製品のイベント要求を待つ nRet = PpiEventRequestPending(ghDeviceHandle, 0x01, &dwEventBuf, &glpOverlapped); if(nRet != FBIPPI_ERROR_IO_PENDING){ MessageBox("割り込みイベント待ち開始に失敗しました", "実行エラー", MB_ICONERROR); break; } // 割り込みがあるまで待機 nRet = WaitForSingleObject(glpOverlapped.hEvent, 10000); // 10 秒でタイムアウト if(nRet != WAIT_OBJECT_0){ MessageBox("タイムアウト(送信停止)", "実行エラー", MB_ICONERROR); break; // データ出力停止(キャンセル) } } if(count == 256) MessageBox("送信完了", "完了", MB_ICONERROR); } 以上でモード1データ出力のプログラムは完成です。 入力側のプログラムは『55ページ Step4.モード0入力』(List 3-2)と同じものを使用します。 プログラムの入力が終わったら、保存した後、入力側(プロジェクト名:PpiMode0_Recv),出力側(プ ロジェクト名:PpiIntr_Send)のプログラムをそれぞれ実行してください。中で行われている処理が、 while文での待機か割り込み処理での待機かの違いであって、『53ページ Step2.モード1出力』 と同一の結果が得られることが確認できます。 では、ここより、使用したFbiPpi.DLLの関数について記載します。 (List 6-2)ではINT(1PC3)がLレベルからHレベルに変化した時のみ割り込みイベントが発生し、Hレ ベルからLレベルに変化しても割り込みイベントは発生しません。これは、どういった信号を割り 込みとして扱うか、製品に設定しているからです。割り込み要因の設定にはPpiSetEventConfig関 数を使用します。 「使用例」 割り込み要因の論理を設定します。 関数が失敗するとエラーコード が格納されます。 nRet = PpiSetEventConfig(ghDeviceHandle, 0xf0); 製品のオープン時に取得したデバ イスハンドルを指定します。 - 83 - Interface Corporation TUT-0034 割り込み要因の論理の設定ですが、設定される数値データは2進数変換時、各ビットにおいて以下 の意味をもっています。 Bit7 Bit6 Bit5 Bit4 EDS4 EDS3 EDS3 EDS1 SIG1∼SIG4の各々がどういった条件の 時、割り込みとするかを設定します。 Bit3 SIG4 Bit2 SIG3 Bit1 SIG2 Bit0 SIG1 各ビットを割り込み接点にアタッチ します。 割り込み発生論理設定状態 EDS1 SIG1の割り込み発生論理の設定 EDS2 SIG2の割り込み発生論理の設定 EDS3 SIG3の割り込み発生論理の設定 EDS4 SIG4の割り込み発生論理の設定 値 意味 0 High → Lowの遷移で割り込み発生 1 Low → Highの遷移で割り込み発生 SIG1[割り込み要因割り当て] 値 意味 0 8255①のポートC接点3(ピン名:1PC3)入力信号 SIG2[割り込み要因割り当て] 値 意味 0 8255①のポートC接点0(ピン名:1PC0)入力信号 1 IR.IN1 ※ PCI-2747AはIR.IN1信号を持ちません。 SIG3[割り込み要因割り当て] 値 意味 0 8255②のポートC接点3(ピン名:2PC3)入力信号 ※ PCI-2747Aは8255②を持ちません。 SIG4[割り込み要因割り当て] 値 意味 0 8255②のポートC接点0(ピン名:2PC0)入力信号 1 IR.IN2 ※ PCI-2747Aは8255②、IR.IN2信号を持ちません。 ※ 電源投入時,PCIバスリセット時,外部リセット信号入力時は全て設定値が0となっています。 (List 6-2)においては、0xf0(16進数でf0)が設定されています。つまり、Bit7∼Bit0までが「11110000」 と設定され、その意味は「1PC3,1PC0,2PC3,2PC0のうちどれかが、LレベルÆHレベルに変化した 時それを割り込み入力とする」と定義しているわけです。 Interface Corporation - 84 - TUT-0034 しかし、今回割り込みとして使用したい信号は1PC3のINTのみですので、他の信号の変化は無視 するように設定をする必要があります。 この処理のことをマスク処理といいます。 割り込み入力のマスク処理にはPpiSetEventMask関数を 使用します。 「使用方法」 関数が失敗するとエラーコードが 格納されます。 割り込み要因のマスク/アンマスクを 設定します。 nRet = PpiSetEventMask(ghDeviceHandle, 0x01); 製品のオープン時に取得したデバイスハンドルを指定します。 割り込み要因のマスクの設定ですが、設定される数値データは2進数変換時、各ビットにおいて以 下の意味をもっています。0の時その接点はマスクされます。 Bit7 未使用 Bit6 未使用 Bit5 SIGR Bit4 SIGT Bit3 SIG4 Bit2 SIG3 Bit1 SIG2 Bit0 SIG1 PpioSetEventConfig関数で設定した 各接点に対応します。 SIGR=外部割り込み SIGT=タイマ割り込み 値 0 1 意味 マスクする マスクしない (List 6-2)では0x01(16進数で1)が設定されています。つまりBit7∼Bit0までが「00000001」と設定さ れ、1PC3以外の入力信号はマスク処理されているので、1PC3以外の状態の変化は割込み信号とし て処理されません。 最後に、実際の監視処理の開始ですが、PpiEventRequestPending関数が呼び出されて初めて処理 が開始(割り込み待機状態)されます。 関数が失敗するとエラーコー ドが格納されます。 「使用方法」 許可するイベントをビットア サインで設定します。 nRet = PpiEventRequestPending(hDeviceHandle, 0x01, &EventBuf, &lpOverlapped); 製品のオープン時に取得したデバイスハン ドルを指定します。 通知されたイベント内 容が格納されます。 OVERLAPPEDデータ構造体へのポインタを指定します。 - 85 - Interface Corporation TUT-0034 許可するイベントですが、設定される数値データは2進数変換時、各ビットにおいて以下の意味を もっています。‘1’の時そのイベントは有効となります。(List 6-2)ではBit5∼Bit0までが「000001」 と設定され、1PC3で入力信号を検知すると割り込みイベントとして認識するよう定義しています。 Bit0 8255①のポートC接点3(ピン名:1PC3)入力信号 Bit1 8255①のポートC接点0(ピン名:1PC0)入力信号 または、IR.IN1(外部割り込み入力信号)からの入力信号 ※ PCI-2747AはIR.IN1信号を持ちません。 Bit2 8255②のポートC接点3(ピン名:2PC3)入力信号 ※ PCI-2747Aは8255②を持ちません。 Bit3 8255②のポートC接点0(ピン名:2PC0)入力信号 または、IR.IN2(外部割り込み入力信号)からの入力信号 ※ PCI-2747Aは8255②、IR.IN2信号を持ちません。 Bit4 インターバルタイマ Bit5 外部リセット入力(RSTIN)割り込み ここまでが、Win32APIを用いた割り込み処理のプログラム例です。割り込みを多用するとプログ ラムが複雑になることがありますが、柔軟なシステム作成において、この割り込み処理は有効な 手段となります。 Interface Corporation - 86 - TUT-0034 第5章 FbiPpi.DLLリファレンス DLL関数一覧 No. 1. PpiOpen 関数名 内 容 PPI製品のオープンを行います。以後の製品へのアクセスを 行えるようにします。 PPI製品のクローズを行います。各種リソースの解放を行い、 以後の製品へのアクセスを禁止します。 8255制御レジスタの制御を行います。 2. PpiClose 3. PpiControl 4. PpiInputPort 5. 6. 7. PpiOutputPort PpiSetEventMask PpiGetEventMask 8. PpiSetEventConfig 9. PpiGetEventConfig 10. PpiSetTimerConfig 割り込みイベント要因割り当ておよび割り込みイベント発 生論理の設定を行います。 割り込みイベント要因割り当ておよび割り込みイベント発 生論理の設定状態を取得します。 インターバルタイマの設定を行います。 11. PpiGetTimerConfig インターバルタイマの設定情報を取得します。 12. PpiGetTimerCount インターバルタイマのカウント値を取得します。 13. 14. PpiGetResetInStatus PpiEventRequestPending 外部リセット入力信号端子(RSTIN)の状態を取得します。 イベント要求を待ちます。 15. PpiCommonGetPciDeviceInfo デバイスID,リソース情報,製品ID(RSW1)等の情報を取得し ます。 任意の8255コントローラのポートからデータを読み込みま す。 任意の8255コントローラのポートへデータを出力します。 割り込みイベントのマスク/アンマスクの設定を行います。 割り込みイベントのマスク状態を取得します。 - 87 - Interface Corporation TUT-0034 PpiOpen 指定されたデバイス名の製品のオープンを行い、以後の製品へのアクセスを行えるようにします。 宣言 HANDLE PpiOpen(LPCTSTR lpszName, DWORD fdwFlags); パラメータ lpszName fdwFlags オープンするデバイス名を指定します。 オープン時のフラグを指定します。 値 FBIDIO_FLAG_SHARE 意味 同じデバイスを重複(共有)してオープンすることを許可します。 戻り値 関数が成功すると有効なデバイスハンドルが返されます。 関数が失敗するとINVALID_HANDLE_VALUEが返されます。INVALID_HANDLE_VALUEの値は、FFFFFFFFh(-1)です。 解説 Windows95では、「コントロールパネル」の「デバイス」に「FbiPciPpi」が追加され認識された当社デジタル入出力製品が一覧 表示されます。一覧の製品型式の横に製品上のロータリスイッチの値とデバイス名が表示されます。自己診断プログラムでも確 認できます。 WindowsNTでは、自己診断プログラムにて割り当てられたデバイス名をご確認ください。 デバイス名は製品上のロータリスイッチ(RSW1)の値で決定されるわけではありません。 使用する製品枚数やスロット位置の変更等でシステム構成が変化すると割り当てられる名前が変化する場合があります。システ ム構成が変化する環境でご使用になる場合は、デバイス名の指定が変更できるようにアプリケーションを作成ください。製品上 に実装されたRSW1(製品ID設定)の値を取得し、アプリケーションで目的の製品であるかを判断することができます。詳しくは、 PpiCommonGetPciDeviceInfo関数 の説明をご参照してください。 PpiClose 製品のクローズを行い、製品アクセスのために使用されていた各種リソースの解放し、以後の製品へのアクセスを禁止します。 宣言 INT PpiClose(HANDLE hDeviceHandle); パラメータ hDeviceHandle 有効なデバイスハンドルを指定します 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 PpiControl 8255 PPIコントローラ制御レジスタを制御します。 宣言 INT PpiContrl(HANDLE hDeviceHandle, DWORD dwController, BYTE bControlData); パラメータ hDeviceHandle dwController bControlData 有効なデバイスハンドルを指定します 搭載された2つの8255のうちどちらを制御するかを指定します。 値 意味 8255コントローラ① FBIPPI_8255_CONTROLLER1 8255コントローラ② FBIPPI_8255_CONTROLLER2 ※ PCI-2747AではFBIPPI_8255_CONTROLLER2は指定できません。 制御データを指定します。8255のモード設定,入出力設定の設定データは『99ページ 8255 PPIコントローラ説明』を参照してください。 第6章 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 Interface Corporation - 88 - TUT-0034 PpiInputPort 8255コントローラのポートからデータを読み込みます。引数にて、コントローラとポートを指定します。 宣言 INT PpiInputPort(HANDLE hDeviceHandle, DWORD dwController, DWORD dwPort, PBYTE pbValue); パラメータ hDeviceHandle dwController dwPort pbValue 有効なデバイスハンドルを指定します 搭載された2つの8255のうちどちらを制御するかを指定します。 値 意味 8255コントローラ① FBIPPI_8255_CONTROLLER1 8255コントローラ② FBIPPI_8255_CONTROLLER2 ※ PCI-2747AではFBIPPI_8255_CONTROLLER2は指定できません。 入力を行うポートを指定します。 値 FBIPPI_PORT_A FBIPPI_PORT_B FBIPPI_PORT_C 意味 ポートA ポートB ポートC バッファへのポインタを指定します。このバッファに指定されたポートより取得した状態が 格納されます。 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 PpiOutputPort 8255コントローラのポートへデータを出力します。引数にて、コントローラとポートを指定します。 宣言 INT PpiOutputPort(HANDLE hDeviceHandle, DWORD dwController, DWORD dwPort, BYTE bValue); パラメータ hDeviceHandle dwController 有効なデバイスハンドルを指定します 搭載された2つの8255のうちどちらを制御するかを指定します。 値 意味 8255コントローラ① FBIPPI_8255_CONTROLLER1 8255コントローラ② FBIPPI_8255_CONTROLLER2 ※ PCI-2747AではFBIPPI_8255_CONTROLLER2は指定できません。 dwPort 入力を行うポートを指定します。 値 意味 FBIPPI_PORT_A ポートA FBIPPI_PORT_B ポートB FBIPPI_PORT_C ポートC pbValue バッファへのポインタを指定します。このバッファに格納した値が指定されたポートより出 力されます。 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 - 89 - Interface Corporation TUT-0034 PpiSetEventMask 割り込みマスク状態を設定します。 宣言 INT PpiSetEventMask(HANDLE hDeviceHandle, BYTE bEventMask); パラメータ hDeviceHandle bEventMask 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファに設定された値により, 割り込み要因のマスク/アンマスクの設定が行われます。設定は下記のビットの組み合わせで行 います。 Bit7 Bit1 Bit0 − − SIGR SIGT SIG4 SIG3 SIG2 SIGR=外部割り込み SIGT=タイマ割り込み SIG1∼4は、PpiSetEventConfig関数にて設定される割り込み要因 Bit6 Bit5 Bit4 Bit3 Bit2 SIG1 値 意味 0 マスク 1 アンマスク 電源投入時は全てマスク状態(0)です。 PCIバスリセット時、外部リセット入力時はSIGR以外がマスク状態(0)になります。SIGRのマ スク/アンマスク状態は変更しません。 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 PpiGetEventMask 割り込みマスク状態を取得します。 宣言 INT PpiGetEventMask(HANDLE hDeviceHandle, PBYTE pbEventMask); パラメータ hDeviceHandle pbEventMask 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファに製品に設定された割り込み要因のマスク/ アンマスクの状態が格納されます。 Bit7 Bit1 Bit0 − − SIGR SIGT SIG4 SIG3 SIG2 SIGR=外部割り込み SIGT=タイマ割り込み SIG1∼4は、PpiSetEventConfig関数にて設定される割り込み要因 Bit6 Bit5 Bit4 Bit3 Bit2 SIG1 値 意味 0 マスク 1 アンマスク 電源投入時は全てマスク状態(0)です。 PCIバスリセット時、外部リセット入力時はSIGR以外がマスク状態(0)になります。SIGRのマス ク/アンマスク状態は変更しません。 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 Interface Corporation - 90 - TUT-0034 PpiSetEventConfig 割り込み要因の割り当て,割り込み発生論理を設定します。 宣言 INT PpiSetEventConfig(HANDLE hDeviceHandle, BYTE bEventConfig); パラメータ hDeviceHandle bEventConfig 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファに割り込み要因の割り当て,割り込み発生論 理の設定データを設定します。 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 EDS4 EDS3 EDS3 EDS1 SIG4 SIG3 SIG2 SIG1 割り込み発生論理設定状態 EDS1 SIG1の割り込み発生論理の設定 EDS2 SIG2の割り込み発生論理の設定 EDS3 SIG3の割り込み発生論理の設定 EDS4 SIG4の割り込み発生論理の設定 値 意味 0 High → Low 1 Low → High SIG1[割り込み要因割り当て] 値 意味 0 8255①のポートC接点3(ピン名:1PC3)入力信号 SIG2[割り込み要因割り当て] 値 意味 0 8255①のポートC接点0(ピン名:1PC0)入力信号 1 IR.IN1 ※ PCI-2747AはIR.IN1信号を持ちません。 SIG3[割り込み要因割り当て] 値 意味 0 8255②のポートC接点3(ピン名:2PC3)入力信号 ※ PCI-2747Aは8255※を持ちません。 SIG4[割り込み要因割り当て] 値 意味 0 8255②のポートC接点0(ピン名:2PC0)入力信号 1 IR.IN2 ※ PCI-2747Aは8255※、IR.IN2信号を持ちません。 ※ 電源投入時,PCIバスリセット時、外部リセット信号入力時は全て設定値が0となっています。 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 - 91 - Interface Corporation TUT-0034 PpiGetEventConfig 割り込み要因の割り当て,割り込み発生論理の設定状態を取得します。 宣言 INT PpiGetEventConfig(HANDLE hDeviceHandle, PBYTE pbEventConfig); パラメータ hDeviceHandle bEventConfig 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。割り込み要因の割り当て,割り込み発生論理の状態が格納 されます。 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 EDS4 EDS3 EDS3 EDS1 SIG4 SIG3 SIG2 SIG1 割り込み発生論理設定状態 EDS1 SIG1の割り込み発生論理の設定 EDS2 SIG2の割り込み発生論理の設定 EDS3 SIG3の割り込み発生論理の設定 EDS4 SIG4の割り込み発生論理の設定 値 意味 0 High → Low 1 Low → High SIG1[割り込み要因割り当て] 値 意味 0 8255①のポートC接点3(ピン名:1PC3)入力信号 SIG2[割り込み要因割り当て] 値 意味 0 8255①のポートC接点0(ピン名:1PC0)入力信号 1 IR.IN1 SIG3[割り込み要因割り当て] 値 意味 0 8255②のポートC接点3(ピン名:2PC3)入力信号 SIG4[割り込み要因割り当て] 値 意味 0 8255②のポートC接点0(ピン名:2PC0)入力信号 1 IR.IN2 ※ 電源投入時,PCIバスリセット時、外部リセット信号入力時は全て設定値が0となっています。 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 Interface Corporation - 92 - TUT-0034 PpiSetTimerConfig インターバルタイマの設定を行います。 宣言 INT PpiSetTimerConfig(HANDLE hDeviceHandle,BYTE bTimerConfigValue); パラメータ hDeviceHandle bTimerConfigValue 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファにインターバルタイマの設定を以下のビット 構成で設定します。 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 − CTL7 CTL6 CTL5 CTL4 CTL3 CTL2 CTL1 タイマ周期はCTL5∼7で設定した基準周期と、CTL1∼4で設定した分周比の積となります。 (周期=基準周期×分周比) CTL4 CTL3 CTL2 CTL1 タイマ停止 0 0 0 0 1分周 0 0 0 1 2分周 0 0 1 0 3分周 0 0 1 1 4分周 0 1 0 0 5分周 0 1 0 1 6分周 0 1 1 0 7分周 0 1 1 1 8分周 1 0 0 0 9分周 1 0 0 1 10分周 1 0 1 0 11分周 1 0 1 1 12分周 1 1 0 0 13分周 1 1 0 1 14分周 1 1 1 0 15分周 1 1 1 1 CTL5∼7基準周期設定 10μs 100μs 1ms 10ms 100ms CTL7 0 0 0 0 1 CTL6 0 0 1 1 0 CTL5 0 1 0 1 0 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 - 93 - Interface Corporation TUT-0034 PpiGetTimerConfig インターバルタイマの設定情報を取得します。 宣言 INT PpiGetTimerConfig(HANDLE hDeviceHandle, PBYTE pbTimerConfigValue); パラメータ hDeviceHandle pbTimerConfigValue 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファにインターバルタイマの設定が以下のビット 構成で格納されます。 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 − CTL7 CTL6 CTL5 CTL4 CTL3 CTL2 CTL1 タイマ周期はCTL5∼7で設定した基準周期と、CTL1∼4で設定した分周比の積となります。 (周期=基準周期×分周比) CTL4 CTL3 CTL2 CTL1 タイマ停止 0 0 0 0 1分周 0 0 0 1 2分周 0 0 1 0 3分周 0 0 1 1 4分周 0 1 0 0 5分周 0 1 0 1 6分周 0 1 1 0 7分周 0 1 1 1 8分周 1 0 0 0 9分周 1 0 0 1 10分周 1 0 1 0 11分周 1 0 1 1 12分周 1 1 0 0 13分周 1 1 0 1 14分周 1 1 1 0 15分周 1 1 1 1 CTL5∼7基準周期設定 CTL7 CTL6 CTL5 10μs 0 0 0 100μs 0 0 1 1ms 0 1 0 10ms 0 1 1 100ms 1 0 0 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 Interface Corporation - 94 - TUT-0034 PpiGetTimerCount インターバルタイマのカウント値を取得します。 宣言 INT PpiGetTimerCount(HANDLE hDeviceHandle, PBYTE pbTimerCount); パラメータ hDeviceHandle pbTimerCount 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファにインターバルタイマの現在のカウンタ値が 以下のビット構成で格納されます。 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 − − − − CTL4 CTL3 CTL2 CTL1 PpiSetTimerConfig関数より設定した周期における、現在の状態値を4bitカウンタで取得します。 0カウント 1カウント 2カウント 2カウント 4カウント 5カウント 6カウント 7カウント 8カウント 9カウント 10カウント 11カウント 12カウント 13カウント 14カウント 15カウント CTL4 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 CTL3 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 CTL2 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 CTL1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 PpiGetResetInStatus 外部リセット入力信号の状態を取得します。 宣言 INT PpiGetResetInStatus(HANDLE hDeviceHandle, PBYTE pbResetInStatus); パラメータ hDeviceHandle pbResetInStatus 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファに外部リセット入力信号の状態が格納されます。 値 0 1 意味 リセット入力無効 リセット入力有効 戻り値 関数が成功するとFBIPPI_ERROR_SUCCESSが返されます。 関数が失敗するとFBIPPI_ERROR_SUCCESS以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラー コード一覧』を参照してください。 解説 外部リセット信号が有効の間(pbResetInStatus = 1)は、出力、および割り込みマスク、要因等の設定をすることができません。外 部リセット信号入力でリセットされた場合、PpiGetResetInStatusでリセット入力信号が無効になったことを確認してから製品の再 設定を行ってください。 - 95 - Interface Corporation TUT-0034 PpiEventRequestPending 割り込みイベント要求を待ちます。 宣言 INT PpiEventRequestPending(HANDLE hDeviceHandle, DWORD dwEventEnableMask, PDWORD pdwEventBuf, LPOVERLAPPED pOverlapped); パラメータ hDeviceHandle dwEventEnableMask 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファに許可するイベントを以下のビットアサイン で指定します。該当ビットが1の時有効です。 Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 pdwEventBuf バッファへのポインタを指定します。このバッファに通知されたイベントが以下のビットアサイ ンで格納されます。該当ビットが1の時有効です。 Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 lpOverlapped 8255 のポートC接点3(ピン名:1PC3)入力信号 8255 のポートC接点0(ピン名:1PC0)入力信号または、IR.IN1(外部割り込み入力信号)から の入力信号 ※ PCI-2747AはIR.IN1信号を持ちません。 8255 のポートC接点3(ピン名:2PC3)入力信号 ※ PCI-2747Aは8255 を持ちません。 8255 のポートC接点0(ピン名:2PC0)入力信号または、IR.IN2(外部割り込み入力信号)から の入力信号 ※ PCI-2747Aは8255 、IR.IN2信号を持ちません。 インターバルタイマ 外部リセット入力(RSTIN)割り込み 8255 のポートC接点3(ピン名:1PC3)入力信号 8255 のポートC接点0(ピン名:1PC0)入力信号または、IR.IN1(外部割り込み入力信号)から の入力信号 ※ PCI-2747AはIR.IN1信号を持ちません。 8255 のポートC接点3(ピン名:2PC3)入力信号 ※ PCI-2747Aは8255 を持ちません。 8255 のポートC接点0(ピン名:2PC0)入力信号または、IR.IN2(外部割り込み入力信号)から の入力信号 ※ PCI-2747Aは8255 、IR.IN2信号を持ちません。 インターバルタイマ 外部リセット入力(RSTIN)割り込み OVERLAPPEDデータ構造体へのポインタを指定します。 戻り値 関数が成功すると0が返されます。 関数が失敗すると0以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラーコード一覧』を参照して ください。 解説 オーバーラップ構造体(lpOverlapped)を指定した非同期コールの場合、FBIPPI_ERROR_IO_PENDINGを返し非同期での動作となり ます。PpiSetEventMask、PpiSetEventConfig関数により必要な割り込みイベントの設定、マスク解除を事前に行う必要があります。 Interface Corporation - 96 - TUT-0034 PpiCommonGetPciDeviceInfo デバイスID,リソース情報,製品ID(RSW1)等の情報を取得します。 宣言 INT PpiCommonGetPciDeviceInfo(HANDLE hDeviceHandle, PDWORD pdwDeviceID, PDWORD pdwVenderID, PDWORD pdwClassCode, PDWORD pdwRevisionID, PDWORD pdwBaseAddress0, PDWORD pdwBaseAddress1, PDWORD pdwBaseAddress2, PDWORD pdwBaseAddress3, PDWORD pdwBaseAddress5, PDWORD pdwSubsystemID, PDWORD pdwSubsystemVenderID, PDWORD pdwInterruptLine, PDWORD pdwBoardID); パラメータ hDeviceHandle pdwDeviceID pdwVenderID pdwClassCode pdwRevisionID pdwBaseAddress0 pdwBaseAddress1 pdwBaseAddress2 pdwBaseAddress2 pdwBaseAddress4 pdwBaseAddress5 pdwSubsystemID pdwSubsystemVenderID pdwInterruptLine pdwBoardID 有効なデバイスハンドルを指定します。 バッファへのポインタを指定します。このバッファにデバイスIDデータが格納されます。弊社 PCIバス用PPI製品は、製品型式の数字部分4桁が適用されます。PCI-2746Cならば2746(16進数で はABAh)、PCI-2747Aならば2747(16進数ではABBh)です。 バッファへのポインタを指定します。このバッファにベンダIDデータが格納されます。弊社の ベンダIDは、1147h(16進数)です。 バッファへのポインタを指定します。このバッファにクラスコードデータが格納されます。 バッファへのポインタを指定します。このバッファにリビジョンIDデータが格納されます。 バッファへのポインタを指定します。このバッファにリソース0データが格納されます。弊社PCI バス用PPI製品は、ここに占有するI/O領域が格納されます。取得した値をFFFChでマスクした値 が占有するI/O領域のベースアドレスです。 バッファへのポインタを指定します。このバッファにリソース1データが格納されます。弊社PCI バス用PPI製品では、使用しません。 バッファへのポインタを指定します。このバッファにリソース2データが格納されます。弊社PCI バス用PPI製品では、使用しません。 バッファへのポインタを指定します。このバッファにリソース3データが格納されます。弊社PCI バス用PPI製品では、使用しません。 バッファへのポインタを指定します。このバッファにリソース4データが格納されます。弊社PCI バス用PPI製品では、使用しません。 バッファへのポインタを指定します。このバッファにリソース5データが格納されます。弊社PCI バス用PPI製品では、使用しません。 バッファへのポインタを指定します。このバッファにサブシステムIDデータが格納されます。 バッファへのポインタを指定します。このバッファにデバイスIDデータが格納されます。 バッファへのポインタを指定します。このバッファに割込みラインデータが格納されます。 バッファへのポインタを指定します。このバッファに製品IDデータが格納されます。 戻り値 関数が成功すると0が返されます。 関数が失敗すると0以外の値が返ります。関数が失敗した場合の戻り値については『98ページ エラーコード一覧』を参照して ください。 - 97 - Interface Corporation TUT-0034 エラーコード一覧 定数 FBIPPI_ERROR_SUCCESS FBIPPI_ERROR_NOT_DEVICE FBIPPI_ERROR_NOT_OPEN FBIPPI_ERROR_INVALID_HANDLE FBIPPI_ERROR_ALREADY_OPEN FBIPPI_ERROR_HANDLE_EOF FBIPPI_ERROR_MORE_DATA FBIPPI_ERROR_INSUFFICIENT_BUFFER FBIPPI_ERROR_IO_PENDING FBIPPI_ERROR_NOT_SUPPORTED FBIPPI_ERROR_MEMORY_NOTALLOCATED FBIPPI_ERROR_PARAMETER FBIPPI_ERROR_INVALID_CALL FBIPPI_ERROR_DRVCAL FBIPPI_ERROR_NULL_POINTER Interface Corporation 値 0 0xC0000001 0xC0000002 0xC0000003 0xC0000004 0xC0000005 0xC0000006 0xC0000007 0xC0000008 0xC0000009 0xC0001000 0xC0001001 0xC0001002 0xC0001003 0xC0001004 内容 正常終了 指定されたデバイスがありません システムがデバイスをオープンできません デバイスハンドルが正しくありません すでにOPENしているデバイスをOPENしようとしました EOFに達しました さらに多くのデータが利用可能です システムコールに渡されたデータ領域が小さすぎます 非同期I/O操作が進行中です サポートされていない機能です 作業用メモリの確保に失敗しました 引数パラメータの値が不正です 不正なファンクション呼び出しです ドライバ が 呼び出せません。 ドライバ,DLL間でNULLポインタが渡されました - 98 - TUT-0034 第6章 8255 PPIコントローラ説明 8255は、プログラマブル汎用I/Oデバイスです。3組(8ビット)の入出力ポートがあり、プログラム による制御でデータ入力,データ出力,ステータス信号入力,コントロール信号出力に使用すること ができます。 6.1 ポートA,B,C 8255は8ビットの入出力ポートが3個あり、それぞれをポートA,ポートB,ポートCと呼びます。 各ポートごとに独特の性質を持っていますので、ポートの選択によって8255の適応性が生かされ ます。 ポートA ポートB ポートC 入力時 ラッチ入力あるいはバッファ入力動作 出力時 ラッチ出力動作 入力時 ラッチ入力あるいはバッファ入力動作 出力時 ラッチ出力動作 入力時 バッファ入力動作(ラッチされません) 出力時 ラッチ出力動作 ポートCはモードによって2つの4ビットポートに分割して使用することが できます。 また、ポートA,Bのコントロール信号の出力ポート、あるいはステータス信 号の入力ポートとして用いることができます。 各ポートと信号名は次の表のように対応しています。 PA0∼PA7 PB0∼PB7 PC0∼PC7 ポートA ポートB ポートC 6.2 グループA制御,グループB制御 8255を使用するにあたって、ポートA,ポートB,ポートCを2つに分けグループA,グループBとしま す。 モード0 モード1 モード2 基本的な入出力ポート コントロール信号,ステータス信号による制御を伴う入出力ポート 双方向データを扱う入出力ポート 使用する目的に合わせて、各グループごとにモードを設定します。可能なモードの組み合わせは 次の6通りです。 ・グループA:モード0, グループB:モード0 ・グループA:モード0, グループB:モード1 ・グループA:モード1, グループB:モード0 ・グループA:モード1, グループB:モード1 ・グループA:モード2, グループB:モード0 ・グループA:モード2, グループB:モード1 - 99 - Interface Corporation TUT-0034 モードの選択はPpiControl関数にて行います。指定する制御データ下記のフォーマットとなりま す。 制御データ(8ビットのバイトデータ) D7 D6 D5 D4 D0 グループB D3 ポートC下位 D1 ポートB D2 モード選択 D3 グループA ポートC上位 D4 ポートA D5, モード選択 D6 D7 機能制御 D2 D1 D0 0 出力 1 入力 0 出力 1 入力 0 モード0 1 モード1 0 出力 1 入力 0 出力 1 入力 00 モード0 01 モード1 1X モード2 0 ビットセット,リセット 1 モード選択 ポートCをコントロール信号の出力,ステータス信号の入力として使用する場合、PpiControl関数に てビットセット/リセットすることができます。 この操作を行うことによって割り込み許可,割り込み禁止等の設定をします。 コントロール信号のビットセット/リセットを行う場合の制御データ 0(D7) X X X D3 D2 D1 D0 6.3 各ビットの対応 D0 D1 D2 D3 D7 セット/ リセット ポートC ビット選択 機能制御 0 リセット 1 セット 0 1 2 3 4 ビット D1 0 1 0 1 0 D2 0 0 1 1 0 D3 0 0 0 0 1 0を指定しビットセット,リセット機能選択 5 1 0 1 6 0 1 1 7 1 1 1 備考:I/Oモジュールがリセットされた時、あるいはモードを選択した時、自動的に全ビットは リセットされます。 Interface Corporation - 100 - TUT-0034 (1)モード0 このモードでは基本的な入出力ポートとして動作をします。この場合、モード0になっている 各ポートはバッファ入力,ラッチ出力動作をします。 出力ポートに指定されたポートは、出力値をラッチし、常に端子から出力します。モード設定直 後はLowレベルを出力します。 また出力ポートに指定されているポートを読み出せば、出力している値が得られます。 PpiContorol関数にて下記の制御データを指定することによりポートA,ポートB,ポートC(上位), ポートC(下位)それぞれを独立に入力あるいは出力ポートに設定します。 モード0を設定する場合の制御データ 1(D7) D0 0(D6) グループB D1 D2 D3 0(D5) D4 D3 ポートC下位 PC0∼PC3 (PC0∼PC2) ※ ポートB D4 モード選択 ポートC上位 PC4∼PC7 ポートA D5,D6 モード選択 D7 グループA 機能制御 0(D2) 0 1 D1 D0 出力 入力 0 出力 1 入力 0を指定しグループBをモード0を指定 0 出力 1 入力 0 出力 1 入力 00(D6,D5)を指定し モード0を指定 1を指定しモード選択機能を選択 ※ グループAがモード0以外の場合にはグループBが使えるポートCのビットはPC0∼PC2の3ビッ トになります。 - 101 - Interface Corporation TUT-0034 (2)モード1 データの入出力制御にコントロール信号,ステータス信号を用いるモードです。モード1では、グ ループA,グループBを単位として使用し、グループAはデータ・ポートにポートA(PA0∼PA7),コン トロール/ステータス・ポートにポートC上位ビット(PC3∼PC7),グループBはデータ・ポートに ポートB(PB0∼PB7),コントロール/ステータス・ポートにポートC下位3ビット(PC0∼PC2)によって 構成します。 モード1では、ポートCへの書き込みはビットセット/リセット機能で行います。 モード1を設定する場合の制御データ 1(D7) 0(D6) 1(D5) D0 グループB D1 D2 D3 グループA D4 D5,D6 D7 D4 D3 ポートC PC3※ ポートB モード選択 ポートC ・ポートA入力時 PC6,PC7 ・ポートA出力時 PC4,PC5 ポートA モード選択 機能制御 1(D2) D1 D0 0 出力 1 入力 0 出力 1 入力 1を指定しモード1を指定 0 出力 1 入力 0 出力 1 入力 01(D6,D5)を指定しモード1を指 定 1を指定しモード選択機能を選 択 ※ グループAがモード0の時のみポートCのPC3を使用できます。それ以外ではPC3はグループA に属します。 モード1でのポートCの機能 ビット PC0 グループB グループA データ入力ポート時 INTR(INTerrupt Request) データ出力ポート時 INTR(INTerrupt Request) PC1 IBF(Input Buffer Full F/F) OBF (Output Buffer Full F/F) PC2 STB (STroBe input) RIE(Read Interrupt Enable flag) 入出力 INTR(INTerrupt Request) DAC (Data Acknowledge input) WIE(Write Interrupt Enable flag) PC3※ PC3 PC4 PC5 PC6 PC7 入出力 INTR(INTerrupt Request) 入出力 STB (STroBe input) RIE(Read Interrupt Enable flag) IBF(Input Buffer Full F/F) 入出力 ACK(Data Acknowledge input) 入出力 WIE(Write Interrupt Enable flag) 入出力 OBF (Output Buffer Full F/F) ※ グループAがモード0の時のみ使用できます。それ以外ではPC3はグループAに属します。 Interface Corporation - 102 - TUT-0034 <データ・ポートを入力に指定した時の動作> データ・ポート(グループAならポートA、グループBならポートB)を入力ポートに指定すると、 データ・ポートは入力ポートとなり、コントロール/ステータス・ポート(ポートC)は次のように定 義されます。(説明中では信号名の上線を省略しています。) STB(Strobe Input)・・・・入力 この入力をLowレベルにすると、外部接続機器からデータ・ポートに送られている信号をデータ・ ポートがラッチします。 IBF(Input Buffer Full F/F)・・・・出力 この出力がHighレベルの時は入力バッファが満たされていることを意味し、外部接続機器に対し てデータの転送の禁止を知らせます。この信号はSTBの立ち下がりでHighレベルとなりデータ読 み出し終了時でLowレベルになります。モード設定直後の初期値はLowレベルです。 INTR(Interrupt Request)・・・・出力 この出力は外部接続機器からのデータが入力ポートにラッチされたときにHighレベルとなり、コ ンピュータに対するデータ読み出し要求割り込み信号として働きます。 なお、RIEにより割り込み許可を行っていない場合、出力はHighレベルのままとなります。 RIE(Read Interrupt Enable flag) コンピュータに対するデータ読み出し要求割り込みの許可フラグで、このビットをビット操作命 令で1にすることによって割り込み許可、0にすることによって割り込み禁止にします。RIEを書き 換えても同じビットに割り当てられているSTBの機能には影響を与えません。 IBF信号がLowレベルになる前にSTBがLowレベルになるとポート内ラッチデータが変化してしま います。 STBはIBFがLowレベルになるまではHighレベルに保たなければなりません。 モード1の入力ポート指定状態でポートCを読み出せばIBF,INT,RIEのステータスが得られます。 ●モード1(グループA)入力 - 103 - Interface Corporation TUT-0034 ●モード1(グループB)入力 ※印の場合、8255内部のラッチが変化してしまいますので、IBF=”0”になるまでSTBを”1”に保つ ようにする必要があります。 ●モード1入力タイミング t ST ST B t S IB IB F tPH tP S 外部バス RD t S IT IN T Interface Corporation - 104 - TUT-0034 <データ・ポートを出力に指定した時の動作> データ・ポート(グループAならポートA、グループBならポートB)を出力ポートに指定すると、デー タ・ポートは出力ポート(モード設定直後はLowレベルを出力)となり、コントロール/ステータス・ ポート(ポートC)は次のように定義されます。(説明中では信号名の上線を省略しています。) OBF (Output Buffer Full F/F)・・・・出力 この信号はコンピュータからのデータを受け出力ポートにラッチされた時にLowレベルとなり、 外部接続機器に対してのデータ受け取り要求として働きます。 OBFはACK=1のときのデータ書き込み終了時でLowレベルになり外部接続機器がデータを受け取 った時のACKの立ち下がりでHighレベルになります。 モード設定直後の初期値はHighレベルです。 ACK(Data Acknowledge input)・・・・入力 この入力は外部接続機器が出力ポートのデータを受け取ったということを知らせる信号です。 データを受け取った時にLowレベルの信号を出すように外部接続機器を設計します。 INTR (Input Request)・・・・出力 この出力は外部接続機器がデータを受け取った時にHighレベルとなり、コンピュータに対する次 のデータの書き込み要求割り込み信号として働きます。 なお、WIEにて割り込み許可を行っていない場合、Highレベルのままとなります。 WIE (Write Interrupt Enable Flag) コンピュータに対するデータ書き込み要求割り込みの許可フラグで、このビットをビット操作命 令で1にすることによって割り込み許可、0にすることによって割り込み禁止にします。 WIEを書き換えても同じビットに割り当てられているACKの機能には影響を与えません。 OBF信号がHighレベルになる前にデータの書き込みを行うとポート出力が変化してしまいますの で、OBF信号がLowレベルの間は書き込みは避けてください。 モード1の出力ポート指定状態でポートCを読み出せば、OBF,NT,WIEのステータスが得られます。 - 105 - Interface Corporation TUT-0034 ●モード1(グループA)出力 ●モード1(グループB)出力 ●モード1出力タイミング WR IN T tAO B OBF t A IT ACK t AK 外部バス Interface Corporation - 106 - TUT-0034 (3)モード2 このモードはグループAのみが可能で、ポートAがコントロール/ステータス信号(ポートC上位5ビ ット)の制御によって入力,出力の双方向の8ビット・データ・ポートとして使用され、モード1の入 力ポート動作,出力ポート動作を合わせたような動作をします。 グループA・モード2でのポートCの機能 ビット PC3 PC4 PC5 PC6 PC7 INTR(INTerrupt Request) STB(STroBe input) RIE(Read Interrupt Enable flag) IBF(Input Buffer Full F/F) DAC(Data Acknowledge input) WIE(Write Interrupt Enable flag) OBF(Output Buffer Full F/F) DAKとSTBの信号でポート0の入力状態,出力状態を切り換えながら、データを双方向へ送ること ができます。モード2ではポートCへの書き込みはビット操作命令で行います。各信号の動作,機能 はモード1の説明を参照してください。 モード2においてポートCを読み出せば、OBF,IBF,INTR,WIE,RIEのステータスが得られます。 備考:モード1と入力動作は同じです。出力動作は次の点が違います。 ・ACK信号がLowレベルの時のみ、出力データがポートAより出力される。 ・出力ポートの出力データは読み出せない。 - 107 - Interface Corporation TUT-0034 モード2入出力タイミング 8255 → PC I バ ス データ書き込み WR IN T 8255 → PC I バ ス データ読み出し RD tAK ACK tST ST B tAO B OBF t S IB IB F tP S tP H tAD tKD 外部バス 外 部 バ ス → 8255 8255 → 外 部 バ ス (4)特殊なモードの組み合わせについて ポートCの全てのビットがコントロール/ステータス信号として用いられるわけではありません。 グループA,グループBともにユーザがデータの入出力に利用できるビットがあります。これらのビ ットを持つモードの組み合わせによって次のような機能を持ちます。 入力動作としてプログラムした時 全ての入力ラインをポートCの読み出し中にアクセスできます。 出力動作としてプログラムした時 ポートC上位4ビット(PC4∼PC7)とポートC下位4ビット(PC0∼PC3)は、それぞれビット操作命令を 用いて個別に書き込みができます。ポートC下位3ビット(PC0∼PC2)は3ビット単位でも書き込み ができます。 Interface Corporation - 108 - TUT-0034 モード1でのPC6,PC7またはPC4,PC5のデータの入出力のセットは、モード選択時の制御データの ビット3(ポートC(上位))で、PC3はビット0(ポートC(下位))で行います。 “1”で入力,“0”で出力ポートにセットします。 入力ポートにセットしたビットのデータは、ポートCの読み出し動作でシステム・バスに読み出せ ます。一方出力ポートにセットしたビットにデータを書き込むためには、ビット操作命令を実行 してください。1度のビット操作命令で出力できるのは1ビットのON/OFFのみです。例えば PC6,PC7と2ビットのデータを書き込むためにはビット操作命令を2回実行してください。 1回目:PC6への書き込み 2回目:PC7への書き込み ポートCに8ビット単位でデータを書き込めるのは、モード0でポートCの上位,下位ビットともに出 力ポートと指定した時だけです。 - 109 - Interface Corporation TUT-0034 技術資料紹介 弊社では下記の技術資料を提供しております。 詳しくは、弊社Web site(www.interface.co.jp)、または弊社窓口までお問い合わせください。 カタログ PRM-0061 PRM-0062 PRM-0063 CPZカタログ(日本語版) PCIカタログ(日本語版) CSIカタログ(日本語版) チュートリアル TUT-0058 TUT-0056 TUT-0055 TUT-0054 TUT-0053 TUT-0050 TUT-0048 TUT-0044 TUT-0043 TUT-0041 TUT-0040 TUT-0039 TUT-0038 TUT-0037 TUT-0036 TUT-0034 TUT-0033 TUT-0032 TUT-0031 TUT-0030 TUT-0029 TUT-0028 TUT-0027 TUT-0026 TUT-0025 TUT-0024 TUT-0023 TUT-0022 TUT-0021 TUT-0020 TUT-0019 TUT-0018 TUT-0017 TUT-0016 TUT-0015 TUT-0014 TUT-0008 TUT-0007 TUT-0006 TUT-0005 TUT-0004 TUT-0003 TUT-0002 TUT-0001 チュートリアル CPZ拡張ユニット 入門編 チュートリアル XP Embedded OS構築編 チュートリアル 画像入力I/Oモジュール CANチュートリアル モーションコントロールチュートリアル RTLinuxによるモーションコントローラI/Oモジュール制御プログラミング チュートリアル(GPG-7400用) RTLinuxによるメモリンクI/Oモジュール制御プログラミング チュートリアル RTLinuxによるメモリ共有インタフェースI/Oモジュール制御プログラミング チュートリアル RTLinuxによる調歩同期シリアル通信I/Oモジュール制御プログラミング チュートリアル RTLinuxによるGP-IBI/Oモジュール制御プログラミング チュートリアル RTLinuxによるDAI/Oモジュール制御プログラミング チュートリアル RTLinuxによるADI/Oモジュール制御プログラミング チュートリアル RTLinuxによるDIOI/Oモジュール制御プログラミング チュートリアル RTLinuxによるHDLCI/Oモジュール制御プログラミング チュートリアル RTLinuxによるPCI/CompactPCI/CardBus制御入門書(導入編) Visual C++によるPPI入門書 Visual Basicによるメモリ共有インタフェース入門書 Visual C++によるメモリ共有インタフェース入門書 Visual Basicによるメモリンク入門書 Visual C++によるメモリンク入門書 Visual BasicによるHDLC入門書 Visual C++によるHDLC入門書 Visual BasicによるGP-IB入門書 Visual C++によるGP-IB入門書 Visual BasicによるDIO入門書 Visual C++によるDIO入門書 Visual BasicによるDA入門書 Visual C++によるDA入門書 Visual BasicによるAD入門書 Visual C++によるAD入門書 Visual Basicによるモーションコントローラ入門書 Visual C++によるモーションコントローラ入門書 メモリンクを使用した負荷分散システム事例チュートリアル Visual BasicによるPPI入門書 モーションコントロールチュートリアル Microsoft Visual Studio .NET移行ガイド 拡張ユニット チュートリアル(問題解決編) 拡張ユニットチュートリアル(入門編) C(98)/ISA製品からPCI/CompactPCI製品への移行チュートリアル(DOS編) DOSによるLAP-B入門書 DOSによるAD入門書 LinuxによるPCI/CompactPCI/CardBus制御 入門書 PCI-ISAバスブリッジチュートリアル PCI-Cバスブリッジチュートリアル 技術情報資料 初めてのCANインタフェース Linux, リアルタイムLinux移植(SH-4)経験談及び当社の今後の取り組みについて LinuxからPCI/CompactPCII/Oモジュールを制御する方法 ActiveXコントロールによるシステム組み込み技術 CompactPCIへの置き換え+システム構築/移行ガイド MS-DOSからPCI/CompactPCII/Oモジュールを制御する方法 Interface Corporation - 110 - TUT-0034 参考文献 著 者 題 名 里 和政/神崎 康宏/斎藤 健司 トランジスタ技術SPECIAL №9「パラレル・インタフェー ス用LSIの使い方」(CQ出版社:1988年) Intel IntelR82C55A CHMOS PROGRAMMABLE PERIPHERAL INTERFACE Datasheets(Intel:October 1995) マイクロソフト株式会社 監修, Microsoft Visual C++/Visual C++ Win32 API オフィシャル アスキー書籍編集部 編 リファレンス 改訂版(株式会社アスキー:1997年) [ISBN4-7561-1106-8] ! 警告 本ドキュメントの一部または全てを弊社の許可なく、複写,複製,転載,電子化することを禁じま す。 - 111 - Interface Corporation TUT-0034 2007年 5月 Ver. 1.1 発行 発行所 〒732-0828 広島県広島市南区京橋町10-21 TEL 082-262-7777 FAX 082-262-5066 定価 ¥2,000 本書の内容の一部または全部を、無断で転載することを禁止します。 本書の内容は、将来予告なく変更することがありますので、予めご了承ください。 © 2001, 2007 Interface Corporation. All rights reserved. サポート体制 本製品についてのお問い合わせは、カスタマーサポートセンタで承ります。弊社Web siteのオ ンラインQA(「サポート」→「お客様相談センタ」をクリック)、E-mailまたはフリーダイヤルをご 利用ください。 お問い合わせ先 <カスタマーサポートセンタ> 0120-447213 FAX 0120-458257 TEL (祝日および弊社休業日を除く月~金 AM9:00~PM5:00迄) E-mail [email protected] TUT-0034 Ver. 1.1 Vol. 1/1 www.interface.co.jp Visual C++によるPPI入門書 TUT-0034 Ver. 1.1 www.interface.co.jp