一、i/o埠介紹
訊號採集與控制是工業控制的最重要組成部分。在工業控制中,通常採集到的訊號有兩類:一類是電壓或電流模擬訊號;另一類是開關量或數字脈衝量(開關量、脈衝量都屬於數碼訊號)。通常檢測出的訊號如果是模擬量的話,必須經過放大、變換變為電壓0~10伏或電流0~10ma,這些模擬量必須經過模/數轉換器(adc:analog-digital cnverter)轉換成數字量, 才能被計算機所接受。同樣輸出控制量訊號也必須是數碼訊號,得經過數/模轉換器(dac:digital-analog cnverter),將數碼訊號轉換成模擬訊號0~10伏 (或0~+5伏)或變為電流0~10ma, 再送入到控制器去控制生產裝置的執行。
而在計算機中,cpu通過匯流排與輸入輸出裝置相連。系統中的很多其他裝置都要通過匯流排,按照cpu規定的時序分時地與cpu進行指令或資料的傳輸。因此輸入輸出裝置不能直接與匯流排相連並占用匯流排,i/o埠就是在匯流排和輸入輸出裝置之間進行資料交換的資料中轉站,我們與輸入輸出裝置的對話實際上是與i/o埠的對話,下面就詳細講述在visual basic環境下如何進行輸出和輸入操作。
二、編寫操作i/o埠的動態鏈結庫函式
visual basic沒有提供直接讀寫i/o埠的方法,所以只能借助其他語言來編寫動態鏈結庫dll(dynamic link library)或vxd,然後再在visual basic中呼叫。因此我們不得不先了解如何編寫操作i/o埠的動態鏈結庫函式。
1.在組合語言中,可以用 in、out 指令操作i/o埠,具體示例如下:
輸入操作:
mov dx, port;port為埠號
in al, dx;讀入埠資料到al暫存器
輸出操作:
mov dx, port;port為埠號
mov al, conbyte;conbyte為控制字,將控制字送到al暫存器
out dx, al;送出控制字到埠
2.在c/c++中,通常用inp和_outp函式操作i/o埠,編寫動態鏈結庫我們可以編寫如下兩個函式,並把它編譯生成dll:
/*作用:從指定埠讀入乙個位元組,引數:portid埠號,返回值:讀入的位元組*/
int _stdcall inport(short portid)
/*作用:向指定埠寫入乙個位元組,引數:portid埠號*/
void _stdcall outport(short portid,short value)
當需要一次操作兩個位元組時,我們就必須用到inpw和outpw兩個函式,具體用法同inp和outp。
同時需要說明的是,_inp和_outp函式和inp和outp函式用法基本上相同,只是在使用時需要標頭檔案,而且本人推薦使用_inp和_outp,而不是使用inp和outp。因為_inp和_outp在debug和release都可以使用,而inp和outp只能用於release設定。如果在debug設定時使用inp和outp,編譯時不會錯,但會產生鏈結錯誤。
三、visual basic中操作i/o埠
到此我們就可以在visual basic中通過動態鏈結庫技術間接操作i/o埠了。在visual basic中動態鏈結庫必須提前申明,其預設為公有過程或函式。其格式為:「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埠中讀取乙個後更多位元組的訊號,而在工業控制領域中,往往是逐個訊號的獲取或操作,因此我們就有必要在讀入訊號時將一次讀到的訊號分離開來,而在輸出訊號時將不需要輸出的其它位遮蔽掉。
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個埠:資料埠、狀態埠和控制埠,常用的列印口為lpt1,它的3個埠的位址分別為:378h、379h和37ah。其中378h和37ah可讀可寫,而379h為唯讀埠
計算機25針列印口各引腳定義如下圖所示。
此主題相關如下:
^^^^^^^^^^^^^^^(丟了!)
與使用其他i/o卡一樣,在執行debug環境下,對列印口的各位進行檢測如下。
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環境下執行 -i 379指令,讀入此埠的資料。讀到的各資料應與輸入訊號相符合。
37ah口只能作輸出口。檢測方法與378h 相同。
檢測結果為:
378各位輸出電平和指令訊號一致,d0~d8位都可以做埠輸出位;
37a各位輸出電平和指令訊號相反,d0~d3位都可以做埠輸出位;
379各位懸空狀態下:11腳為「0」,10,12,13,15為「1」,故使用d3~d6做埠輸入位。
綜上,通常使用列印口做i/o埠的共有12個輸出位和4個輸入位。
。
Linux 對 IO 埠的操作
1。在裝置開啟或者驅動模組被載入時,申請i o埠區域 request region 2。之後使用inb outb 等函式對i o埠操作 3。在裝置被關閉或者解除安裝時,釋放i o埠範圍 release region 1。在裝置開啟或者驅動模組被載入時,申請i o埠區域並且使用ioport map 對...
Linux 快速操作IO埠
在嵌入式裝置中對gpio的操作是最基本的操作。一般的做法是寫乙個單獨驅動程式,網上大多數的例子都是這樣的。其實linux下面有乙個通用的gpio操作介面,那就是我要介紹的 sys class gpio 方式。首先,看看系統中有沒有 sys class gpio 這個資料夾。如果沒有請在編譯核心的時候...
驅動學習筆記 IO埠操作
最近一段時間,工作需要編寫除錯乙個usb轉虛擬串列埠的windows驅動程式。特意翻看了下n久之前的驅動程式關於io埠操作的學習筆記,不知道是記性差了,還是有些知識生疏了,乾脆重新記錄整理下。一 概述 1.turboc中兩組i o操作函式 input inp 8位 inpw 16位 inpd 32位...