چگونه از پورت موازی استفاده کنیم
مقدمه:
این مقاله صرفا برای استفاده عموم از پورت موازی نوشته شده و قبل مطالعه لازم است نکاتی را مورد بررسی قرار دهیم:
- در زبانهای برنامه نویسی اعداد در هگزا با فورمت
0xNNNN نوشته میشوند. برای مثال :
0xa30b , 0x55bfa , 0x2ab25 , …
- در رایانه ها فضای حافظه شامل چندین بخش است که بخشی از آن مربوط به ارتباط با سخت افزار است که به آن فضای پورتها می گویند. یعنی ثباتهایی که در این محدوده هستند برای ذخیره اطلاعات نیستند این ثباتها در داخل BIOS و یا سایر آی سی های سیستم وجود دارند. به وسیله این ثباتها می توان سیستم را Over Clock کرد یا ساعت وتاریخ آن را تغییر داد ، رایانه را Restart کرد و ... . در محیط ویندوز به دلیل مسائل امنیتی دسترسی مستقیم به فضای پورتها ممکن نیست به همین دلیل از توابعی مانند Inp32 و Out32 برای دسترسی به این رجیستر ها استفاده می کنیم.این توابع در فایل inpout32.dll وجود دارند.
- توجه کنید که به این رجیستر ها به دلیل این که ارتباط میان برنامه و سخت افزار را میسر می سازند ، پورت گفته می شود. مثلا رجیستر شماره 0x378 را پورت 0x378 می نامند.
Void Out32(int address , int value);
Uint Inp32(int address);
توجه داشته باشید که درست است که این دو تابع مقدار محتوای پورت ( ثبات یا همان رجیستر ) مورد نظر را به صورت int که چهار بایتی است رد و بدل می کنند اما فقط بایت کوچکتر مورد استفاده است و سه بایت دیگر برای تابع بی استفاده است.
پورت موازی چیست؟
این پورت در ابتدا فقط برای پرینتر های IBM روی کامپیوتر ها اظافه شد. اما با ورود پورت سریال و USB اکنون سالهای آخر عمر خود را سپری می کند و هم اکنون روی سیستم های پیشرفته نصب نمی شود. اما برای ساخت پروژه های کوچک مرتبت با رایانه ساده ترین و ارزانترین گزینه است.
همان طور که در شکل می بینید این پورت دارای 25 پایه است که 8 تای آن بدون استفاده و به زمین متصل اند.بقیه پایه ها سه گروهند:
الف) پایه های خروجی (Data Out)
شامل پایه های ( 2-9 ) می شود.در اغلب رایانه ها فقط خروجی اند و به عنوان ورودی نمی توان از آنها استفاده کرد. این پایه ها از نوع آی سی های TTL هستند و در حالت اتصال کوتاه جریانی تا 100mA را می هند.
این پایه ها به وسیله ثبات شماره ( 0x378 ) رایانه ها قابل دسترسی هستند (البته ممکن است در گروهی از رایانه ها شماره این ثبات فرق کند). ارتباط بیت های این ثبات با پایه های پورت در شکل نمایش داده شده است.
ب)پایه های ورودی ( Status )
شامل پایه های ( 10،11،12،13،15 ) می شود.این گروه از پایه ها فقط ورودی اند یعنی فقط می توان اطلاعات این پایه ها را خواند. این پایه ها به وسیله
ثبات شماره ( 0x379 ) رایانه ها قابل دسترسی هستند (البته ممکن است در گروهی از رایانه ها شماره این ثبات فرق کند).این پایه ها در حالت باز با یک مقاومت 1K به VCC متصل شده اند.ارتباط بیت های این ثبات با پایه های پورت در شکل نمایش داده شده است.
ج)پایه های ورودی و خروجی ( Control )
شامل پایه های ( 10،11،12،13،15 ) می شود.این گروه از پایه ها فقط ورودی اند یعنی فقط می توان اطلاعات این پایه ها را خواند. این پایه ها به وسیله
ثبات شماره (0x37a ) رایانه ها قابل دسترسی هستند (البته ممکن است در گروهی از رایانه ها شماره این ثبات فرق کند).این پایه ها در حالت باز با یک مقاومت 1K به VCC متصل شده اند.مقدار صفر ویک این پایه ها را هم می توان خواند و هم می توان آن را نوشت.
آدرس پورت
پیش از این گفتیم آدرس پورت مورد نظر در فظای رایانه ممکن است در بعضی از رایانه ها تفاوت کند اما باید بدانیم که ترتیب این آدرس ها همواره یکی است. یعنی رجیستر خروجی Data در ابتدا بعد از آن Status یا همان ورودی ها و بعد از آن هم Control یا همان خروجی ها.
آدرس آغاز دسترسی به رجیستر را Base address می نامیم و حالا به جداول زیر دقت کنید:
آدرس پورت در رایانه شما
به مسیر زیر مراجعه کنید :
Control Panel / System / Hardware / Device Manager / Ports (Com & LPT) / ECP Printer port / Resources.
در این پنجره لیستی وجود دارد که آدرس رجیسترهای کامپیوتر شما را نشان می دهد. رایانه من دارای دو BaseAddress برای دسترسی به پورت موازی (LPT)است که با I/O Range نشان داده شده است.یکی از 0x378 – 0x37f و دیگری از 0x778 – 0x77b البته هر دوی این آدرس ها به یک پورت متصل اند.اگر در رایانه شما چنین پنجره ای وجود ندارد برنامه port95ntرا دانلود و نصب کنید.
پروژه اول:
خاموش روشن کردن چراغ با پورت موازی
این برنامه درون کامپایلر Dev-C++ کار می کند و به احتمال زیاد در بقیه کامپایلر ها هم همین طور.
ابتدا باید فایل inpout32.Dll را به برنامه اضافه کنیم.
#include
/* prototype (function typedef) for DLL function Inp32: */
typedef short _stdcall (*inpfuncPtr)(short portaddr);
typedef void _stdcall (*oupfuncPtr)(short portaddr, short datum);
HINSTANCE hLib;
inpfuncPtr inp32;
oupfuncPtr oup32;
int openPortLib()
{
/* Load the library */
hLib= LoadLibrary("inpout32.dll");
if(hLib == NULL)
return-1;
/* get the address of the function */
inp32 = (inpfuncPtr) GetProcAddress(hLib, "Inp32");
if(inp32 == NULL) {
return-2;
}
oup32 = (oupfuncPtr) GetProcAddress(hLib, "Out32");
if(oup32 == NULL) {
return-3;
}
return0; //loaded succed
}
int main()
{
openPortLib();
}
اگر از تابع openPortLib و Typedefine ها سر در نیاوردید نگرا نباشید من هم چیزی نفهمیدم. فقط میدانیم از این به بعد در برنامه ما دو تابع inp32 برای خواندن از رجیستر ها و ou32 برای نوشتن در رجیسترها وجود دارند. با ید توجه کنید که قبل از استفاده از این دو تابع تابع openPortLib را یکبار در آغاز برنامه فراخوانی کنید و همجنین فایل inpout32.dll را در مجاورت فایل اجرایی برنامه تان یا در پوشه system32 کپی کنید.
حالا کار را شروع می کنیم.قرار است برنامه با پس از هر بار فشار دادن کلیدها یک LED را که به پایه شماره 3 متصل است را برعکس کند یعنی اگر خاموش است ، روشن و اگر روشن است ، خاموش کند و با زدن دکمه y برنامه بسته شود.
#include
#include
#define BASE 0x378
/* prototype (function typedef) for DLL function Inp32: */
typedef short _stdcall (*inpfuncPtr)(short portaddr);
typedef void _stdcall (*oupfuncPtr)(short portaddr, short datum);
HINSTANCE hLib;
inpfuncPtr inp32;
oupfuncPtr oup32;
int openPortLib()
{
/* Load the library */
hLib= LoadLibrary("inpout32.dll");
if(hLib == NULL)
return-1;
/* get the address of the function */
inp32 = (inpfuncPtr) GetProcAddress(hLib, "Inp32");
if(inp32 == NULL) {
return-2;
}
oup32 = (oupfuncPtr) GetProcAddress(hLib, "Out32");
if(oup32 == NULL) {
return-3;
}
return0; //loaded succed
}
int main()
{
openPortLib();
char ch = 'f';
bool temp = true;
while(ch != 'y' && ch != 'Y')
{
oup32( BASE , (temp ? 0 : 0x02) );
ch= getch();
temp= !temp;
}
}
پروژه دوم:
برنامه ای که با زدن کلیدی بسته شود
این برنامه درون حلقه ای قرار می گیرد و با اتصال کوتاه کردن پایه 15 از پورت به زمین یا همان بدنه و در حقیقت صفر کردن این پایه از نظر منطقی از حلقه خارج می شود.پایه 15 بیت سوم از رجیستر Status (BASE+1) است و معکوس هم نشده.
#include
#include
#define BASE 0x378
/* prototype (function typedef) for DLL function Inp32: */
typedef short _stdcall (*inpfuncPtr)(short portaddr);
typedef void _stdcall (*oupfuncPtr)(short portaddr, short datum);
HINSTANCE hLib;
inpfuncPtr inp32;
oupfuncPtr oup32;
int openPortLib()
{
/* Load the library */
hLib= LoadLibrary("inpout32.dll");
if(hLib == NULL)
return-1;
/* get the address of the function */
inp32 = (inpfuncPtr) GetProcAddress(hLib, "Inp32");
if(inp32 == NULL) {
return-2;
}
oup32 = (oupfuncPtr) GetProcAddress(hLib, "Out32");
if(oup32 == NULL) {
return-3;
}
return0; //loaded succed
}
int main()
{
openPortLib();
while( (inp32(BASE+1) & 0x08) == 0x08 )
{
}
}
منبع