php5|應用示範
一. 預先的知識:
什麼是RS232/RS484及其應用?
QUOTE:
RS232介面就是串口,電腦機箱後方的9芯(或25芯)插座,旁邊一般有 "|O|O|" 樣標識。
一般機箱有兩個,新機箱有可能只有一個。膝上型電腦有可能沒有。
有很多工業儀器將它作為標準通訊連接埠。通訊的內容與格式一般附在儀器的使用者說明書中。
電腦與電腦或電腦與終端之間的資料傳送可以採用串列通訊和並行通訊二種方式。由於串列通訊方式具有使用線路少、成本低,特別是在遠程傳輸時,避免了多條線路特性的不一致而被廣泛採用。 在串列通訊時,要求通訊雙方都採用一個標準介面,使不同 的裝置可以方便地串連起來進行通訊。 RS-232-C介面(又稱 EIA RS-232-C)是目前最常用的一種串列通訊介面。它是在1970年由美國電子工業協會(EIA)聯合貝爾系統、 數據機廠家及電腦終端生產廠家共同制定的用於串列通訊的標 准。它的全名是“資料終端設備(DTE)和資料通訊裝置(DCE)之間 串列位元據交換介面技術標準”該標準規定採用一個25個腳的 DB25連接器,對連接器的每個引腳的訊號內容加以規定,還對各種信 號的電平加以規定。
(1)介面的訊號內容 實際上RS-232-C的25條引線中有許多是很少使用的,在電腦與終端通訊中一般只使用3-9條引線。RS-232-C最常用的9條引線的訊號內容見附表1所示
(2)介面的電氣特性 在RS-232-C中任何一條訊號線的電壓均為負邏輯關係。即:邏 輯“1”,-5— -15V;邏輯“0” +5— +15V 。雜訊容限為2V。即 要求接收器能識別低至+3V的訊號作為邏輯“0”,高到-3V的訊號 作為邏輯“1”
(3) 介面的物理結構 RS-232-C介面連接器一般使用型號為DB-25的25芯插頭座,通常插頭在DCE端,插座在DTE端. 一些裝置與PC機串連的RS-232-C介面,因為不使用對方的傳送控制訊號,只需三條介面線,即“發送資料”、“接收資料”和“訊號地”。所以採用DB-9的9芯插頭座,傳輸線採用屏蔽雙絞線。
(4)傳輸電纜長度 由RS-232C標準規定在碼元畸變小於4%的情況下,傳輸電纜長度應為50英尺,其實這個4%的碼元畸變是很保守的,在實際應用中,約有99%的使用者是按碼元畸變10-20%的範圍工作的,所以實際使用中最大距離會遠超過50英尺,美國DEC公司曾規定允許碼元畸變為10%而得出附表2 的實驗結果。其中1號電纜為屏蔽電纜,型號為DECP.NO.9107723 內有三對雙絞線,每對由22# AWG 組成,其外覆以屏蔽網。2號電纜為不帶屏蔽的電纜。型號為DECP.NO.9105856-04是22#AWG的四芯電纜。
1.RS-232-C是美國電子工業協會EIA(Electronic Industry Association)制定的一種串列物理介面標準。RS是英文“推薦標準”的縮寫,232為標識號,C表示修改次數。RS-232-C匯流排標準設有25條訊號線,包括一個主通道和一個輔助通道,在多數情況下主要使用主通道,對於一般雙工通訊,僅需幾條訊號線就可實現,如一條發送線、一條接收線及一條地線。RS-232-C標準規定的資料轉送速率為每秒50、75、 100、150、300、600、1200、2400、4800、9600、19200傳輸速率。RS-232-C標準規定,磁碟機允許有2500pF的電容負載,通訊距離將受此電容限制,例如,採用150pF/m的通訊電纜時,最大通訊距離為15m;若每米電纜的電容量減小,通訊距離可以增加。傳輸距離短的另一原因是RS-232屬單端訊號傳送,存在共地雜訊和不能抑制共模幹擾等問題,因此一般用於20m以內的通訊。
2.RS-485匯流排,在要求通訊距離為幾十米到上千米時,廣泛採用RS-485 串列匯流排標準。RS-485採用平衡發送和差分接收,因此具有抑制共模幹擾的能力。加上匯流排收發器具有高靈敏度,能檢測低至200mV的電壓,故傳輸訊號能在千米以外得到恢複。 RS-485採用半雙工工作方式,任何時候只能有一點處於發送狀態,因此,發送電路須由使能訊號加以控制。RS-485用於多點互連時非常方便,可以省掉許多訊號線。應用RS-485 可以連網構成分布式系統,其允許最多並聯32台磁碟機和32台接收器。
以往,PC與智慧型裝置通訊多藉助RS232、RS485、乙太網路等方式,主要取決於裝置的介面規範。但RS232、RS485隻能代表通訊的物理介質層和鏈路層,如果要實現資料的雙向訪問,就必須自己編寫通訊應用程式,但這種程式多數都不能符合ISO/OSI的規範,只能實現較單一的功能,適用於單一裝置類型,程式不具備通用性。在RS232或RS485裝置聯成的裝置網中,如果裝置數量超過2台,就必須使用RS485做通訊介質,RS485網的裝置間要想互連資訊只有通過“主(Master)”裝置中轉才能實現,這個主裝置通常是PC,而這種裝置網中只允許存在一個主裝置,其餘全部是從(Slave)裝置。而現場匯流排技術是以ISO/OSI模型為基礎的,具有完整的軟體支援系統,能夠解決匯流排控制、衝突檢測、鏈路維護等問題。
來源網址:http://zhidao.baidu.com/question/4578886.html
從串口雙機對聯線纜指南
QUOTE:
(一)串列通訊電纜的製作
無論是9孔插頭,還是25孔插頭,其串列通訊電纜連線時都要遵循下列對接關係:
SG←→SG TXD←→RXD RXD←→TXD RTS←→CTS
CTS←→RTS DTR←→DSR DSR←→DTR
根據上述對接關係,就可以非常方便地串連串列通訊電纜。這裡順便介紹一下上述各引腳所代表的含義:
SG英文全稱為Signal Ground/Common Return,表示訊號地;
TXD指Transmitted Data,表示資料發送;
RXD指Received Data,表示接收資料;
RTS指Request To Send,表示發送請求;
CTS指Clear To Send,表示清除請求;
DTR指Data Terminal Ready,表示資料終端準備就緒;
DSR指Data Signal Rate Selector,表示資料置位準備就緒。
在製作9芯串口連線時,需要2個9孔插頭和1.5米長的至少7芯的扁平電纜,引腳連線如下所示。
9孔插頭-9孔插頭引腳連線為:2-3、3-2、4-6、5-5、6-4、7-8、8-7。
9孔插頭-25孔插頭引腳連線為:2-2、3-3、4-6、5-7、6-20、7-5、8-4。
25孔插頭-25孔插頭引腳連線為:2-3、3-2、4-5、5-4、6-20、7-7、20-6。
說明:這裡有部分串口通訊說明圖片,請到 http://bbs.chinaunix.net/viewthread.php?tid=771726 進行查看
二、測試環境的構建:
1. 參考上面的《(一)串列通訊電纜的製作》,首先把兩台電腦通過串口連結起來。
當然,你也完全可以這麼操作一台電腦上面的兩個串口,而不需要兩台電腦;如果你有兩個串口的話。
因為我以前做過工業控制底層開發,所以我可以很容易的構建這個基本的環境;
實際上,只要:RxD TxD對接,GND直連即可,俗稱三線串連。
這一點不做任何答疑。
2. PHP運行環境的構建:
作業系統:WindowsXP(其他Windows系統沒有測試)
PHP5.1.4: http://cn.php.net/get/php-5.1.4-Win32.zip/from/a/mirror
PECL5.1.4:http://cn.php.net/get/pecl-5.1.4-Win32.zip/from/a/mirror
解壓PHP5.1.4,把PECL5.1.4之中的php_dio.dll放到PHP5.1.4的ext目錄之下
把PHP5.1.4之中的php.ini-dist拷貝粘貼為php.ini,並開啟設定然後儲存:
CODE:[Copy to clipboard]extension=php_dio.dll
這一點不做任何答疑。
三:參考資料:
1. 參考手冊文檔:
http://cn.php.net/manual/zh/ref.dio.php
http://cn.php.net/manual/zh/ref.exec.php
如果代碼之中有你沒有見過,或者沒有使用過,或者不熟悉的函數,請訪問以上網址。
主要使用了PHP的Direct IO Functions.
四:示範代碼:
CODE:[Copy to clipboard]<?php
// --------------------------------------------------------------------------
// File name : RS232_Server.php
// Description : RS232示範上位機程式
// Requirement : PHP 5.1.4 (cli) (http://www.php.net)
//
// Copyright(C), HonestQiao, 2006, All Rights Reserved.
//
// Author: HonestQiao (honestqiao@hotmail.com/QQ:5601680)
//
// 程式簡介:
// 本程式與RS232_Client構成一個完整的示範系統,展示了PHP在RS232串口通訊上的應用。
// 程式之中實現了一個基礎但是完整的RS232通訊協議(HQB232),通訊協議格式如下:
// 協議內容:
// C->S 01 //請求通訊
// S->C 02 //響應通訊
// C->S LEN DATA //LEN表示資料(DATA)長度 DATA表示實際資料
// C->S 03 //結束通訊
// 說明:S表示上位機 C表示下位機
// HQB232表示HonestQiao示範的基礎(Base)RS232通訊協議,包含了協議的
// 請求和響應,資料幀的結構。
// 示範過程為通訊的請求和響應,十次資料幀的發送, 通訊的結束
// 資料幀的結構為當前的序號,microtime(),隨機字串
//
// 歡迎探討PHP在RS232串口通訊上的應用。
// --------------------------------------------------------------------------
set_time_limit(0);
exec('mode COM1: baud=115200 data=8 stop=1 parity=n xon=on');
$fd = dio_open('COM1:', O_RDWR);
if(!$fd)
{
die("Error when open COM1");
}
$ff = dio_stat($fd);print_r($ff);
echo "HQB232 SERVER is listenning on COM1\n";
/// read
$len = 2;
$t=0;while (($t++)<1000)
{
$data = dio_read($fd, $len);
if ($data) {
if($data==chr(0).chr(1)){
echo "S_RECV:01\n";
echo "S_SEND:02\n";
dio_write($fd,chr(0).chr(2));
break;
}
}
}
/// read
$len = 2;
$t=0;while (($t++)<1000)
{
$len = 2;
$data = dio_read($fd, $len);
if($data==chr(0).chr(3)){
echo "S_RECV:03\n";
break;
}
elseif ($data) {
$len = intval($data);
$data = dio_read($fd, $len);
if($data){
echo "S_RECV:($len)$data\n";
}
}
}
dio_close($fd);
?>
CODE:[Copy to clipboard]<?php
// --------------------------------------------------------------------------
// File name : RS232_Client.php
// Description : RS232示範下位機程式
// Requirement : PHP 5.1.4 (cli) (http://www.php.net)
//
// Copyright(C), HonestQiao, 2006, All Rights Reserved.
//
// Author: HonestQiao (honestqiao@hotmail.com/QQ:5601680)
//
// 程式簡介:
// 本程式與RS232_Server構成一個完整的示範系統,展示了PHP在RS232串口通訊上的應用。
// 程式之中實現了一個基礎但是完整的RS232通訊協議(HQB232),通訊協議格式如下:
// 協議內容:
// C->S 01 //請求通訊
// S->C 02 //響應通訊
// C->S LEN DATA //LEN表示資料(DATA)長度 DATA表示實際資料
// C->S 03 //結束通訊
// 說明:S表示上位機 C表示下位機
// HQB232表示HonestQiao示範的基礎(Base)RS232通訊協議,包含了協議的
// 請求和響應,資料幀的結構。
// 示範過程為通訊的請求和響應,十次資料幀的發送, 通訊的結束
// 資料幀的結構為當前的序號,microtime(),隨機字串
//
// 歡迎探討PHP在RS232串口通訊上的應用。
// --------------------------------------------------------------------------
set_time_limit(0);
exec('mode COM2: baud=115200 data=8 stop=1 parity=n xon=on');
$fd = dio_open('COM2:', O_RDWR);
if(!$fd)
{
die("Error when open COM2");
}
$ff = dio_stat($fd);print_r($ff);
echo "HQB232 CLIENT is start on COM2\n";
dio_write($fd,chr(0).chr(1));echo "C_SEND:01\n";
$len = 2;
$t=0;while(($t++)<1000)
{
$data = dio_read($fd, $len);
if($data==chr(0).chr(2)){
echo "C_RECV:02\n";
break;
}
}
$len = 2;
$t=0;while(($t++)<10)
{
$sdata = sprintf("%03d",$t) . "=" . microtime() . " (" . randomkeys(rand(0,35)) . ")";
$slen = strlen($sdata);
$stxlen = sprintf("%02d",$slen);
dio_write($fd,"$stxlen");
dio_write($fd,"$sdata");echo "C_SEND:($stxlen)$sdata\n";
//sleep(1);
}
dio_write($fd,chr(0).chr(3));echo "C_SEND:03\n";
dio_close($fd);
function randomkeys($length)
{
$pattern = "1234567890abcdefghijklmnopqrstuvwxyz";
for($i=0;$i<$length;$i++)
{
$key .= $pattern{rand(0,35)};
}
return $key;
}
?>
五、示範過程:
上位機:開始->運行->CMD
然後轉到PHP5.1.4目錄之下,執行:
php -f RS232_Server.php
下位機:開始->運行->CMD
然後轉到PHP5.1.4目錄之下,執行:
php -f RS232_Client.php
實際結果如下:
CODE:[Copy to clipboard]F:\usr\local\php5>php -f e:\RS232_Server.php
Array
(
[device] => 3
[inode] => 0
[mode] => 8192
[nlink] => 1
[uid] => 0
[gid] => 0
[device_type] => 3
[size] => 0
[atime] => 0
[mtime] => 0
[ctime] => 0
)
HQB232 SERVER is listenning on COM1
S_RECV:01
S_SEND:02
S_RECV:(53)001=0.19238200 1150031774 (krruv981gpf1pmi1fz4qz09e9)
S_RECV:(42)002=0.19144800 1150031775 (jrhw41mphuy0ui)
S_RECV:(40)003=0.19148500 1150031776 (lqq560p6v17r)
S_RECV:(36)004=0.19148900 1150031777 (3ct02xmc)
S_RECV:(28)005=0.19212700 1150031778 ()
S_RECV:(33)006=0.19162500 1150031779 (2ilqf)
S_RECV:(34)007=0.19167800 1150031780 (vwmdfc)
S_RECV:(62)008=0.19168700 1150031781 (idb0laix4a6ryxz5nb7u74iaza601it6sv)
S_RECV:(56)009=0.19170100 1150031782 (r9ypgtvu4j7w1u141qx6im20ajy7)
S_RECV:(53)010=0.19171000 1150031783 (wq5mp1sdfuet1tp0x3vk67n47)
S_RECV:03
F:\usr\local\php5>
CODE:[Copy to clipboard]F:\usr\local\php5>php -f e:\RS232_Client.php
Array
(
[device] => 3
[inode] => 0
[mode] => 8192
[nlink] => 1
[uid] => 0
[gid] => 0
[device_type] => 3
[size] => 0
[atime] => 0
[mtime] => 0
[ctime] => 0
)
HQB232 CLIENT is start on COM2
C_SEND:01
C_RECV:02
C_SEND:(53)001=0.19238200 1150031774 (krruv981gpf1pmi1fz4qz09e9)
C_SEND:(42)002=0.19144800 1150031775 (jrhw41mphuy0ui)
C_SEND:(40)003=0.19148500 1150031776 (lqq560p6v17r)
C_SEND:(36)004=0.19148900 1150031777 (3ct02xmc)
C_SEND:(28)005=0.19212700 1150031778 ()
C_SEND:(33)006=0.19162500 1150031779 (2ilqf)
C_SEND:(34)007=0.19167800 1150031780 (vwmdfc)
C_SEND:(62)008=0.19168700 1150031781 (idb0laix4a6ryxz5nb7u74iaza601it6sv)
C_SEND:(56)009=0.19170100 1150031782 (r9ypgtvu4j7w1u141qx6im20ajy7)
C_SEND:(53)010=0.19171000 1150031783 (wq5mp1sdfuet1tp0x3vk67n47)
C_SEND:03
F:\usr\local\php5>
六:說明
1. exec('mode COM1: baud=115200 data=8 stop=1 parity=n xon=on');
exec('mode COM2: baud=115200 data=8 stop=1 parity=n xon=on');
mode是CMD下面的命令,表示設定串口的參數,因為dio_tcsetattr() 未在Windows下面實現,所以需要使用CMD的mode命令來進行設定,具體用法,請看:help mode
2. 通訊協議使用ASCII文本進行,沒有使用HEX十六進位。因為是示範程式,所以協議非常簡單,但是一個協議基本的內容都有了。
3. 下位機程式的sleep(1),這個是通訊之中常見的情況,資料轉送和上位機處理需要一定的時間。
4. 示範的為RS232,以此類推,你也可以用到其他的場合。例如:簡單修改,應用到HTTP通訊。
5. 硬體環境的建立,PHP環境的建立,不做任何答疑。
6. 歡迎探討。
7. 感謝mikespook的意見,附加,如果是*nix,則:
'/dev/ttyS0'表示第一個COM連接埠,依此類推;連接埠的設定,應該在dio_open之後,使用:
dio_tcsetattr($fd, array(
'baud' => 9600,
'bits' => 8,
'stop' => 1,
'parity' => 0
));