RS232485串口通信详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

串口通信详解
一、RS-232
RS-232在1962年发布,命名为EIA-232-E,作为工业标准,以保证不同厂家产品之间的兼容。

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;若每M电缆的电容量减小,通信距离可以增加。

传输距离短的另一原因是RS-232属单端信号传送,存在共地噪声和不能抑制共模干扰等问题,因此一般用于20m以内的通信。

目前RS-232是PC机与通信工业中应用最广泛的一种串行接口。

RS-232被定义为一种在低速率串行通讯中增加通讯距离的单端标准。

RS-232采取不平衡传输方式,即所谓单端通讯。

收、发端的数据信号是相对于
信号地,如从DTE设备发出的数据在
使用DB25连接器时是2脚相对7脚<信号地)的电平,DB25各引脚定义参见图1。

典型的RS-232信号在正负电平之间摆动,在发送数据时,发送端驱动器输出正电平在+5~+15V,负电平在-5~-15V电平。

当无数据传输时,线上为TTL,从开始传送数据到结束,线上电平从TTL电平到RS-232电平再返回TTL电平。

接收器典型的工作电平在+3~+12V与-3~-12V。

因为发送电平与接收电平的差仅为2V至3V左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约15M,最高速率为20kb/s。

RS-232是为点对点<即只用一对收、发设备)通讯而设计的,其驱动器负载为3~7kΩ。

所以RS-232适合本地设备之间的通信。

RS232C串口通信接线方法<三线制)
首先,串口传输数据只要有接收数据针脚和发送针脚就能实现:同一个串口的接收脚和发送脚直接用线相连,两个串口相连或一个串口和多个串口相连
∙同一个串口的接收脚和发送脚直接用线相连对9针串口和25针串口,均是2与3直接相连;
∙两个不同串口<不论是同一台计算机的两个串口或分别是不同计算机的串口)
上面表格是对微机标准串行口而言的,还有许多非标准设备,如接收GPS数据或电子罗盘数据,只要记住一个原则:接收数据针脚<或线)与发送数据针脚<或线)相连,彼些交叉,信号地对应相接。

表1
二、RS485和RS422
RS-422由RS-232发展而来,它是为弥补RS-232之不足而提出的。

为改进RS-232通信距离短、速率低的缺点,RS-422定义了一种平衡通信接口,将传输速率提高到10Mb/s,传输距离延长到4000英尺<速率低于100kb/s时),并允许在一条平衡总线上连接最多10个接收器。

RS-422是一种单机发送、多机接收的单向、平衡传输规范,被命名为TIA/EIA-422-A标准。

为扩展应用范围,EIA又于1983年在RS-422基础上制定了RS-485标准,增加了多点、双向通信能力,即允许多个发送器连接到同一条总线上,同时增加了发送器的驱动能力和冲突保护特性,扩展了总线共模范围,后命名为TIA/EIA-485-A标准。

因为EIA提出的建议标准都是以“RS”作为前缀,所以在通讯工业领域,仍然习惯将上述标准以RS作前缀称谓。

平衡传输
RS-422、RS-485与RS-232不一样,数据信号采用差分传输方式,也称作平衡传输,它使用一对双绞线,将其中一线定义为A,另一线定义为B,如图2。

图2
通常情况下,发送驱动器A、B之间的正电平在+2~+6V,是一个逻辑状态,负电平在-2~6V,是另一个逻辑状态。

另有一个信号地C,在RS-485中还有一“使能”端,而在RS-422中这是可用可不用的。

“使能”端是用于控制发送驱动器与传输线的切断与连接。

当“使能”端起作用时,发送驱动器处于高阻状态,称作“第三态”,即它是有别于逻辑“1”与“0”的第三态。

接收器也作与发送端相对的规定,收、发端通过平衡双绞线将AA与BB对应相连,当在收端AB之间有大于+200mV的电平时,输出正逻辑电平,小于-200mV时,输出负逻辑电平。

