免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 22705 | 回复: 15
打印 上一主题 下一主题

[硬件 通讯]PHP在RS232串口通讯协议的应用演示[测试环境PHP5.1.4] [复制链接]

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-06-11 20:48 |只看该作者 |倒序浏览
[硬件 通讯]PHP在RS232串口通讯协议的应用演示[测试环境WinXP/PHP5.1.4]

1. 预先的知识:
什么是RS232/RS484及其应用?
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



从串口双机对联线缆指南
  (一)串行通讯电缆的制作

  无论是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://win2000server.vicp.net:88/Article_Show.asp?ArticleID=25

[ 本帖最后由 HonestQiao 于 2006-6-11 23:03 编辑 ]

RS232_DB9.jpg (55 KB, 下载次数: 187)

RS232_DB9.jpg

RS232_DB25.jpg (44.5 KB, 下载次数: 157)

RS232_DB25.jpg

9-25table.gif (4.79 KB, 下载次数: 176)

9-25table.gif

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
2 [报告]
发表于 2006-06-11 20:48 |只看该作者
二、测试环境的构建:
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,并打开设置然后保存:
  1. extension=php_dio.dll
复制代码

  这一点不做任何答疑。

  

[ 本帖最后由 HonestQiao 于 2006-6-12 22:31 编辑 ]

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
3 [报告]
发表于 2006-06-11 20:48 |只看该作者
三:参考资料:
1. 参考手册文档:
http://cn.php.net/manual/zh/ref.dio.php
http://cn.php.net/manual/zh/ref.exec.php
  如果代码之中有你没有见过,或者没有使用过,或者不熟悉的函数,请访问以上网址。
  主要使用了PHP的Direct IO Functions.

[ 本帖最后由 HonestQiao 于 2006-6-11 21:06 编辑 ]

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
4 [报告]
发表于 2006-06-11 20:49 |只看该作者
四:演示代码:

  1. <?php
  2. // --------------------------------------------------------------------------
  3. // File name   : RS232_Server.php
  4. // Description : RS232演示上位机程序
  5. // Requirement : PHP 5.1.4 (cli) (http://www.php.net)
  6. //
  7. // Copyright(C), HonestQiao, 2006, All Rights Reserved.
  8. //
  9. // Author: HonestQiao (honestqiao@hotmail.com/QQ:5601680)
  10. //
  11. // 程序简介:
  12. // 本程序与RS232_Client构成一个完整的演示系统,展示了PHP在RS232串口通讯上的应用。
  13. // 程序之中实现了一个基础但是完整的RS232通讯协议(HQB232),通讯协议格式如下:
  14. // 协议内容:
  15. //             C->S 01 //请求通讯
  16. //             S->C 02 //响应通讯
  17. //             C->S LEN DATA //LEN表示数据(DATA)长度 DATA表示实际数据
  18. //             C->S 03 //结束通讯
  19. // 说明:S表示上位机 C表示下位机
  20. //       HQB232表示HonestQiao演示的基础(Base)RS232通讯协议,包含了协议的
  21. //   请求和响应,数据帧的结构。
  22. //       演示过程为通讯的请求和响应,十次数据帧的发送, 通讯的结束
  23. //       数据帧的结构为当前的序号,microtime(),随机字符串
  24. //        
  25. //       欢迎探讨PHP在RS232串口通讯上的应用。
  26. // --------------------------------------------------------------------------
  27. set_time_limit(0);
  28. exec('mode COM1: baud=115200 data=8 stop=1 parity=n xon=on');

  29. $fd = dio_open('COM1:', O_RDWR);
  30. if(!$fd)
  31. {
  32.         die("Error when open COM1");
  33. }

  34. $ff = dio_stat($fd);print_r($ff);
  35. echo "HQB232 SERVER is listenning on COM1\n";
  36. /// read
  37. $len = 2;
  38. $t=0;while (($t++)<1000)
  39. {
  40.         $data = dio_read($fd, $len);
  41.         if ($data) {
  42.                 if($data==chr(0).chr(1)){
  43.                         echo "S_RECV:01\n";
  44.                         echo "S_SEND:02\n";
  45.                         dio_write($fd,chr(0).chr(2));
  46.                         break;
  47.                 }
  48.         }
  49. }

  50. /// read
  51. $len = 2;
  52. $t=0;while (($t++)<1000)
  53. {
  54.         $len = 2;
  55.         $data = dio_read($fd, $len);
  56.         if($data==chr(0).chr(3)){
  57.                 echo "S_RECV:03\n";
  58.                 break;
  59.         }
  60.         elseif ($data) {
  61.                 $len = intval($data);
  62.                 $data = dio_read($fd, $len);
  63.                 if($data){
  64.                         echo "S_RECV:($len)$data\n";
  65.                 }
  66.         }
  67. }
  68. dio_close($fd);
  69. ?>
