智能仪表和现场总线的出现标志着工业控制领域网络时代的到来,成为工业控制的主流。目前国际上已经出现了多种现场总线和相应的通信协议,但是其系统造价对于许多中小型应用仍显过高。而RS485总线以其构造简单、造价低廉、可选芯片多、便于维护等特点在众多工业控制系统中得到应用。
1、 RS485总线及现有工作方式的特点
RS485总线以双绞线为物理介质,工作在半双工的通信状态下,即同一时刻,总线上只能有一个节点成为主节点而处于发送状态,其他所有节点必须处于接收状态。如果同一时刻有两个以上的节点处于发送状态,将导致所有发送方的数据发送失败,即所谓总线冲突。为了避免总线冲突,RS485总线具有以下特点:
以工作模式来说,一般的RS485总线工作在主从模式下。整个通信总线系统由一个主节点、若干个从节点组成,由主节点不断地轮流查询从节点是否有通信需求。如果有则将总线控制权交给某一从节点,从节点发送完毕后立刻交还总线控制权。另外还有一种“轮主轮从”的工作方式,即让总线控制权在各个节点间以类似令牌环的方式传递,得到控制权的节点成为主节点,其它节点成为从节点。一个节点在发送完数据的同时,将总线控制权交给相邻的节点,而这个节点在处理完本节点的通信需求后再把控制权向下传递。令牌环式的RS485工作方式如图1所示。
从通信节点来讲,RS485总线上的节点必须具备将自己的驱动器切换到高阻态的功能,以便在发送完数据后不会对总线状态造成影响。这种驱动器实行发送态—高阻态切换的一个影响是?押从发送数据完毕到设备切换为高阻态,需要一个转换延迟。这个转换延迟是2线制通信中一个很重要的参数。这个时间不能太短,否则发出的字符的最后一部分因为尚未在总线上建立起来而导致丢失。同时这个时间也不能太长,否则在发送端还未转为高阻态时其他设备已经开始发送数据,会导致总线冲突。因此2线制RS485总线上的主设备必须知道所有从设备的反应时间,并保证在从设备反应之前把驱动器设为高阻态,以接收从设备的数据。常用设备的转换延迟是当前波特率发送一个字节的时间。
以上为适应RS485总线的特殊之处而采用的工作方式也引入了一些不足。首先,上面提到的两种总线工作方式在很多对实时性、可靠性要求高的工业控制场合有较大的局限性。主要原因是主从式总线的从节点无发起通信的权利,相互之间的通信需要通过主节点中转。而“轮主轮从”总线上的各个节点由于等待总线控制权的时间未知,实时性也无法保证。同时,如果主从式的主节点或者是“轮主轮从”式的获取令牌的节点出现故障,整个总线的工作将瘫痪,风险过于集中。其次,对驱动器实行“发送态—高阻态”切换以及考虑切换延迟等要求使编程变得复杂。在上电瞬间、CPU损坏或者是程序跑飞的情况下,还需要考虑复杂的故障保护等问题,否则将容易引起总线故障。
2、 RS485总线上CSMA/CD的实现
为了解决各个节点主动获取总线控制权的问题,人们想到了利用监听总线状态的方式实现总线控制权的本地判断和获取,也就是CSMA/CD协议实际上做的工作。即所有节点在发送前监听总线上是否有其他节点在发送数据,如果有,就暂时不发送。另外在发送数据的同时,边发送边监听,如果监听到冲突则冲突双方都停止发送。这样做,既能保证每一个节点都具有发起通信的权利,又能尽量减少发生总线冲突的机会,提高整个系统的吞吐量。
已有的一种实现方法是将总线接收器的输出端反相后接到CPU的外部中断管脚,如图2所示。用触发中断的方式判断总线上是否有数据传输,同时结合定时器中断判断总线是否空闲。如果总线空闲,就获得总线控制权,发送数据;然后用监听自己发送数据的办法判断是否发生总线冲突。该方法解决了总线控制权分配的时延问题,但是需要使用至少4个管脚(INT0、RXD、TXD、驱动器使能管脚),并且占用外部中断和内部定时器中断,需要利用软件监听发送的数据避免总线冲突。系统资源耗费较多,编程复杂,在一些场合的应用也有局限性。本文在以上方法的基础上提出了一种利用硬件监听总线状态的方法,真正实现CSMA/CD协议。同时减少了系统资源的占用率,简化了总线冲突的判断。另外实现了驱动器的无延迟自动切换,进一步提高了系统的实时性。该系统工作稳定、可靠,并且大大提高了通信的实时性,特别适合实时分布式控制的场合。
2.1 系统框图
系统由总线状态判断逻辑、驱动器自动切换逻辑两部分组成,如图3所示。系统资源只占用CPU的3个管脚:RXD、TXD、总线状态指示脚,不占用任何中断。在软件实现方面由于采用了硬件判断总线状态而变得非常简单,只需要对标准的232通信程序做微小修改即可。
2.2 总线状态判断逻辑
该电路由双RS485总线接收器构成,两个接收器的输出相与后得到总线状态信号。偏置电阻网络的对称形式使得在总线没有被驱动的情况下,两条总线的电平相等。总线状态判断逻辑如图4所示。由于接收器的两个接入点电平不同,所以当总线处于高阻状态或者总线被短路时,两个接收器都是高电平输出,总线状态为高电平。因为A、B线通过6。8kΩ电阻分别接入两个接收器的不同接收端,所以当总线出现任何一个确定的逻辑状态时,都将引起其中一个接收器的输出变为低电平,这样总线状态就变为低电平,表明总线被占用。经过理论计算和EWB仿真,该网络从A、B点看接入阻抗为12。2kΩ,恰好满足RS485协议的接收器输入阻抗要求。
2.3 驱动器无延迟自动切换逻辑
为了实现驱动器的无延迟自动切换,TXD信号反相后接到驱动器使能,而驱动器输入直接接地,如图5所示。这样处理使驱动器只在数据为0时打开,把数据0发出去。而当数据为1或者无数据时立刻关闭,缩短了切换时间。但是这样做,使得数据1无法被正常发送出去。为使串行数据能被正确地接收,有两个办法产生数据中的1。第一个办法,使用总线判断电路中的正向接收器的输出端?穴OUT+?雪作为RXD信号,该信号在总线空闲、开路和短路时输出逻辑1,并且与RXD信号同相。第二个办法,使用类似MAX3080自带故障保护(fail-safe)功能的芯片作为接收器。MAX3080将接收器的触发门限电压从-200mv~+200mv调整为-200mv~-50mv,也能够在总线空闲、开路和短路时输出逻辑1。如果总线上的每一个节点都使用这些方法,那么所有节点都可以实现驱动器无延迟自动切换而不必担心数据中的1不能被正确接收。
2.4 软件的实现
发送数据方面,只需将标准串口函数putc()封装成一个函数RS485PutString()发送数据即可。在RS485PutString()函数中,能够方便地实现各种总线状态判断策略,甚至是CSMA/CD协议,实现载波监听,边发送边监听。也可以在此函数的基础上进行诸如定义不同数据包的实时性级别、定义总线超时判断等高级编程。
该函数的主要流程如图6。
判断总线状态就是简单地读取总线状态判断电路的输出,高为空闲,低为总线已被占用。为了减少误判,通常在判断总线状态为空闲后还要继续判断一段时间,具体的总线状态判断策略要根据通信协议进行调整。
如果判断总线空闲,即可进行数据发送。在发送过程中可以方便地继续读取总线状态以进行边发送边监听的冲突检测。一旦发现冲突发生,发送方放弃本次数据传输而转入强化冲突流程(继续发送几个0x00以使各方都确认发生了总线冲突),然后再进入总线侦听流程。以往的RS485总线冲突检测处理机制是通过对自己所发送的数据进行监听接收,然后比较接收到的数据与发送的数据是否相符,判断是否发生总线冲突,在软件实现上比较复杂。而本系统的冲突检测非常简单:发送完一个字节就读取一次总线状态指示管脚的状态,如果发现总线被占用,就是发生了总线冲突。
接收程序方面,因为接收器常开,所以仍然可以使用串行接收器的中断服务程序,将接收到的数据放入缓冲区,然后由命令解释程序处理接收到的命令。本质上与RS232的串口通信程序完全一样,只是如果接收器是常开的话,在自己发送数据时,要记住将串行接收器中断关闭,发送完毕后再打开,以避免运行不必要的中断服务程序。
另外,还可以结合驱动器和总线状态判断逻辑对总线进行开路和短路的检测/报警。具体说就是某一个节点使能总线驱动器,然后判断总线状态,如果仍然显示总线空闲,说明总线短路或者总线到总线状态判断逻辑之间开路了。
2.5 存在的不足之处
该方法中的总线状态判断逻辑对逻辑0状态的要求比较高,需要B线电平比A线高约1。1V才能得到低电平。如果采用总线判断电路中的正向接收器的输出端(OUT+)作为RXD信号,就会因为对逻辑0的要求而不满足RS485的-200mV门限电平标准。若采用另一个具有故障保护功能的接收器并联的话,固然能满足-200mV门限电平标准,但整个节点的输入阻抗将降低到6kΩ。
以上不足之处都在于无法完全满足标准RS485总线标准,但在特定条件下是不会影响工作效果的。例如阻抗虽然降低了,但是当节点数不超过16时,是能够很好地工作的。
实验表明,这种实现了CSMA/CD的多主式RS485总线工作稳定,可靠性高,大大提高了实时性。特别适合于强调实时性的分布式控制系统,能够方便地实现点与点之间的控制信息实时交换。