۱۳۸۷ اردیبهشت ۲۹, یکشنبه

چگونه از پورت موازی (Parallel Port) استفاده کنیم C# , C++ l

چگونه از پورت موازی استفاده کنیم


مقدمه:‏
این مقاله صرفا برای استفاده عموم از پورت موازی نوشته شده و قبل مطالعه لازم ‏است نکاتی را مورد بررسی قرار دهیم:‏
- در زبانهای برنامه نویسی اعداد در هگزا اینطور
‎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;‎
‎ }‎
‎ ‎
‎ return 0; //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;‎
‎ }‎
‎ ‎
‎ return 0; //loaded succed‎
‎}‎

int main()‎
‎{‎
‎ openPortLib();‎
‎ char ch = 'f';‎
‎ bool temp = true;‎
‎ ‎
‎ while(ch != 'y' && ch != 'Y')‎
‎ {‎
‎ oup32( BASE , (temp ? 0 : 0x‎‏02‏‎) );‎
‎ 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;‎
‎ }‎
‎ ‎
‎ return 0; //loaded succed‎
‎}‎

int main()‎
‎{‎
‎ openPortLib();‎
‎ ‎
‎ while( (inp32(BASE+1) & 0x08) == 0x08 )‎
‎ {‎
‎ ‎
‎ }‎
‎}‎


دانلود سورس برنامه ها

C# and parallel port :

در این زبان هم به همین ترتیب عمل می کنیم. یعنی فایل ‏inpout32.dll را یه بارنامه پیوند می دهیم و از دو تابع :

Void Out32(int address , int value);‎

Uint Inp32(int address);‎

استفاده می کنیم. برای این کار باید ابتدا namespace به نام InteropServices را به برنامه اضافه کنیم. لذا دستور زیر را در بالای فایل برنامه اضافه می کنیم.


using System.Runtime.InteropServices;

حالا نوبت به اضافه کردن دو تابع Out32 و Inp32 می رسد. برای این کار دو دستور زیر را به برنامه اضافه می کنیم.


[DllImport("inpout32.dll", EntryPoint = "Out32")]
public static extern void Output(int adress, int value); //imports Out32 as name Output
[DllImport("inpout32.dll", EntryPoint = "Inp32")]
public static extern void Input(int adress); //imports Inp32 as name Input

توجه داشته باشید که شما با این روش می توانید در هنگام تعریف تابع خارجی هر نامی را که می خواهید به تابع اختصاص دهید. همانطور که در اینجا برای Out32 نام Output در نظر گرفته شده و برای Inp32 نام Input .

مثال زیر را انلود کنید ، با بررسی برنامه نکات ابهام برطرف می شود. ان شاء الله

این برنامه 8 عدد LED که به پورت دیتا وصل شده اند را خاموش و روشن می کند و یک رقص نور ساده است. همچنین برای مثال ورودی نیز پایه 10 پورت پرینتر که همان بیت 7 از رجیستر status را چک می کند و اگر 1 بود دکمه مربوطه قرمز رنگ و اگر 0 بود آبی رنگ می شود.

دانلود برنامه به زبان C#

۲ نظر:

diana_682000@yahoo.com گفت...

سلام میشه درمورد 7-segها هم مثال بزنید مثلا 7seg ای که اعداد یا حروف رو نشون بده تو رو خدا خیلی ضروریه اگه لطف کنین ممنون میشم

ناشناس گفت...

نظرات و اعتقادات هر کسی قابل احترامه ولی به نظر من جای اون عکسی بالای صفحه قرار داده شده و به مهندس موسوی علنا داره توهین میکنه به نظر من تو یک وبلاگ علمی نیست. بیایید همونقدر که برای الکترونیک وقت میگذاریم , به دور از هر تعصب و هر تاثیرپذیری از تبلیغات جناحی واقعا به حرفها و خواسته های این شخص هم کمی فکر کنیم و ببینیم چیزی که میگه آیا به ضرر ملت هست و یا به نفع اونها.