2009년 06월 04일
델파이로 병렬포트 이용하기...
어제 병렬포트에서 RF 센서의 입력을 받아야 하는 상황이 있었습니다.
그런데...포트를 읽을 때마다 255 (=0xFF, 0b11111111) 이더군요.
입력이 없는 Floating 상태에서는 내부적으로 풀업되어 있으니 255 가 나오는 것은 맞는데
2번핀을 25번핀에 연결했을 때는 254가 나와야 하는데 255 라서 곤란했습니다.
(병렬포트의 2번~9번 핀은 데이터 D0~D7 입니다., 18~25번 핀은 Ground 입니다.
2번핀을 25번핀에 연결하면
D7 D6 D5 D4 | D3 D2 D1 D0
1 1 1 1 1 1 1 0 = 0b11111110 = 0xFE = 254
가 되어야 합니다.)
어제는 급해서...STROBE 핀을 이용해서 입력을 받았습니다. 날새고 한참 자고 일어나서 지금 책을 찾아보고 이유를 알았습니다.
병렬포트는 Control 포트를 이용하여 병렬 포트를 제어합니다. Data 포트의 입출력 방향도 바꿉니다.
C5 = 0 이면 Output 이고 C5 = 1 이면 Input 입니다.
따라서 Data 포트로 입력을 받으려면 C5에 1을 출력하고 Data 포트를 읽어야 했던 것입니다.
다음은 델파이 7에서 io.dll 을 이용해서 병렬포트를 통해 값을 출력하거나 입력받는 프로그램입니다.
io.dll 말고 다른 라이브러리를 사용할 경우 dll 참조부분과 함수 이름만 수정하시면 됩니다.
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const DATA1 = $378;
const DATA2 = $278;
const STATUS1 = $379;
const STATUS2 = $279;
const CONTROL1 = $37A;
const CONTROL2 = $27A;
type
TForm1 = class(TForm)
btRead: TButton;
Memo1: TMemo;
edWriteValue: TEdit;
btWrite: TButton;
cbxSelPort: TComboBox;
procedure btReadClick(Sender: TObject);
procedure btWriteClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure PortOut(Port : Word; Data : Byte); stdcall; external 'io.dll';
function PortIn(Port:Word):Byte; stdcall; external 'io.dll';
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btReadClick(Sender: TObject);
var
iTmpDataPort: Integer;
iTmpControlPort: Integer;
byInValue: Byte;
begin
if cbxSelPort.Text = '0x378' then begin
iTmpDataPort := DATA1;
iTmpControlPort := CONTROL1;
end;
if cbxSelPort.Text = '0x278' then begin
iTmpDataPort := DATA2;
iTmpControlPort := CONTROL2;
end;
PortOut(iTmpControlPort, $2D);
byInValue := PortIn(iTmpDataPort);
PortOut(iTmpControlPort, $00);
Memo1.Lines.Add(IntToStr(byInValue));
end;
procedure TForm1.btWriteClick(Sender: TObject);
var
iTmpDataPort: Integer;
iTmpControlPort: Integer;
iOutValue: Integer;
begin
if cbxSelPort.Text = '0x378' then begin
iTmpDataPort := DATA1;
iTmpControlPort := CONTROL1;
end;
if cbxSelPort.Text = '0x278' then begin
iTmpDataPort := DATA2;
iTmpControlPort := CONTROL2;
end;
if TryStrToInt(edWriteValue.Text, iOutValue) then begin
if (0 <= iOutValue) AND (iOutValue <= 255) then
PortOut(iTmpDataPort, iOutValue)
else begin
ShowMessage('병렬포트로 출력하실 값의 범위는 0부터 255까지 입니다.');
edWriteValue.SetFocus;
exit;
end;
end
else begin
ShowMessage('병렬포트로 출력하실 값은 0부터 255까지 입니다.');
edWriteValue.SetFocus;
exit;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
end;
end.
위 소스는 잠에서 깨어 책보고 바로 만든 것입니다. 그래서 맘에 안드는 구석이 많은...깔끔해 보이지 않는 그런 소스입니다...만,
기능적으로 큰 문제는 없습니다.
...회사에서 사용할 때는 좀 더 이쁘게 다듬겠지요...;
배열도 쓰고 하드웨어 자원도 검색하고...등등...;;
아니면 병렬포트를 이용하는 컴포넌트라도 찾아서 사용하겠지요...;;;
여튼, 제가 네이버와 델코에서 엉뚱한 답때문에 삽질한 것이 억울해서 올립니다. 알고보면 아무것도 아닌데 찾아보면 찾기 힘들거나 찾아도 틀린 정보가 많은...그런 것이었습니다.
다른 분들은 저처럼 삽질하지 않으시기를...
# by | 2009/06/04 00:08 | 델파이 | 트랙백 | 덧글(3)




☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
근데 연락처가 읍네요 ㅠㅜ