接收器接收平衡线上的电平范围通常在200mV至6V之间。

参见图3。

图3
RS-422电气规定
RS-422标准全称是“平衡电压数字接口电路的电气特性”,它定义了接口电路的特性。

图5是典型的RS-422四线接口。

实际上还有一根信号地线,共5根线。

图4是其DB9连接器引脚定义。

因为接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。

即一个主设备<Master),其余为从设备<Salve),从设备之间不能通信,所以RS-422支持点对多的双向通信。

接收器输入阻抗为4k,故发端最大负载能力是10×4k+100Ω<终接电阻)。

RS-422四线接口因为采用单独的发送和接收通道,因此不必控制数据方向,各装置之间任何必须的信号交换均可以按软件方式<XON/XOFF握手)或硬件方式<一对单独的双绞线)实现。

图4 图5
RS-422的最大传输距离为4000英尺<约1219M),最大传输速率为10Mb/s。

其平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能达到最大传输距离。

只有在很短的距离下才能获得最高速率传输。

一般100M长的双绞线上所能获得的最大传输速率仅为1Mb/s。

RS-422需要一终接电阻,要求其阻值约等于传输电缆的特性阻抗。

在矩距离传输时可不需终接电阻,即一般在300M以下不需终接电阻。

终接电阻接在传输电缆的最远端。

RS-422有关电气参数见表1
RS-485电气规定
因为RS-485是从RS-422基础上发展而来的,所以RS-485许多电气规定与RS-422相仿。

如都采用平衡传输方式、都需要在传输线上接终接电阻等。

RS-485可以采用二线与四线方式,二线制可实现真正的多点双向通信,参见图6。

而采用四线连接时,与RS-422一样只能实现点对多的通信,即只能有一个主
<Master)设备,其余为从设备,但它比RS-422有改进,无论四线还是二线连接方式总线上可多接到32个设备。

参见图7。

图6 图7
RS-485与RS-422的不同还在于其共模输出电压是不同的,RS-485是-7V至+12V之间,而RS-422在-7V至+7V之间,RS-485接收器最小输入阻抗为12k S-422是4k S-485满足所有RS-422的规范,所以RS-485的驱动器可以用在RS-422网络中应用。

RS-485有关电气规定参见表1。

RS-485与RS-422一样,其最大传输距离约为1219M,最大传输速率为10Mb/s。

平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能使用规定最长的电缆长度。

只有在很短的距离下才能获得最高速率传输。

一般100M长双绞线最大传输速率仅为1Mb/s。

RS-485需要2个终接电阻,其阻值要求等于传输电缆的特性阻抗。

在矩距离传输时可不需终接电阻,即一般在300M以下不需终接电阻。

终接电阻接在传输总线的两端。

RS-422与RS-485的网络安装注意要点
RS-422可支持10个节点,RS-485支持32个节点,因此多节点构成网络。

网络拓扑一般采用终端匹配的总线型结构,不支持环形或星形网络。

在构建网络时,应注意如下几点:
1.采用一条双绞线电缆作总线,将各个节点串接起来,从总线到每个节点的引出线长度应尽量短,以便使引出线中的反射信号对总线信号的影响最低。

图8所示为实际应用中常见的一些错误连接方式<a,c,e)和正确的连接方式<b,d,f)。

a,c,e这三种网络连接尽管不正确,在短距离、低速率仍可能正常工作,但随着通信距离的延长或通信速率的提高,其不良影响会越来越严重,主要原因是信号在各支路末端反射后与原信号叠加,会造成信号质量下降。

2.应注意总线特性阻抗的连续性,在阻抗不连续点就会发生信号的反射。

下列几种情况易产生这种不连续性:总线的不同区段采用了不同电缆,或某一段总线上有过多收发器紧靠在一起安装,再者是过长的分支线引出到总线。

总之,应该提供一条单一、连续的信号通道作为总线。

图8
RS-422与RS-485传输线上匹配的一些说明
对RS-422与RS-485总线网络一般要使用终接电阻进行匹配。

