用Visual Basic完成對(duì)系統(tǒng)I/O端口的設(shè)置
發(fā)表時(shí)間:2024-06-14 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]文/easypower 同時(shí)需要說明的是,_inp和_outp函數(shù)和inp和outp函數(shù)用法基本上相同,只是在使用時(shí)需要頭文件,而且本人推薦使用_inp和_outp,而不是使用inp和outp。因?yàn)開inp和_outp在Debug和Release都可以使用,而inp和outp只能用于Releas...
文/easypower
同時(shí)需要說明的是,_inp和_outp函數(shù)和inp和outp函數(shù)用法基本上相同,只是在使用時(shí)需要頭文件,而且本人推薦使用_inp和_outp,而不是使用inp和outp。因?yàn)開inp和_outp在Debug和Release都可以使用,而inp和outp只能用于Release設(shè)置。如果在Debug設(shè)置時(shí)使用inp和outp,編譯時(shí)不會(huì)錯(cuò),但會(huì)產(chǎn)生鏈接錯(cuò)誤。
一、Visual Basic中操作I/O端口
到此我們就可以在Visual Basic中通過動(dòng)態(tài)鏈接庫技術(shù)間接操作I/O端口了。在Visual Basic中動(dòng)態(tài)鏈接庫必須提前申明,其缺省為公有過程或函數(shù)。其格式為:“Declare Sub過程名Lib‘庫名’[Alias‘別名’] [(參數(shù)表)]”,或者“Declare Function過程名Lib‘庫名’[Alias‘別名’] [(參數(shù)表)] As類型”。例如:
Public Declare Function Outport Lib "vcDll.dll" (ByVal portid As Integer, ByVal value As Integer) As Integer //IO輸出函數(shù)
Public Declare Function Inport Lib "vcDll.dll" (ByVal portid As Integer) As Integer //IO輸入函數(shù)
這樣定義后在程序中就可以直接使用上面定義的函數(shù)或過程來操作I/O端口了。
二、Visual Basic中位操作
上文介紹的I/O端口操作是一次從I/O端口中讀取一個(gè)后更多字節(jié)的信號(hào),而在工業(yè)控制領(lǐng)域中,往往是逐個(gè)信號(hào)的獲取或操作,因此我們就有必要在讀入信號(hào)時(shí)將一次讀到的信號(hào)分離開來,而在輸出信號(hào)時(shí)將不需要輸出的其它位屏蔽掉。
1.分離讀取到的I/O端口信號(hào)(需要讀取D0位信號(hào))
IOvalue=Inport(BASE)//首先讀取BASE地址I/O端口信號(hào)
IOvaluer=IOvalue AND &1H// (屏蔽掉其他7位,只留下D0位)
2.屏蔽其它位信號(hào)并輸出相應(yīng)信號(hào)(D0位置1操作)
IOvalue=Inport(BASE)//首先讀取BASE地址I/O端口信號(hào)
IOvalue = IOvalue OR &01H //(B00000001,屏蔽掉其他7位,將D0位置1)
CALL Outport(BASE,IOvalue)//輸出相應(yīng)信號(hào)
在上面的位操作中,我們用到了邏輯運(yùn)算符AND和OR,邏輯分析表如下。
AND 1 0
1 1 0
0 0 0
OR 1 0
1 1 1
0 1 0
使用AND運(yùn)算符可以對(duì)指定的位置0,例如:十六進(jìn)制&H84的二進(jìn)制為:10000100,它的第三位為1,若要將第三位置為0,且其它位不變,可以使用:&H84 AND &HFB = &H80,&H80的二進(jìn)制值為B10000000。
使用OR運(yùn)算符可以對(duì)指定的位置1,例如:十六進(jìn)制&H84的第二位為0,若要將第二位置為1,且其它位不變,可以使用:&H84 OR &H02 = &H86,&H86的二進(jìn)制值為B10000110。
三、使用計(jì)算機(jī)LPT打印口做I/O端口
打印口有3個(gè)端口:數(shù)據(jù)端口、狀態(tài)端口和控制端口,常用的打印口為L(zhǎng)PT1,它的3個(gè)端口的地址分別為:378H、379H和37AH。其中378H和37AH可讀可寫,而379H為只讀端口。
與使用其他I/O卡一樣,在運(yùn)行DEBUG環(huán)境下,對(duì)打印口的各位進(jìn)行檢測(cè)如下。
378H作數(shù)據(jù)輸出口。鍵入指令–O 378 00(01,02,04,08,10,20,40,80,F(xiàn)F),同時(shí)用萬用表分別檢測(cè)2~9腳的電壓(25腳接萬用表“地”),可分別測(cè)到對(duì)應(yīng)位與所輸入的數(shù)據(jù)相符合(”1”對(duì)應(yīng)5V,”0”對(duì)應(yīng)0V)。說明此地址的8位可作為8個(gè)輸出線。
379H作輸入端口。為了給各腳提供輸入電平,我們先引入一個(gè)外部5V電源。電源地線接打印口的25腳,而后分別在10,11,12,13,15腳接入5V、0V,同時(shí)在DEBUG環(huán)境下執(zhí)行-I 379指令,讀入此端口的數(shù)據(jù)。讀到的各數(shù)據(jù)應(yīng)與輸入信號(hào)相符合。
37AH口只能作輸出口。檢測(cè)方法與378H相同。
檢測(cè)結(jié)果為:
378各位輸出電平和指令信號(hào)一致,D0~D8位都可以做端口輸出位;
37A各位輸出電平和指令信號(hào)相反,D0~D3位都可以做端口輸出位;
379各位懸空狀態(tài)下:11腳為“0”,10,12,13,15為“1”,故使用D3~D6做端口輸入位。
綜上,通常使用打印口做I/O端口的共有12個(gè)輸出位和4個(gè)輸入位。
四、Windows 2000/XP/NT下I/O端口操作
Windows 2000/XP/NT對(duì)硬件實(shí)現(xiàn)了屏蔽,對(duì)I/O端口進(jìn)行了嚴(yán)格的控制,許多在Windows 9x下正常運(yùn)行的用戶應(yīng)用程序,在Windows 2000/XP/NT中直接訪問硬件會(huì)引起系統(tǒng)異常,因此不能在Windows 2000/XP/NT下直接訪問I/O端口。
通常有兩種方法解決Windows 2000/XP/NT下I/O端口操作問題,一是編寫一個(gè)運(yùn)行在RING0級(jí)(設(shè)備驅(qū)動(dòng)驅(qū)動(dòng)程序級(jí))的虛擬設(shè)備驅(qū)動(dòng)程序(Virtual X Device,VSD),它可以不受限制地訪問硬件設(shè)備、捕獲I/O端口操作和內(nèi)存訪問等,甚至可以截獲硬件中斷,這樣就可以在USER方式下實(shí)現(xiàn)Windows 2000/XP/NT下I/O端口的訪問操作。另一種方法就是修改I/O允許位圖設(shè)置,允許一個(gè)特定的任務(wù)存取特定的I/O端口。這允許USER方式的程序在RING3級(jí)(應(yīng)用程序級(jí))按照I/O允許位圖設(shè)置,不受限制地訪問I/O端口。
接下來本文介紹兩種在Windows 2000/XP/NT下實(shí)現(xiàn)I/O端口操作的方法,WinIO和PortTalk。
WinIO程序庫通過使用一種內(nèi)核模式的設(shè)備驅(qū)動(dòng)器和其它幾種底層編程技巧,繞過了Windows系統(tǒng)的保護(hù)機(jī)制,從而允許在Windows 2000/XP/NT下應(yīng)用程序直接對(duì)I/O端口和物理內(nèi)存進(jìn)行操作。需要注意的是,在Windows 2000/XP/NT下,WinIO函數(shù)庫只允許被具有管理員權(quán)限的應(yīng)用程序調(diào)用。WinIO程序庫含有相應(yīng)驅(qū)動(dòng)程序的源代碼和Visual BASIC例程,下載地址為:www.internals.com/utilities/winio.zip。
PortTalk使用的是上述的第二種方法,它夠讓你現(xiàn)有的程序運(yùn)行在windows 2000/XP/NT下,但是需要注意的是,因?yàn)楸仨氃赗ING0和RING3下來回切換,所以使用PortTalk會(huì)降低程序的運(yùn)行效率。PortTalk設(shè)備驅(qū)動(dòng)程序也提供了全部源代碼,下載地址為:www.beyondlogic.org/porttalk/porttalk.zip。