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