但在短距离与低速率下可以不用考虑终端匹配。

那么在什么情况下不用考虑匹配呢?理论上,在每个接收数据信号的中点进行采样时,只要反射信号在开始采样时衰减到足够低就可以不考虑匹配。

但这在实际上难以掌握,美国MAXIM公司有篇文章提到一条经验性的原则可以用来判断在什么样的数据速率和电缆长度时需要进行匹配:当信号的转换时间<上升或下降时间)超过电信号沿总线单向传输所需时间的3倍以上时就可以不加匹配。

例如具有限斜率特性的RS-485接口MAX483输出信号的上升或下降时间最小为250ns,典型双绞线上的信号传输速率约为0.2m/ns<24AWG PVC电缆),那么只要数据速率在250kb/s以内、电缆长度不超过16M,采用MAX483作为RS-485接口时就可以不加终端匹配。

一般终端匹配采用终接电阻方法,前文已有提及,RS-422在总线电缆的远端并接电阻,RS-485则应在总线电缆的开始和末端都需并接终接电阻。

终接电阻一般在RS-422网络中取100Ω,在RS-485网络中取120Ω。

相当于电缆特性阻抗的电阻,因为大多数双绞线电缆特性阻抗大约在100~120Ω。

这种匹配方法简单有效,但有一个缺点,匹配电阻要消耗较大功率,对于功耗限制比较严格的系统不太适合。

另外一种比较省电的匹配方式是RC匹配,如图9。

利用一只电容C隔断直流成分可以节省大部分功率。

但电容C的取值是个难点,需要在功耗和匹配质量间进行折衷。

还有一种采用二极管的匹配方法,如图10。

这种方案虽未实现真正的“匹配”,但它利用二极管的钳位作用能迅速削弱反射信号,达到改善信号质量的目的。

节能效果显著。

图9 图10
RS-422与RS-485的接地问题
电子系统接地是很重要的,但常常被忽视。

接地处理不当往往会导致电子系统不能稳定工作甚至危及系统安全。

RS-422与RS-485传输网络的接地同样也是很重要的,因为接地系统不合理会影响整个网络的稳定性,尤其是在工作环境比较恶劣和传输距离较远的情况下,对于接地的要求更为严格。

否则接口损坏率较高。

很多情况下,连接RS-422、RS-485通信链路时只是简单地用一对双绞线将各个接口的“A”、“B”端连接起来。

而忽略了信号地的连接,这种连接方法在许多场合是能正常工作的,但却埋下了很大的隐患,这有下面二个原因:
1.共模干扰问题:正如前文已述,RS-422与RS-485接口均采用差分方式传输信号方式,并不需要相对于某个参照点来检测信号,系统只需检测两线之间的电位差就可以了。

但人们往往忽视了收发器有一定的共模电压范围,如RS-422共模电压范围为-7~+7V,而RS-485收发器共模电压范围为-7~+12V,只有满足上述条件,整个网络才能正常工作。

当网络线路中共模电压超出此范围时就会影响通信的稳定可靠,甚至损坏接口。

以图11为例,当发送驱动器A向接收器B发送数据时,发送驱动器A的输出共模电压为VOS,因为两个系统具有各自独立的接地系统,存在着地电位差VGPD。

那么,接收器输入端的共模电压VCM就会达到VCM=VOS+VGPD。

RS-422与RS-485标准均规定VOS≤3V,但VGPD可能会有很大幅度<十几伏甚至数十伏),并可能伴有强干扰信号,致使接收器共模输入VCM超出正常范围,并在传输线路上产生干扰电流,轻则影响正常通信,重则损坏通信接口电路。

图11
2.<EMI)问题:发送驱动器输出信号中的共模部分需要一个返回通路,如没有一个低阻的返回通道<信号地),就会以辐射的形式返回源端,整个总线就会像一个巨大的天线向外辐射电磁波。

因为上述原因,RS-422、RS-485尽管采用差分平衡传输方式,但对整个RS-422或RS-485网络,必须有一条低阻的信号地。

一条低阻的信号地将两个接口的工作地连接起来,使共模干扰电压VGPD被短路。

这条信号地可以是额外的一条线<非屏蔽双绞线),或者是屏蔽双绞线的屏蔽层。

这是最通常的接地方法。

值得注意的是,这种做法仅对高阻型共模干扰有效,因为干扰源内阻大,短接后不会形成很大的接地环路电流,对于通信不会有很大影响。

当共模干扰源内阻较低时,会在接地线上形成较大的环路电流,影响正常通信。

笔者认为,可以采取以下三种措施:<1)如果干扰源内阻不是非常小,可以在接地线上加限流电阻以限制干扰电流。

接地电阻的增加可能会使共模电压升高,但只要控制在适当的范围内就不会影响正常通信。

<2)采用浮地技术,隔断接地环路。

这是较常用也是十分有效的一种方法,当共模干扰内阻很小时上述方法已不能奏效,此时可以考虑将引入干扰的节点<例如处于恶劣的工作环境的现场设备)浮置起来<也就是系统的电路地与机壳或大地隔离),这样就隔断了接地环路,不会形成很大的环路电流。

<3)采用隔离接口。

有些情况下,出于安全或其它方面的考虑,电路地必须与机壳或大地相连,不能悬浮,这时可以采用隔离接口来隔断接地回路,但是仍然应该有一条地线将隔离侧的公共端与其它接口的工作地相连。

参见图12。

图12
RS-422与RS-485的网络失效保护
RS-422与RS-485标准都规定了接收器门限为±200mV。

这样规定能够提供比较高的噪声抑制能力,如前文所述,当接收器A电平比B电平高+200mV以上时,输出为正逻辑,反之,则输出为负逻辑。

但因为第三态的存在,即在主机在发端发完一个信息数据后,将总线置于第三态,即总线空闲时没有任何信号驱动总线,使AB之间的电压在-200~+200mV 直至趋于0V,这带来了一个问题:接收器输出状态不确定。

如果接收机的输出为0V,网络中从机将把其解释为一个新的启动位,并试图读取后续字节,因为永远不会有停止位,产生一个帧错误结果,不再有设备请求总线,网络陷于瘫痪状态。

除上述所述的总线空闲会造成两线电压差低于200mV的情况外,开路或短路时也会出现这种情况。

故应采取一定的措施避免接收器处于不确定状态。

图13
通常是在总线上加偏置,当总线空闲或开路时,利用偏置电阻将总线偏置在一个确定的状态<差分电压≥-200mV)。

如图13。

将A上拉到地,B下拉到5V,电阻的典型值是1k Ω,具体数值随电缆的电容变化而变化。

上述方法是比较经典的方法,但它仍然不能解决总线短路时的问题,有些厂家将接收门限移到-200mV/-50mV,可解决这个问题。

例如Maxim公司的MAX3080系列RS-485接口,不仅省去了外部偏置电阻,而且解决了总线短路情况下的失效保护问题。

RS-422与RS-485的瞬态保护
前文提到的信号接地措施,只对低频率的共模干扰有保护作用,对于频率很高的瞬态干扰就无能为力了。

因为传输线对高频信号而言就是相当于电感,因此对于高频瞬态干扰,接地线实际等同于开路。

这样的瞬态干扰虽然持续时间短暂,但可能会有成百上千伏的电压。

实际应用环境下还是存在高频瞬态干扰的可能。

一般在切换大功率感性负载如电机、变压器、继电器等或闪电过程中都会产生幅度很高的瞬态干扰,如果不加以适当防护就会损坏RS-422或RS-485通信接口。

对于这种瞬态干扰可以采用隔离或旁路的方法加以防护。

1.隔离保护方法。

这种方案实际上将瞬态高压转移到隔离接口中的电隔离层上,因为隔离层的高绝缘电阻,不会产生损害性的浪涌电流,起到保护接口的作用。

