什么是端口?
端口包含了一系列信号线, 通过这个端口 CPU 可以同其他外部设备交换数据, 比如我们经
常见到的 Modem,打印机等.
通常情况下, 打开的信号是”1”, 关闭的信号是”0”. 并口在同一时间内可以发送 8 位的数
据, 接收 5 位的数据. 而串口 RS-232 则只能发送 1 位数据, 但串口是多向的, 所以在同一时刻
既可以发送也可以接收.
并口
D0-D7 为数据线, S0-S7 为状态线, 但是 S0,S1,S2 是看不见的(从图中你也可以看出),
状 态 线 是 用 来 读 取 数 据 的 , 但 S0 却 不 同 , 它 是 超 时 标 志 位 , 其 他 的 状 态 线 从 第
10-11-12-13-15 针是用来发送数据的(可以看出是 5 位). 那么我们怎么能得到这些数据端口
呢? 很简单: 每一个并口都有一个地址. 在 Windows2000 中, 你可以在打印机端口(LPT1)的
属性中看到他们. 比如:我的是 0378-037F, 如果是 10 进制, 那么就是 888. 同样你也可以看
到你的 COM 端口的地址. 让我以打印机为例解释一下这些针位的意义:
S0: 在 EPP(增强的串口)模式下, 如果超时的话, 这位置 1.
S1: 没用(估计是装饰).
S2: 大多数情况下没有使用.
S3: 如果打印机发生了错误则置 0. 它通常被叫做 nError 或者 nFault.
S4: 如果数据达到, 则置 1.我们通常叫做 Select.
S5: 如果没有打印纸了则置 1.通常叫做 PaperEnd 或者 PaperEmpty 或者 PError.
S6: 如果打印机得到了一个字节的数据则此位置 0, 通常叫做 nAck 或者 nAcknowledge.
S7: 如果打印机处于繁忙的状态则此位置 0, 通常叫做 Busy.
控制线:
这些线通常用来输出,但有时也可以用于输入. 他们占用 C0-C7(如图), 但是在接口上 C4,
C5, C6, C7 是不可见, 他们占用的端口地址是 0x37A.
C0: 这一针脚是保留的. 他发送命令去读取端口上的数据(D0-D7). 当计算机启动的时候,
这一位被置 1,通常叫做 nStrobe.
C1: 保留.通过他发送命令给打印机, 可以得到下一条打印线.(LF)
C2: 重置打印机并且清空数据缓冲区.(nInitialize)
C3: 保留.置高电平打开数据输入.启动计算机时置 0.(nSelectIn)
地线:
从 G0-G7 的针是接地用的, 他们一般是用来完善电路的.
综上所述,在我的应用程序里使用数据线而不是具有保留位的控制线或者状态线作为数据传
输。原因显而易见:我们可以发送任何数据到数据线上,比如 00000000,这样 8 根针就没有
任何电压(0 伏特);当然也可以发送 11111111(255),这样每根针都有+5 伏特的电压。
但是如果我们使用控制线,他有 C0,C1 和 C3 是保留,当我们发送 0000000 的时候,他却只
能是 0100,所以这样数据就不正确了。
信号
数据位
针脚
方向
-Strobe
¬C0
1
Output
+Data Bit 0
D0
2
Output
+Data Bit 1
D1
3
Output
+Data Bit 2
D2
4
Output
+Data Bit 3
D3
5
Output
+Data Bit 4
D4
6
Output
+Data Bit 5
D5
7
Output
+Data Bit 6
D6
8
Output
+Data Bit 7
D7
9
Output
-Acknowledge
S6
10
Input
+Busy
¬S7
11
Input
+Paper End
S5
12
Input
+Select In
S4
13
Input
-Auto Feed
¬C1
14
Output
-Error
S3
15
Input
-Initialize
C2
16
Output
-Select
¬C3
17
Output
Ground
-
18-25
Ground
下面的电路图说明了我们的电路如何工作:
下面的图片是从不同角度拍摄的,说明了最终完成电路的样子:
我们再来看看到底都需要一些什么:
1-2 米的并口电缆(3 米也是可以的,不过这样电压将降低到 4.7V)
9 芯的电缆(8 根用于连接二极管,1 根用于接地)
一个电路实验板(图中白色的东西)
8 个发光二极管
万用表(不是必要)
我的程序, 使得你的电路可以工作 J
这里省略了原著中关于数制转换的介绍, 相信能看这篇文章的这都是小意思.
编码
在编码之前, 你应该先确定一下你的 OS. 如果你使用 Win98, 你可以通过”outputb”函数
访问端口. 当你升级到 Win2000 后, 使用这个函数就不行了.在 WinNT, Win2K, WinXP 下是
不能直接访问端口的. 在我的程序中使用inpout32.dll 来访问端口, 在这个地址有这个Dll 的源
代码.
注意: 我是使用这个地址(http:/www.logix4u.net )的应用信息来导入函数的, 你访问的
时候这个信息可能已经更新了.
在我的 PortInterop.cs 文件中, 我如下使用这个 DLL
using System;
using System.Runtime.InteropServices;
public class PortAccess
{
}
[DllImport("inpout32.dll", EntryPoint="Out32")]
public static extern void Output(int adress, int value);
这个函数携带 2 个参数,一个是地址,一个是数据. 如果向 LPT1 发送数据, 那么就设置地址
参数为 888(16 进制为 0x378), 如果是 LPT2, 那么就是 0x278, 比如:
PortAccess.Output(888, 255);
发送空数据就是这样:
PortAccess.Output(888, 0);
如果是使用 TruboC++就是这样:
#include
#include // For _out
#define port 0x378 // Port Address
#define data port+0 // Data Port of the parallel cable
void main (void)
{
_out(data, 255); // For all lights on
_out(data, 0); // For all lights off
}
简单的使用 C#操作端口就是这样了, 如果你发挥你的想象力, 可以设计很多实用的电路,
你可以到其他一些电路方面的新闻组上去搜索一下, 相信你会找到更多的灵感, 比如你可以做
个: