The parallel port is referred to as parallel port. It has 3 ports: data port, status port, and control port. The commonly used parallel port is LPT1. The addresses of its three ports are: 378H, 379H and 37AH respectively.
1. Read and write parallel
In assembly language, the parallel port can be operated with the in and out instructions, but there are no corresponding functions and methods in Delphi to read and write the parallel port. Fortunately, Delphi can be embedded in the assembly program, and directly embed the assembly instructions in and out It can easily read and write parallel ports. We can also access the parallel port by calling Windows API functions or DLLs and VXDs provided by third parties, but it is more convenient and quick to read and write the parallel port by using embedded assembly methods.
Use the following ReadPort function and WritePort procedure to read and write parallel ports, and the parameter Port is the port address to operate.
function ReadPort(Port:Word):BYTE;
var
B:BYTE;
Begin
ASM
MOV DX, Port;
IN AL, DX;
MOV B, AL;
END;
Results:=B;
end;
PRocedure WritePort(Port:WORD;ConByte:BYTE);
Begin
ASM
MOV DX, Port;
MOV AL, ConByte;
OUT DX, AL;
END;
end; 2. bit operation
To control the parallel port in bitwise terms, you can first read the data of the parallel port, then perform bit operations, and then write to the parallel port again, so that the bit control of the parallel port can be achieved.
The logical operator and performs bitwise logic and operation on two numbers to be operated: that is, the result of 1 and 1 is 1, and the other 0 and 1, 1 and 0 and 0 and 0. The results of 0 are all 0.
Logical operator or performs bitwise logical or operation on two numbers to be operated: that is, as long as the two bits of "OR" are one, the result is 1; otherwise, the result of "OR" is 0.
Use the and operator to specify the position 0. For example, the binary of hexadecimal 84H is: 10000100, and its third bit is 1. To set the third position to 0 and other bits remain unchanged, you can use: $84 and $FB = $80, the binary value of 80H is 10000000.
Use the or operator to specify a position 1, for example: the second bit of hexadecimal 84H is 0. To set the second bit to 1 and other bits remain unchanged, you can use: $84 or $02 = $86, 86H The binary value is 10000110.
example:
1. Set the potential of D2 bits of data port 378H to low, that is, set 0:
B:=ReadPort($378);
B:=B and $FB;
WritePort($378,B);
2. Set the potential of D2 bits of data port 378H to high, that is, set 1:
B:=ReadPort($378);
B:=B or $04;
WritePort($378,B);
3. Determine the potential of D2 bits of data port 378H:
B:=ReadPort($378);
if ((B and $04)=$04) then
// Code when the potential is high
else
// Code when the potential is low
or:
B:=ReadPort($378);
if ((B or $FB)=$FF) then
// Code when the potential is high
else
// Code when the potential is low
3. Specific implementation
The following example is the potential height of each bit of the data port 378H that controls the parallel port. The 8 bits of the data port: D0~D7 correspond to pins 2~9 of the parallel interface. For instructions on other pins of the parallel interface, please check the relevant information, so I won’t talk about it here.
First run Delphi, create a new project, and click F12 to add the code of read and write ports to Unit1 of Form1:
function ReadPort(Port:WORD):BYTE;
procedure WritePort(Port:WORD;ConByte:BYTE);
function ReadPort(Port:WORD):BYTE;
var
B:BYTE;
Begin
ASM
MOV DX, Port;
IN AL, DX;
MOV B, AL;
END;
Results:=B;
end;
procedure WritePort(Port:WORD;ConByte:BYTE);
Begin
ASM
MOV DX, Port;
MOV AL, ConByte;
OUT DX, AL;
END;
end;
Add 8 CheckBox components, modify their Caption properties to D0 to D7 respectively, and arrange them right to left.
Double-click CheckBox1 and add the following program code to the OnClick event of the CheckBox1 component:
procedure TForm1.CheckBox1Click(Sender: TObject);
var
b:BYTE;
Begin
b:=0;
if CheckBox1.Checked then
b:=b or $01;
if CheckBox2.Checked then
b:=b or $02;
if CheckBox3.Checked then
b:=b or $04;
if CheckBox4.Checked then
b:=b or $08;
if CheckBox5.Checked then
b:=b or $10;
if CheckBox6.Checked then
b:=b or $20;
if CheckBox7.Checked then
b:=b or $40;
if CheckBox8.Checked then
b:=b or $80;
WritePort($378,b); //Write data port
end;
After the input is completed, set the OnClick event of CheckBox2 to CheckBox8, the 7 CheckBox components, to the OnClick event of CheckBox1: CheckBox1Click.
At this time, compile and run the program, you can click these 8 CheckBoxes to control the potential of each bit of the LPT1 data port.
Next, the function of monitoring the data port status of the parallel port is added.
Add a Timer component in Form1: Timer1, modify its Enabled property to False and Interval property to 1.
Added to the OnTimer event in Timer1:
procedure TForm1.Timer1Timer(Sender: TObject);
var
B:BYTE;
Begin
B:=ReadPort($378); //Read data port
CheckBox1.Checked:=((B or $FE)=$FF);
CheckBox2.Checked:=((B or $FD)=$FF);
CheckBox3.Checked:=((B or $FB)=$FF);
CheckBox4.Checked:=((B or $F7)=$FF);
CheckBox5.Checked:=((B or $EF)=$FF);
CheckBox6.Checked:=((B or $DF)=$FF);
CheckBox7.Checked:=((B or $BF)=$FF);
CheckBox8.Checked:=((B or $7F)=$FF);
end;
Add a CheckBox component, and the modified Caption property is "monitor parallel port", and add it to its OnClick event:
procedure TForm1.CheckBox9Click(Sender: TObject);
Begin
Timer1.Enabled:=CheckBox9.Checked;
end;
Compile and run the program, click "Monitor Parallel Port", and you can monitor the status of the parallel port LPT1 data port 378H and modify its status in real time.
In order to facilitate viewing and verifying the status of the data port 378H, I made a small parallel port test circuit, which uses a printing interface, 8 LEDs (light emitting diodes) and 8 1K resistors. The connection circuit is shown in the figure :
After the circuit diagram is completed, install it on the parallel port of the computer, and run the written program to easily view the potential of each bit of the data port 378H.
Finally, let’s do another revolving lantern experiment.
First declare a global variable tb: add "tb:BYTE" below "Form1:TForm1":
var
Form1: TForm1;
tb:BYTE;
Then add a Timer and a CheckBox in Form1, modify the Enabled property of Timer2 to False, modify the Interval property to 300, double-click Timer2, and add it to its OnTimer event:
procedure TForm1.Timer2Timer(Sender: TObject);
var
B:BYTE;
Begin
if tb=0 then
tb:=1
else
tb:=tb * 2;
WritePort($378,tb);
B:=ReadPort($378);
CheckBox1.Checked:=((B or $FE)=$FF);
CheckBox2.Checked:=((B or $FD)=$FF);
CheckBox3.Checked:=((B or $FB)=$FF);
CheckBox4.Checked:=((B or $F7)=$FF);
CheckBox5.Checked:=((B or $EF)=$FF);
CheckBox6.Checked:=((B or $DF)=$FF);
CheckBox7.Checked:=((B or $BF)=$FF);
CheckBox8.Checked:=((B or $7F)=$FF);
end;
Modify the Caption property of CheckBox10 to "Revolving Light Demo", then double-click CheckBox10, and add it to its OnClick event:
procedure TForm1.CheckBox10Click(Sender: TObject);
Begin
Timer2.Enabled:=CheckBox10.Checked;
end;
Compile and run the program.
Click on "Revolving Lantern Demonstration", have you seen the effect of "Revolving Lantern"? By modifying Timer2's Interval, you can adjust the speed. More and more cool effects depend on your creativity.
Note: The above method of embedding assembly access to parallel ports can only be used under Win9X. To access parallel ports under WinNT/2K, you should use Windows API functions or DLLs and VXDs that are specifically read and write parallel ports.
The above program was tested and passed under Win98+Delphi6.0