摘要:PLC以其固有的特性,在闸阀门智能化处理中得到了广泛的应用。解决好PLC与闸阀门开度检测装置间的数据传输接口是实现闸阀门高效、可靠、安全运行的关键。虽然,PLC提供SSI输入模块,但这类模块价格太高,需要配置专用电缆和处理软件。利用单片机实现与闸阀门开度检测装置(SSI)的输入接口,实现串行数据转换成并行数据与PLC数值量输入模块连接的输出接口。这样既降低了成本,又简化了PLC的编程。
关键词:单片机 闸阀门 检测方法
闸阀门开度检测装置在淮安三线船闸工程中,是实现闸阀门安全、高效和智能化运行的主要设备之一。该检测装置运用主要目的为:
(1)在闸阀门启闭操作时,用于实时指示闸阀门的开度位置,以利于操作员及时掌握闸阀门的运行情况;
(2)闸阀门开度参与闸阀门的运行控制,如使阀门开启至任意设定开度,实时监视阀门在这一设定开度时的下滑情况,并根据阀门下滑至不同关键位置时,立即采取相应的处理措施。
(3)控制左右人字闸门同步运行与平稳变速运行。
ROQ425是德国海德汉(HENDENHAIN)的(13位 12位)绝对编码器。特别适合于高精度、大量程闸阀门行程测量和控制的场合,是构成闸阀门检测装置的主要部件。具有如下主要特点:
(1)分辨率高,最高可达8192线/转(13位);
(2)量程大,最高可达4096转(12位);
(3)掉电位置保护,无论开度仪掉电多少时间,系统上电后,ROQ425总能准确地测量出闸门当前的开度。
(4)数据输出接口,采用串行同步接口(SSI)传输数据。
PLC以其固有的特性,在闸阀门智能化处理中得到了广泛的应用。解决好PLC与闸阀门开度检测装置间的数据传输接口是实现闸阀门高效、可靠、安全运行的关键。虽然,PLC提供SSI输入模块,但这类模块价格太高,需要配置专用电缆和处理软件。利用单片机实现与闸阀门开度检测装置(SSI)的输入接口,实现串行数据转换成并行数据与PLC数值量输入模块连接的输出接口。这样既降低了成本,又简化了PLC的编程。
1. 硬件设计
硬件设计方案主要实现
(1)与ROQ425的SSI连接;
(2)与PLC模拟量输入模块和MODBUS口的连接;
(3)完成输入串行数据(ROQ425 SSI)到输出4-20mA的转换。
(4)完成输入串行数据(ROQ425 SSI)通过MODBUS口输出到PLC
1.1 ROQ425 SSI接口介绍
ROQ425 SSI接口电压为5V±5%,空载时最大电流功耗为250mA。采用差分SN65LBC176线接收/驱动器进行数据传输,最远传输距离可达100m。ROQ425内部接口见图1。
ROQ425是多圈绝对型旋转编码器,每圈用13位表示精度,用12位记录圈数。因此,开度绝对位置值采用25位字长表示。数据发送时序关系见图2,其工作原理为:
- 不发送数据时,CLOCK为高电平。
- 数据发送过程:当ROQ425接收到CLOCK发送周期(nT)的第一个下降沿时,ROQ425读取25位字长的绝对位置值存入数据缓存器。数据缓存器中数据随着CLOCK发送周期的上升沿串行同步发送数据,第一个发出的数据位是绝对位置值的第25位(MSB),最后一个发出的数据位是绝对位置值的第1位。
- 中断数据发送:在数据发送过程中,当CLOCK为高电平时间超过t3(35us)时,ROQ425终止当前数据发送周期,为下一个重新开始的发送周期做好准备。
- 数据重发:当完成一个绝对位置值的数据字发送周期后,DATA维持t3时间的低电平。若在t3(12~35us)内,CLOCK开始一个新的发送周期,就会重发刚才发送的绝对位置值数据。
1.2 硬件工作原理
硬件设计由SSI接口、I/O接口、单片机和电源四部分组成。
(1)SSI接口选用ROQ425推荐的RS422接口芯片MAX488。
(2)I/O接口采用光电耦合器隔离,DA模块采用AD7541和AD694。MODBUS接口模块采用MAX232E。
(3)单片机选用高性能的AT89C51(单字长指令、定时/计数器、看门狗)
(4)选用24VDC输入5VDC输出和24VDC输入15VDC输出的DC/DC模块电源。
原理图如下
2.软件设计
通过对AT89C51进行编程,达到实时将SSI接口数据转换成4-20输出或通过MODBUS口传送至PLC系统的目的。主要流程如下:
- 第一步 :初始化设置。包括串口设置,中断设置,PLC地址的设置,零点设置等
- 第二步:读取ROQ425数据并转换成十进制
- 第三步:将转换过的数据通过并口和串口输出
- 第四步:重复第二步
下面是AT89C51的部分源程序:
#include <reg51.h>
#include <stdio.h> /* define I/O functions */
#include <absacc.h> /* define absacc functions */
#include <STDLIB.h> /* define absacc functions */
#include <intrins.h> /*#define uchar unsigned char*/
#define _Nop() _nop_()
typedef unsigned int word;
typedef unsigned char byte;
typedef unsigned long dword;
static word data da,db,dc,df,p,crc1,cir,high;
static dword data da1,db1,dc1,df1,dd,de,max,zero,zero2,dcb;
static byte data show[7],show1[4],show2[4],sendm[8],s[4],bb[4];
static byte data dd1,watch,kk,t[1],dd2[1];
code byte disp[16]={0x77,0x41,0x3b,0x6b,0x4d,0x6e,0x7e,0x43,0x7f,0x6f,0x5f,0x7c,0x36,0x79,0x3e,0x1e};
void readgray();/*读取ROQ425数据*/
void delay();
void i_start();
void i_stop();
void i_init();
void i_send(byte);
void display();
void change(dword);
void change1(dword);
void setzero();
void zero1();
void nub();
void addr();
void cir1();
void e_start();
void e_stop();
void e_send(byte);
byte e_recevie();
void e_ack(bit);
void e_send1(dword);
bit isend(byte,byte,byte *,byte);
bit ireceive(byte,byte,byte *,byte);
void watchdog();
void one();
void two();
void three();
void one1();
void two1();
void three1();
void pos();
void res();
void comsend(byte);
word crc16(byte *);
byte shj();
void main()
{
register i,j,k,x;
bit d;
dcb=0;
show[0]=0x70;
show[1]=0x00;
show[2]=0x27;
display();
for (i=0;i<4;i )
{
show1[i]=0;
show2[i]=0;
}
SCON=0xc8;/*采用方式3 */
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
ET1=0;
ES=0;
EA=0;
high=0x07;
max=8000;
dd1=0;
sda1=1;
delay();
sda1=0;
dd2[0]=0;
while(1)
{
for (j=0;j<4;j )
{
for (x=0;x<8;x )
{
zero2*=2;
z=(bit)(show2[j]&0x80);
if (z==1)
zero2 ;
show2[j]=show2[j]<<1;
}
}
zero=zero2;
p=0;
watchdog();
txd=1;
readgray();
watchdog();
dd=da & 0x0fff;
de=db & 0x1fff;
dc1=dd*8192 de;
P0=dc1 & 0x000000ff;//(dc1 & 0x000001fe)>>1;
P2=(dc1 & 0x00000f00)>>8;//(dc1 & 0x00001e00)>>9;
if(t[0]==1)
{
if((zero>=0)&&(zero<=10000000))
one();
else
if((zero>10000000)&&(zero<=33390591))
two();
else
three();
}
else
{
if((zero>=0)&&(zero<=10000000))
one1();
else
if((zero>10000000)&&(zero<=33390591))
two1();
else
three1();
}
sendm[0]=0x06;
sendm[1]=0x06;
sendm[2]=0x00;
sendm[3]=0x05;
sendm[4]=dc1/256;
sendm[5]=dc1%6;
crc1=crc16(sendm);
sendm[6]=crc1 / 256;
sendm[7]=crc1 & 0xff;
rd=1;
for(i=0;i<8;i )
{
ACC=sendm[i];
TB8=par;
comsend(sendm[i]);
}
watchdog();
display();
}//end while
}//end main
3.结束语
采用上述方法实现PLC与闸阀门开度检测装置之间的连接。不仅具有成本低、PLC编程简单的特点,而且具有高可靠性。