通常采用高频变压器、光耦等元件实现接口的电气隔离,已有器件厂商将所有这些元件集成在一片IC 中,使用起来非常简便,如Maxim公司的MAX1480/MAX1490,隔离电压可达2500V。

这种方案的优点是可以承受高电压、持续时间较长的瞬态干扰,实现起来也比较容易,缺点是成本较高。

2.旁路保护方法。

这种方案利用瞬态抑制元件<如TVS、MOV、气体放电管等)将危害性的瞬态能量旁路到大地,优点是成本较低,缺点是保护能力有限,只能保护一定能量以内的瞬态干扰,持续时间不能很长,而且需要有一条良好的连接大地的通道,实现起来比
较困难。

实际应用中是将上述两种方案结合起来灵活加以运用,如图14。

在这种方法中,隔离接口对大幅度瞬态干扰进行隔离,旁路元件则保护隔离接口不被过高的瞬态电压击穿。

常见的I/O设备及其与PC间的连接方法
1、PC-Based设备
常见的PC-Based设备及其通讯连接方式见表。

常见的PC-Based设备及其通讯连接方式
2、PLC设备
常见的PLC设备及其通讯连接方式见表。

常见的PLC设备及其通讯连接方式
3、智能指示、控制仪表及控制器
目前国内外的智能仪表厂商有数千家,产品种类繁多,难以归纳,其中数字指示仪、单<多)回路调节器、流量积算仪、智能终端、楼宇自控设备所占比重较大,这里不一一列举。

这些仪表与计算机间的通讯方式以RS485居多,但越来越多的产品会增加现场总线的通讯接口,智能控制器、楼宇自控设备使用现场总线的较多<如LonWorks、C-Bus等)。

在这方面较有影响的厂商有霍尼韦尔、横河、富士电机、山武、欧陆、慕尔、ABB、H&B、梅特勒-托利多、GEFRAN等。

计算机与PLC的通讯
可编程序控制器<PLC)都有一个编程口。

以日本三菱公司生产的PLC为例<包括FX系列和A系列),其编程口为RS-422格式,根据PLC型号不同又分为8针座编程口和25针座编程口。

对于后者,可直接将SC—08编程电缆将PLC的编程口和微型计算机的RS—232
口连接起来;对于后者,则还需要一根转换电缆将PLC 的8针座编程口和25针编程电缆相连。

无论何种情况,一旦将PLC用户程序由微型计算机编程环境传到PLC 用户程序区,其编程口大多就没有被再利用。

其实,这是一种浪费。

也就是说,可利用此编程口实现微型计算机和PLC 的数据通讯,将PLC的工作状态纳入微型计算机管理之下。

编程口操作命令类型与通讯端口初始化
串行通讯是计算机与其它机器之间进行通讯的一种常用方法,在WINDOWS操作系统中提供了实现各种串行通讯的API函数。

通过SC—08编程电缆或FX232AW模块,可将微型计算机的串行通讯口RS—232和PLC 的编程口连接起来,这样微型计算机就可对PLC的RAM 区数据进行读、写操作。

由PLC本身所具有的特性,可对PLC进行以下四种类型的操作:
<1)位元件或字元件状态读操作<CMD0);
<2)位元件或字元件状态写操作<CMD1);
<3)位元件强制ON操作<CMD7);
<4)位元件强制OFF操作<CMD8)。

另外,在进行上述四类操作以前,首先要对端口进行初始化操作,即设定通讯协议<包括设置通讯波特率、数据位数、数据停止位及奇偶校验)。

在WINDOWS的SDK中定义了一个结构DCB,该结构详细地说明了如何对通讯端口进行控制,所以通讯端口的初始化也是围绕着对这个结构的正确设置为中心进行的。

用VC++语言实现端口初始化如下:
BOOL CSerial::Open(int nPort>
{
//nPort 为微型计算机串行通讯口端口号。

nport=1为端口1;nPort=2为端口2。

char szPort\[15\]。

DCB dob。

m_hIDComDev=CreateFile(szPort, GENERIC_READ│
GENERIC_WRITE,O,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL│
FILE_FLAG_OVERLAPPED,NULL>。

dcb.DCB1ength=sizeof(DCB>。

GetCommState(m_hIDComDev,&dcb>。

//取得通讯资源当前设置
dcb.BaudRate=9600。

//设定波特率为9600
dcb.ByteSize=7。

//7数据位
dcb.Parity=2。

//偶校验
dcb.StopBits=0。

//设定1个停止位
if(SetCommState(m_hIDComDev,&dcb>return(TRUE>。

else return(FALSE>。

//设置端口,若设置成功则返回TRUE,否则返回FALSE

需要说明的是CSerial是一个用于串行通讯的类,它包含了进行串行通讯的所需的函数。

除上述端口初始化成员函数Open外,还包括另两个重要成员函数:一个是endData,把数据从一个缓冲区发送到串行端口。

另一个是ReadData,从端口的接收缓冲区中读入数据。

其次,在每进行一次上述四类操作中的一种操作以前,还要进行握手联络。

对PLC发请求讯号ENQ<代码为OX05),然后读PLC 的响应讯号。

如果读到的响应讯号为ACK<代码为OX06),则表示PLC已准备就绪,等待接收通讯数据。

握手联络VC++语言示PLC已准备就绪,等待接收通讯数据。

握手联络VC++语言实现为:
BOOL CNTJD1g::ReadFromPLC(char *Read_char char *Read_address,int
Read_bytes>
{
CSerial Serial。

//用于串行通讯的类
char read_BUFFER。

if(Serial.Open(2>//初始化串行口通讯口COM2
{ Serial.SendData(&ENQ_request,1>。

//发送联络讯号
Sleep(1000>。

//等待1秒钟
Serial.ReadData(&read_BUFFER,1>。

//读取PLC响应讯号
if(read_BUFFER==ACK>
{ 如果PLC响应讯号等于ACK,则进行上述四种操作:}}
Serial.Close(>://操作完毕后,关闭通讯口
}
编程口命令操作
<1)位元件或字元件状态读操作
操作对象元件:PLC内部的X、Y、M、S、T、C、D元件;命令格式:
说明:①为读命令起始标志STX,代码为OX02;
②为位元件或字元件状态读命令CMDO,命令代码为OX30;
③为读位元件或字元件的4位起始地址,高位先发,低位后发,且是以ASCII码的形式发送;
④为一次读取位元件或字元件的个数,最多一次可读取OXff个字节的元件,以ASCII码的形式发送;
⑤为停止位标志ETX,代码为OX03;
⑥为2位和校验,和累计为②、③、④项代码,取其和最低两位转化成ASCII码,高位先发,低位后发。

在发送完上述命令格式代码后,就可直接读取PLC响应的信息。

响应信息格式如下:
VC++语言实现:
BOOL CNTJDlg::ReadFromPLC(char *Read_char char
*Read_address, int Read_bytes>
{
char senddatasum_CHECK\[2\]。

char readdatasum_CHECK\[2\]。

char
total_DATABYTES\[2\]。

char readdatasum_check\[2\]。

int readdata_sum。

int datasum_check=0。

int i。

Serial.SendData(&STX_start,1>。

/向PLC发送“开始”标志代码
Serial.SendData(&CMDO_read,1>。

//发送“读”命令代码
datasum_check+=CMDO_read。

for(i=0。

i<4。

i++>{Serial.SendData(&Read_address\[i\],1>。

//发送起始元件地址的ASCII代码datasum_check+=Read_address\[i\]。

}
Change to ASCII(total DATABYTES,Read_bytes>。

//将字节数转化成ASCII代码
for (i=0。

i<2。

i++>{Serial.SendData(&total_DATABYTES\[i\],1>。

//发送元件字节数的ASCII代码>datasum_check+total_DATABYTES\[i\]。

}
Serial.SendData(&ETX_end,1>。

//发送“结束”标志代码
senddatasum_CHECK+ETX_end。

Change_to_ASCII(senddatasum_CHECK,senddatasum_CHECK>。

//将“和”转化成ASCII码
for (i=0。

i<2。

i++> Serial.SendData(&senddatasum_CHECK\[i\],1>。

Sleep(1000>。

//等待PLC响应
Serial.ReadData(&read_BUFFER,1>。

if(read_BUFFER==STX_start>{
readdata_sum=0。

for(i=0。

i<2*Read_bytes。

i++>{Serial.ReadData(&Read_char\[i\],1>。

//读Read_bytes个字节readdata_sum+Read_char\[i\]。

}
Serial.ReadData(&read_BUFFER,1>。

if(read_BUFFER==ETX_end>{Serial.ReadData(readdatasum_CHECK,2>。

//读入的“和”的低2位ASCII码Readdata_sum+=ETX_end。

}
Change_to_ASCII(readdatasum_check,readdata_sum>。

//将计算得到的“和”转化成ASCII码
if(*readdatasum_CHECK==*readdatasum_check>//“和”校验
{ AfxMessageBox(“数据读出成功!”>return TRUE。

}
else { AfxMessageBox(“校验错误”>return FALSE.}
}
<2)位元件或字元件状态写操作
操作对象元件:同3<1);命令格式:
说明:①为写命令起始标志STX,代码为OX02;
②为位元件或字元件状态写命令CMD1,命令代码为OX31;
③为写位元件或字元件的4位起始地址,高位先发,低位后发,且是以ASCII码的形式发送;
④为一次写入位元件或字元件的个数,以ASCII码的形式发送;
⑤为待写到PLC RAM区的数据DATA,以ASCII码形式发送;
⑥为停止位标志ETX,代码为OX03。

⑦为2位和校验,和累计为②、③、④项代码,取其和最低两位转化成ASCII码,高位先发,低位后发。

VC++语言实现:
BOOL CNTJDlg::WritePLC(char *data_ADDRESS,char *Write_ASC,int bytesnumber>
{
char total_BYTES\[2\]。

char senddatasum_CHECK\[2\]。

char read_BUFFER。

char read_finishBUFFER。

int datasum_check=0。

int i=0。

Serial.SendData(&STX_start,1>。

//向PLC发送“开始”标志代码
datasum_check=0。

Serial.SendData(&CMD1_write,1>。

//发送“写”命令代码
datasum_check+CMD1_write。

for(i=0。

i<4。

i++> {Serial.SendData(&data_ADDRESS\[i\],1>。

//发送起始元件地址的ASCII码
datasum_check+=data_ADDRESS\[i\]。

Change_to_ASCII(total_DATABYTES,bytesnumber>。

//将字节数转化成ASCII码
for(i=0。

i<2。

i++>
{
Serial.SendData(&total_BYTES\,1>。

//发送元件字节数的ASCII代码
datasum_check+=total_BYTES\[i\]。

}
for {i=0。

i<bytesnumber*2。

i++>
{
Serial.SendData(&Write_ASC\[i\],1>。

//发送要写入的数据的ASCII码
datasum_check+=Write_ASC\[i\]。

}
Serial.SendData(&ETX_end,1>。

//发送“结束”标志代码
datasum_check+=ETX_end。

Change_to_ASCII(senddatasum_CHECK,datasum_check>。

//将“和”转化成ASCII 码
Serial.SendData(&senddatasum_CHECK,2>。

Sleep(1000>。

Serial.ReadData(&read_finishBUFFER,1>。

if (read_finishBUFFER==ACK_reply>
{AfxMessageBox(“数据写入 OK”>return TRUE。

}
else {AfxMessageBox(“数据写入失败”>return FALSE。

}
<3)位元件强制ON操作
操作对象:X、Y、M、S、T、C元件。

相关文档
最新文档