复制代码


  1. <?php
  2. // --------------------------------------------------------------------------
  3. // File name   : RS232_Client.php
  4. // Description : RS232演示下位机程序
  5. // Requirement : PHP 5.1.4 (cli) (http://www.php.net)
  6. //
  7. // Copyright(C), HonestQiao, 2006, All Rights Reserved.
  8. //
  9. // Author: HonestQiao (honestqiao@hotmail.com/QQ:5601680)
  10. //
  11. // 程序简介:
  12. // 本程序与RS232_Server构成一个完整的演示系统,展示了PHP在RS232串口通讯上的应用。
  13. // 程序之中实现了一个基础但是完整的RS232通讯协议(HQB232),通讯协议格式如下:
  14. // 协议内容:
  15. //             C->S 01 //请求通讯
  16. //             S->C 02 //响应通讯
  17. //             C->S LEN DATA //LEN表示数据(DATA)长度 DATA表示实际数据
  18. //             C->S 03 //结束通讯
  19. // 说明:S表示上位机 C表示下位机
  20. //       HQB232表示HonestQiao演示的基础(Base)RS232通讯协议,包含了协议的
  21. //   请求和响应,数据帧的结构。
  22. //       演示过程为通讯的请求和响应,十次数据帧的发送, 通讯的结束
  23. //       数据帧的结构为当前的序号,microtime(),随机字符串
  24. //        
  25. //       欢迎探讨PHP在RS232串口通讯上的应用。
  26. // --------------------------------------------------------------------------
  27. set_time_limit(0);
  28. exec('mode COM2: baud=115200 data=8 stop=1 parity=n xon=on');

  29. $fd = dio_open('COM2:', O_RDWR);
  30. if(!$fd)
  31. {
  32.         die("Error when open COM2");
  33. }

  34. $ff = dio_stat($fd);print_r($ff);
  35. echo "HQB232 CLIENT is start on COM2\n";
  36. dio_write($fd,chr(0).chr(1));echo "C_SEND:01\n";
  37. $len = 2;
  38. $t=0;while(($t++)<1000)
  39. {
  40.         $data = dio_read($fd, $len);
  41.         if($data==chr(0).chr(2)){
  42.                 echo "C_RECV:02\n";       
  43.                 break;
  44.         }
  45. }
  46. $len = 2;
  47. $t=0;while(($t++)<10)
  48. {
  49.         $sdata = sprintf("%03d",$t) . "=" . microtime() . " (" . randomkeys(rand(0,35)) . ")";
  50.         $slen = strlen($sdata);
  51.         $stxlen = sprintf("%02d",$slen);
  52.         dio_write($fd,"$stxlen");
  53.         dio_write($fd,"$sdata");echo "C_SEND:($stxlen)$sdata\n";
  54.         //sleep(1);
  55. }
  56. dio_write($fd,chr(0).chr(3));echo "C_SEND:03\n";
  57. dio_close($fd);

  58. function randomkeys($length)
  59.   {
  60.    $pattern = "1234567890abcdefghijklmnopqrstuvwxyz";
  61.    for($i=0;$i<$length;$i++)
  62.    {
  63.      $key .= $pattern{rand(0,35)};
  64.    }
  65.    return $key;
  66. }
  67. ?>
复制代码


[ 本帖最后由 HonestQiao 于 2006-6-12 22:21 编辑 ]

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
5 [报告]
发表于 2006-06-11 21:07 |只看该作者
五、演示过程:
上位机:开始->运行->CMD
然后转到PHP5.1.4目录之下,执行:
php -f RS232_Server.php

下位机:开始->运行->CMD
然后转到PHP5.1.4目录之下,执行:
php -f RS232_Client.php


实际结果如下:


  1. F:\usr\local\php5>php -f e:\RS232_Server.php
  2. Array
  3. (
  4.     [device] => 3
  5.     [inode] => 0
  6.     [mode] => 8192
  7.     [nlink] => 1
  8.     [uid] => 0
  9.     [gid] => 0
  10.     [device_type] => 3
  11.     [size] => 0
  12.     [atime] => 0
  13.     [mtime] => 0
  14.     [ctime] => 0
  15. )
  16. HQB232 SERVER is listenning on COM1
  17. S_RECV:01
  18. S_SEND:02
  19. S_RECV:(53)001=0.19238200 1150031774 (krruv981gpf1pmi1fz4qz09e9)
  20. S_RECV:(42)002=0.19144800 1150031775 (jrhw41mphuy0ui)
  21. S_RECV:(40)003=0.19148500 1150031776 (lqq560p6v17r)
  22. S_RECV:(36)004=0.19148900 1150031777 (3ct02xmc)
  23. S_RECV:(28)005=0.19212700 1150031778 ()
  24. S_RECV:(33)006=0.19162500 1150031779 (2ilqf)
  25. S_RECV:(34)007=0.19167800 1150031780 (vwmdfc)
  26. S_RECV:(62)008=0.19168700 1150031781 (idb0laix4a6ryxz5nb7u74iaza601it6sv)
  27. S_RECV:(56)009=0.19170100 1150031782 (r9ypgtvu4j7w1u141qx6im20ajy7)
  28. S_RECV:(53)010=0.19171000 1150031783 (wq5mp1sdfuet1tp0x3vk67n47)
  29. S_RECV:03

  30. F:\usr\local\php5>
复制代码



  1. F:\usr\local\php5>php -f e:\RS232_Client.php
  2. Array
  3. (
  4.     [device] => 3
  5.     [inode] => 0
  6.     [mode] => 8192
  7.     [nlink] => 1
  8.     [uid] => 0
  9.     [gid] => 0
  10.     [device_type] => 3
  11.     [size] => 0
  12.     [atime] => 0
  13.     [mtime] => 0
  14.     [ctime] => 0
  15. )
  16. HQB232 CLIENT is start on COM2
  17. C_SEND:01
  18. C_RECV:02
  19. C_SEND:(53)001=0.19238200 1150031774 (krruv981gpf1pmi1fz4qz09e9)
  20. C_SEND:(42)002=0.19144800 1150031775 (jrhw41mphuy0ui)
  21. C_SEND:(40)003=0.19148500 1150031776 (lqq560p6v17r)
  22. C_SEND:(36)004=0.19148900 1150031777 (3ct02xmc)
  23. C_SEND:(28)005=0.19212700 1150031778 ()
  24. C_SEND:(33)006=0.19162500 1150031779 (2ilqf)
  25. C_SEND:(34)007=0.19167800 1150031780 (vwmdfc)
  26. C_SEND:(62)008=0.19168700 1150031781 (idb0laix4a6ryxz5nb7u74iaza601it6sv)
  27. C_SEND:(56)009=0.19170100 1150031782 (r9ypgtvu4j7w1u141qx6im20ajy7)
  28. C_SEND:(53)010=0.19171000 1150031783 (wq5mp1sdfuet1tp0x3vk67n47)
  29. C_SEND:03

  30. F:\usr\local\php5>
复制代码

[ 本帖最后由 HonestQiao 于 2006-6-11 21:18 编辑 ]

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
6 [报告]
发表于 2006-06-11 21:18 |只看该作者
六:说明
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
));

[ 本帖最后由 HonestQiao 于 2006-6-12 22:23 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2006-06-11 22:08 |只看该作者
帮乔版补充一点~~
linux下com口读写采用文件的方式~比较简单~~所以dio这个ext只用于windows下~~

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
8 [报告]
发表于 2006-06-11 22:16 |只看该作者
原帖由 mikespook 于 2006-6-11 22:08 发表
帮乔版补充一点~~
linux下com口读写采用文件的方式~比较简单~~所以dio这个ext只用于windows下~~


注意,该模块完全适合在*nix下面使用。
为何:举一个例子:
dio_tcsetattr()这个函数是设置端口参数的,如果使用PHP文件读写,那么将不好设置了(虽然可以有方法设置)。


PHP supports the direct io functions as described in the Posix Standard (Section 6) for performing I/O functions at a lower level than the C-Language stream I/O functions (fopen(), fread(),..). The use of the DIO functions should be considered only when direct control of a device is needed. In all other cases, the standard filesystem functions are more than adequate.

[ 本帖最后由 HonestQiao 于 2006-6-11 22:18 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2006-06-11 22:53 |只看该作者
The use of the DIO functions should be considered only when direct control of a device is needed. In all other cases, the standard filesystem functions are more than adequate.

我是这样理解这句话的~~
“DIO函数应当只用在有必要直接操作设备的时候。其他任何时候,标准的文件系统函数将更加适合。”
*nix下“一切皆文件”的思想,操作com亦可~~印象中WIN下的COM好像在WINNT家族中也是使用文件的方式访问~~

hCOM = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

这样独占访问好像也可以~~
----------------------
不过使用 dio 可以在不编写ext的情况下访问如加密狗,刷读卡设备等等~~

论坛徽章:
0
10 [报告]
发表于 2006-06-11 22:59 |只看该作者
赫赫,,你以前用什么语言写工控
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP