1. 병렬포트의 구조
그림 1 프린터 포트의 외형도
1, 14, 16, 17번은 input도 되고 output도 된다는 것을 알 수 있다.
그래서 여기서는 1, 14, 16, 17번은 사용을 안 하기로 한다.
OUTPUT |
2, 3, 4, 5, 6, 7, 8, 9 |
INPUT |
10, 11, 12, 13, 15 |
IN/OUT |
1, 14, 16, 17 |
GND |
18, 19. 20, 21, 22, 23, 24, 25 |
표 1 프린터 포트의 핀 종류
2. 병렬포트의 출력
병렬 테스트를 하기 위해 간단히 회로를 꾸며 보자. 아래의 회로도처럼 꾸민다.
그림 2 프린터 포트 입력 테스트를 위한 회로도
회로도가 완성되면, PC 쪽에서 프린터 포트를 제어 해야 한다.
VC++를 사용해서 제어 하겠다. (C 보다는 VC++ 이 편하다.)
Dialog Based 로 한 다음, 버튼을 하나 만들고, 그 버튼 메시지 아래와 같은 코드를 입력
for(int i=0;i<256;i++) {
_outp(0x378,i);
for(int j=0;j<10000;j++);
} |
그리고 버튼을 누르면 병렬포트에 연결시켰던 LED들이 우르르~ 켜지는 것을 볼 수 있다.
(하지만, win2000 이상에서는 잘 안될 것이다.)
그래서 다른 방법을 써야 한다. 라이브러리를 사용해야 한다.
라이브러리를 사용하면 2000 이하의 버전에서도 사용이 가능하므로, 라이브러리를 사용해서 하는게 좋을 것이다. (나중에 자세히 설명한다.)
파일은 자료실에 있다.
_outp(0x378,i); 함수에서,
0x378은 LPT1일때 즉 프린터포트의 주소이고, 그 뒤의 값은 데이터 값이다.
즉, 2번부터 9번까지(Data0 부터 Data7까지)데이터를 출력해 준다.
예를들어, _outp(0x378,9)라고 했다면,
9는 2진수로 1001이므로 2번핀과 5번핀이 HIGH 로 된다.
cf. 라이브러리를 이용한 제어
http://www.driverlinx.com/ 에 자세한 설명이 있고,
라이브러리를 제작, 배포하는 곳이다. 다운 받으려면 가입을 해야 하지만
http://www.driverlinx.com/DownLoad/DlPortIO.htm 여기에서 그냥 받을 수 있다.
또는 자료실 (http://rtcontrol00.ee.hallym.ac.kr ) 에 있다.
port95nt.exe Port I/O Driver (1,573k)
를 다운 받아 설치한다. 다 끝나면 (꼭 리붓을 해야 한다.)
그림 3 생성된 단축 아이콘
그림의 C++ PortIO 를 실행하면
그림 4 실행초기 화면 |
그림 5 프린터 포트를 쓰는 화면 |
프린터 포트를 쓰는 그림에서 Write 를 누르면 프린터 포트에 데이터를 쓰는 것이다.
0x378 은 프린터 포트를 쓰는 주소이고, 0은 데이터 이다.
즉 프린터 포트에 0을 쓰는 것이다.
값을 읽을 때에는 Read 를 누르면 된다.
일단 여기서 에러 없이 잘 되면, 프린터 포트 제어에 문제가 없는 것이다.
이제 자신의 코드를 만들어 보자. VC6.0++ 을 이용하겠다.
VC++로 라이브러리 추가하여 프로그램 짜기
다이러로그 방식으로 프로그램을 짜서 버튼을 만들고 메시지를 연결한다.
라이브러리를 연결해야 하는데,
우선, 라이브러리를 사용할 폴더로 복사한다. [ Dlportio.h 파일과 Dlportio.lib 파일 ]
설치된 폴더에서 API 폴더에 있다.
그리고, 라이브러리를 연결하고, 헤더파일을 추가한다.
(VC++ 에 대한 설명은 생략한다.)
그리고 코드를 연결한다.
void CPTESTDlg::OnButton1() {
for(int i=0;i<256;i++) {
DlPortWritePortUchar(0x378,i);
Sleep(1);
}
}DlPortWritePortUchar() 함수는 포트에 값을 쓰는 함수이다.
함수를 알아보려면 Dlportio.h 를 열어 보기 바란다.(절대 수정하지는 말고 ^^;; )
그리고 버튼을 누르면 LED 가 빠르게 깜빡거릴 것이다.
dlportio.h 파일을 보면 다음과 같은 함수가 있다.
<Read 함수>
DlPortReadPortUchar(IN ULONG Port);
DlPortReadPortUshort(IN ULONG Port);
DlPortReadPortUlong(IN ULONG Port);
DlPortReadPortBufferUchar(IN ULONG Port,IN PUCHAR Buffer,IN ULONG Count);
DlPortReadPortBufferUshort(IN ULONG Port,IN PUSHORT Buffer,IN ULONG Count);
DlPortReadPortBufferUlong(IN ULONG Port,IN PULONG Buffer,IN ULONG Count);
<Write 함수>
DlPortWritePortUchar(IN ULONG Port,IN UCHAR Value);
DlPortWritePortUshort(IN ULONG Port,IN USHORT Value);
DlPortWritePortUlong(IN ULONG Port,IN ULONG Value);
DlPortWritePortBufferUchar(IN ULONG Port,IN PUCHAR Buffer,IN ULONG Count);
DlPortWritePortBufferUshort(IN ULONG Port,IN PUSHORT Buffer,IN ULONG Count);
DlPortWritePortBufferUlong(IN ULONG Port,IN PULONG Buffer,IN ULONG Count);
뒤에 붙은 char(1byte), short(2byte), long(4byte) 은 데이타 타입이다.
자주 사용하는 함수는 DlPortReadPortUchar(), DlPortWritePortUchar() 이고, 바이트 단위로 통신하는 것이다.
이제부터 라이브러리를 사용한다고 가정하고 설명하겠다.
3. 병렬포트의 입력
parallel port를 통해 입력을 받아보기 위해 회로를 꾸미자.
그림 6 입력과 출력 회로도
주의 사항
최상위 비트는 11번이다.
11번,10번,12번,13번,15번 순이다. 주의 요
입력 버튼을 만들고, 코드를 넣자.
void CPTESTDlg::OnButton2() {
int a=DlPortReadPortUchar(0x379);
m_strData.Format("%x",a);
UpdateData(FALSE);
}
테스트를 해 보면 11번(최상위) 핀은 반전되어서 나오는 것을 알수 있다.
( 뒤쪽의 3비트는 I/O 공동으로 사용한 데이터 같은데 뭔지 모르겠음)
입력 값 |
PC 에서 읽은 값 |
1111 1XXX |
0111 1XXX |
0000 0XXX |
1000 0XXX |
1010 1XXX |
0010 1XXX |
0110 0XXX |
1110 0XXX |
실시간으로 프린트 포트로부터 입력 받기
약간의 C++ 지식이 필요하다.
일단 소스를 보면
void CPTESTDlg::OnButton2() {
// 실시간으로 프린터 포트의 입력 값을 읽어서 화면에 보여줌
while(1){
MSG msg;
while(::PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)){
switch(msg.message){
case WM_QUIT:
case WM_DESTROY:
case WM_CLOSE:
PostQuitMessage(0);
return ;
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
int a=DlPortReadPortUchar(0x379);
m_strData.Format("%x",a);
UpdateData(FALSE);
}
} |
그리고 종료 할 때,
PostQuitMessage(0);
를 꼭 해주어야 한다. 그렇지 않으면 리소스를 반납하지 않기 때문에, PC 가 느려진다.
꼭 리소스가 제대로 반납되는지 확인 하기 바란다.
<참고> ECP , EPP 모드에 관해
하이텔 :신동익 (kbread )님께서 쓰신 글입니다.
안녕하세요.
프린터포트로 뭔가를 하려는 분이 많이 계신가본데,제가 얼마 전에 인터넷에서
자료를 좀 구했습니다.
보통 centronics라고 불리우는 일반적인 프린터 포트 방식으로는 4bit의 데이타를 그것도 출력으로만 사용할 수 있지요.
최근에는 외장 하드디스크나 zip drive 등 대용량, 고속으로 동작하는 외부기기를 프린터포트에 접속하여 사용하는 경우가 늘고 있습니다. 따라서 병렬포트(프린터 포트보다 치기가 쉬워서)도 기존의 규격으로는 부족한 감이 있지요.
그래서 기존의 모드를 그대로 지원하면서, 고속의 확장모드를 지원할 수 있도록 새로운 규격의 병렬포트가 등장한 겁니다. 이른바 EPP, ECP라는 것 말입니다.
EPP는 Enhanced Parallel Port의 약자로서 프린터를 제외한 고속, 대용량(외장 하드, 캐너 등)의 외부기기를 지원하는 모드입니다. 8bit의 데이타 버스를 양방향으로 이용할 수 있습니다.
ECP는 Extended Compatibility Port의 약자로서 프린터로의 데이타 전송을 고속화 하려는 목적으로 고안된 것입니다. 마찬가지로 8bit의 양방향 통신을 할 수 있습니다. 최근의 레이저 프린터들은 대개 이 모드를 지원합니다.
또한 이러한 모드를 이용하기 위해서는 PC에 이 모드를 지원하는 병렬포트가 장착되어 있어야 하는데, PC의 부팅 시 cmos setup에 들어가서 지원여부를 확인할 수 있습니다. setup menu에서 communication port쪽을 살펴보면, com1은 어쩌구, com2는 저쩌구, lpt1은 어쩌구 에서 LPT부분의 메뉴를 변경해 보면 normal, ECP, EPP, ECP+EPP등이 나타나면 이게 지원되는 보드입니다.
ECP 모드에서의 전송 속도는 500Kbyte/sec에서 최대 2MByte/sec까지 가능합니다.
이 정도의 속도라면 보통 ISA bus에 인터페이스 한 것과 거의 대등한 속도라고 봅니다. 그리고 프로토콜도 매우 간단해서 프린터포트 인터페이스를 해 보신 분이라 면 누구나 쉽게 할 수 있습니다.
보다 자세한 규격은 인터넷주소 http://www.fapo.com/ieee1284.htm에 있습니다.
참고로 ECP, EPP를 지원하는 병렬포트 규격을 IEEE1284라 합니다.