PCのI/Oポート操作
組込みをやっているとデバッグ時に適当なパルスを発生させたり、ある入力に
対して応答を出力したり、といった処理をする必要があります。
波形発生器等があれば大抵のことは出来ますし、精度もいいので文句はないのですが、
これらを使わずに、PCからのI/Oポート操作で簡易的なツールを作られてる方は多いと思います。
この辺りのツールはDOSの時代の方がやりやすかった(^^; ことと思います。Windowsになって
行儀が悪いとされながらも、3.1 や 95,98では強引に出来ていました。が、NT/2000ではそうは
行きません(DDKでドライバ作ればいいんですがね^^;)。
そういうこともあり、PCのI/Oポートを直接操作するDLLや、デバイスドライバも多く作られて
おります。市販のものもありますし、フリーのものもあります。これらを使わない手は
ないでしょう。
Window9x/NT/2000 で使えて且つ、フリーのものを物色したところ、気に入ったのが見つかり
ました。
WinIo.dll v1.3(2001/03/17) です。Yariv Kaplan 氏が作成されたソフトェアで、
http://www.internals.comからダウンロードできます。
この WinIo.dll を使って I/Oポート(LPTポート)を操作するツールを作ってみました。
(注) Windowsアプリケーションとしては異端であることを最初に断っておきます。
【WinIo.dll のススメ】
- WinIo.dllラッパークラス CWio を作る
- CWioクラスのデモ
- LPTポートの説明
- WinIo.dllラッパークラス CWio を作る
ダウンロードした winio.zip を解凍したら、\Winio\Release 以下の
WinIo.dllとWinIo.sysの2ファイルを使用します。
WinIo.sys は WinIo.dll が使用するので、ユーザー側は気にすることは特に
ありません。WinIo.dll は動的にリンクするようにします。CWio は、初期化処理にて
全てのWinIo.dllのexport関数のアドレスを獲得して置きます。後は必要な時に、
それを元にコールします。使い終わったら、終了処理をコールして、
WinIo.dll をメモリから解放します。
CWioのユーザーは、上記のようなことは気にせず、初期化と終了処理さえ
行えば、好きなように直接I/Oポートを操作できます。
ソースはこちら。
CWio クラス図
CWioの公開メソッドです。
- CWio()
コンストラクタ。LPTポートの初期化等行う。
- ~CWio()
デストラクタ。
- int Init()
初期化処理。ポートのRead/Wirte を行う前に必ず一度コールして置きます。WinIo.dll の
動的ロードとDLL内の関数ポインタを一括して獲得します。
- void End()
終了処理。ポートの Read/Write を行わない時や、アプリケーションを終了するときに
コールします。WinIo.dll を開放します。
- bool ReadPort( BYTE & )
指定のLPTポート(ステータスポート)から、1バイトデータを読み込みます。
- bool WritePort( BYTE )
指定のLPTポート(データポート)へ、1バイトデータを書き込みます。
- void SetLptPort( WORD )
LPTポートアドレスを指定します。デフォルトで LPTポートは 0378h になっ
ています。このデフォルト値を変更したい場合にコールします。一度コールす
ると以降のポートRead/Wirte はそのアドレスが対象となります。
- bool ReadPort( BYTE &, WORD )
指定したアドレスから、1バイトデータを読み込みます。
- bool WritePort( BYTE, WORD )
指定したアドレスへ、1バイトデータを書き込みます。
- CWioクラスのデモ
CWioを使った VC6.0のデモプロジェクトです。かなり手抜きですが、
基本動作確認においては十分でしょう。LPTポート0x378を読み書きします。
- [Start]ボタンで、WinIo.dllをロードして初期化します。
- [RearPort]ボタンで 0x378ポートを読み込み、16進数表示します。
- [WritPort]ボタンで 右のエディットBOX中の10進数を 0x378ポートに書き込みます。大きく手を抜いています。10進数です。
- [End]ボタンで、WinIo.dll を解放します。
ソースはここ。
LPTポートの各bitとプリンタコネクタとのピン番号の対応は下記のようになります。
D-sub25pinのコネクタとの対応
Pin |
I/O |
Description |
1 | I/O | -ストローブ信号 |
2 | I/O | data bit 0 |
3 | I/O | data bit 1 |
4 | I/O | data bit 2 |
5 | I/O | data bit 3 |
6 | I/O | data bit 4 |
7 | I/O | data bit 5 |
8 | I/O | data bit 6 |
9 | I/O | data bit 7 |
10 | I | -アクノリッジ信号 |
11 | I | ビジー信号 |
12 | I | プリンタエラー信号 |
13 | I | セレクト信号 |
14 | O | -オートフィーダ信号 |
15 | I | -エラー信号 |
16 | O | -初期化信号 |
17 | O | -セレクト信号 |
18 | - | GND |
19 | - | GND |
20 | - | GND |
21 | - | GND |
22 | - | GND |
23 | - | GND |
24 | - | GND |
25 | - | GND |
- LPTポートの説明
- LPTポート
BIOSの内容より最大4台のパラレルポートが使用できるようですが、
実際には3台(LPT1,LPT2,LPT3)にしか対応してないです。
プリンタポート・アドレスは以下に示す3つでこの順番に使用可能で
ある状態かをチェックして、使用可能であればそこのポートがデフォ
ルトのプリンタポートとな
ります。
Printer Port Address
| Data Address | Status Address | Parallel Control | Int.Level |
Parallel 1 | 03BCh | 03BDh | 03BEh | IRQ 7 |
Parallel 2 | 0378h | 0379h | 037Ah | IRQ 7 |
Parallel 3 | 0278h | 0279h | 027Ah | IRQ 5 |
- Data Resister
データレジスタは 8bit でプリンタポートデータの読み込みと書き込み
を行います。bit0〜bit7 はパラレルポートのピン番号2〜9 に相当します。
余談でが PC-98 series では出力のみとなるためI/O仕様をあわせる為に PC/AT で
も出力としてしか使用しないようにしていまいした。〜PC98全盛時代〜。
- Status Resister
ステータスレジスタはプリンタ状態のラインを読み込む Read Only のレジス
タです。bit 7 の BUSY信号は反転されて入力されます。
このbit 7 はパラレルポートのビン番号11
に相当します。
くどいですが反転されて入力されますので御注意下さい。
Status Resister bit assign
bit |
Description |
Note |
0 |
- |
- |
1 |
- |
- |
2 |
INST |
interrupt status |
3 |
ERR |
0:printer error |
4 |
SLCT |
1:printer select |
5 |
PE |
1:printer paper end |
6 |
ACK |
0:ACK receive |
7 |
BUSY |
0:printer busy |
(*) Linux でヤルってものいいですね。Windowsより煩雑でなさそうです。
LINUX研究所なんか見てるとそう思いますです。
by masu
e-mail: massun.masumoto@nifty.ne.jp
URL : http://member.nifty.ne.jp/~masumoto/