组态王与单片机通信协议1.docx

上传人:b****8 文档编号:11951099 上传时间:2023-06-03 格式:DOCX 页数:23 大小:58.66KB
下载 相关 举报
组态王与单片机通信协议1.docx_第1页
第1页 / 共23页
组态王与单片机通信协议1.docx_第2页
第2页 / 共23页
组态王与单片机通信协议1.docx_第3页
第3页 / 共23页
组态王与单片机通信协议1.docx_第4页
第4页 / 共23页
组态王与单片机通信协议1.docx_第5页
第5页 / 共23页
组态王与单片机通信协议1.docx_第6页
第6页 / 共23页
组态王与单片机通信协议1.docx_第7页
第7页 / 共23页
组态王与单片机通信协议1.docx_第8页
第8页 / 共23页
组态王与单片机通信协议1.docx_第9页
第9页 / 共23页
组态王与单片机通信协议1.docx_第10页
第10页 / 共23页
组态王与单片机通信协议1.docx_第11页
第11页 / 共23页
组态王与单片机通信协议1.docx_第12页
第12页 / 共23页
组态王与单片机通信协议1.docx_第13页
第13页 / 共23页
组态王与单片机通信协议1.docx_第14页
第14页 / 共23页
组态王与单片机通信协议1.docx_第15页
第15页 / 共23页
组态王与单片机通信协议1.docx_第16页
第16页 / 共23页
组态王与单片机通信协议1.docx_第17页
第17页 / 共23页
组态王与单片机通信协议1.docx_第18页
第18页 / 共23页
组态王与单片机通信协议1.docx_第19页
第19页 / 共23页
组态王与单片机通信协议1.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

组态王与单片机通信协议1.docx

《组态王与单片机通信协议1.docx》由会员分享,可在线阅读,更多相关《组态王与单片机通信协议1.docx(23页珍藏版)》请在冰点文库上搜索。

组态王与单片机通信协议1.docx

组态王与单片机通信协议1

一、    通讯参数:

通讯参数包括数据位,停止位,波特率、校验方式。

数据位、停止位、波特率由单片机决定。

组态王中的设定和单片机一致即可。

校验方式参照“数据传输格式”中相关部分。

二、    数据传输格式:

格式1、组态王发送地址请求格式:

(此时检验位为1)

ENQ

Sta

EOT

CRC

格式2、单片机应答地址格式:

(此时检验位为0)

ACK

Sta

ETX

CRC

格式3、组态王读数据请求格式:

(此时检验位为0)

ENQ

R

DataType

DataAddr

DataNum

EOT

CRC

格式4、单片机应答读数据格式(正确):

(此时检验位为0)

ACK

DataLong

Data….

ETX

CRC

格式5、单片机应答读数据格式(错误):

(此时检验位为0)

NAK

ErrorCode

ETX

CRC

格式6、组态王写数据请求格式:

(此时检验位为0)

ENQ

W

DataType

DataAddr

Data….

EOT

CRC

 

格式7、单片机应答写数据格式(正确):

(此时检验位为0)

ACK

ErrorCode

ETX

CRC

三、时序:

读数据:

组态王

单片机

第一步:

格式1

 

 

第二步:

格式2

第三步:

格式3

 

 

第四步:

格式4或格式5

第五步:

如果第四步单片机执行格式4,结束。

否则,执行格式1。

 

 

第六步:

格式2

第七步:

格式3

 

 

第八步:

格式4或格式5

写数据:

组态王

单片机

第一步:

格式1

 

 

第二步:

格式2

第三步:

格式6

 

 

第四步:

格式7

第五步:

如果第四步单片机执行格式7的ErrorCode=0,结束。

否则,执行格式1。

 

 

第六步:

格式2

第七步:

格式6

 

 

第八步:

格式7

四、协议说明:

 

数据传输:

所有数据均为16进制数

ENQ(头)

H05

询问

请求帧的开始代码

ACK(头)

H06

确认

ACK应答帧的开始代码

NAK(头)

H15

否认

NAK应答帧的开始代码

EOT(尾)

H04

正文的结束

请求帧的结束ASCII代码

ETX(尾)

H03

结束正文

应答帧的结束ASCII代码

Sta:

设备地址1字节

R:

   读标志1字节(0x52)

W:

  写标志1字节(0x57)

DataType;需要交换的数据类型,1字节。

1,字节;2,字,3,浮点型。

DataType的值

含义

1

字节

2

3

浮点数

DataNum:

要读取的数据的数量,1字节。

DataAddr;为数据偏移地址2字节,低字节在前,高字节在后

Data:

实际传输的数据,低字节在前,高字节在后

DataLong:

 单片机返回Data的字节数,2字节,低字节在前,高字节在后

CRC:

为从第一个字节至CRC前的所有字节的异或值,1字节

ErrorCode:

ErrorCode数值

含义

0

正确应答

1

数据类型错误

2

数据范围超限

3

指令无法识别,应为R或W。

4

校验错误

1.通讯口设置:

      通讯方式:

RS-232,RS-485,RS-422均可。

      波特率:

 由单片机决定(2400,4800,9600and19200bps)。

字节数据格式:

由单片机决定。

起始位

数据位

校验位

停止位

 

注意:

在组态王中设置的通讯参数如波特率,数据位,停止位,奇偶校验必须与单片机编程中的通讯参数一致

 

 

2.在组态王中定义设备地址的格式

格式:

##.# 

前面的两个字符是设备地址,范围为0-255,此地址为单片机的地址,由单片机中的程序决定;

后面的一个字符是用户设定是否打包,“0”为不打包、“1”为打包,用户一旦在定义设备时确定了打包,组态王将处理读下位机变量时数据打包的工作。

 

3.在组态王中定义的寄存器格式

寄存器名称

dd上限

dd下限

数据类型

Xdd

65535

0

FLOAT/BYTE/UINT

斜体字dd代表数据地址,此地址与单片机的数据地址相对应。

 

 

注意:

在组态王中定义变量时,一个X寄存器根据所选数据类型(BYTE,UINT,FLOAT)的不同分别占用一个、两个,四个字节,定义不同的数据类型要注意寄存器后面的地址,同一数据区内不可交叉定义不同数据类型的变量。

为提高通讯速度建议用户使用连续的数据区。

 

例如,

1、在单片机中定义从地址0开始的数据类型为BYTE型的变量:

则在组态王中定义相应的变量的寄存器为X0、X1、X2、X3、X4。

,数据类型为BYTE,每个变量占一个字节

2、在单片机中定义从地址100开始的数据类型为UINT型的变量:

则在组态王中定义相应的变量的寄存器为X100、X102、X104、X106、X108。

,数据类型UINT,每个变量占两个字节

3、在单片机中定义从地址200开始的数据类型为FLOAT型的变量:

则在组态王中定义相应的变量的寄存器为X200、X204、X208、X212。

, 数据类型FLOAT,每个变量占四个字节

 

 

3.组态王与单片机通讯的命令格式:

读写格式(除字头、字尾外所有字节均为ASCII码)

 

字头

设备地址

标志

数据地址

数据字节数

数据…

异或

CR

说明;

字头:

1字节1个ASCII码,40H

设备地址:

1字节2个ASCII码,0—255(即0---0x0ffH)

标志:

1字节2个ASCII码,bit0~bit7,

bit0=0:

读,bit0=1:

写。

bit1=0:

不打包。

    bit3bit2=00,数据类型为字节。

    bit3bit2=01,数据类型为字。

    bit3bit2=1x,数据类型为浮点数。

数据地址:

2字节4个ASCII码,0x0000~0xffff

数据字节数:

1字节2个ASCII码,1—100,实际读写的数据的字节数。

数据…:

为实际的数据转换为ASCII码,个数为字节数乘2。

异或:

异或从设备地址到异或字节前,异或值转换成2个ASCII码

CR:

0x0d。

 

通讯尝试恢复命令(COMERROR),请求地址为0的一个BYTE数据

 

3.1.上位机发送读命令

字头

设备地址

标志

数据地址

数据字节数

异或

CR

下位机应答:

若正常:

字头

设备地址

数据字节数

数据…

异或

CR

若不正常:

字头

设备地址

**

异或

CR

 

例1:

读15号仪表,数据地址为15的数据。

其中数据为100,数据类型为字节,不打包。

组态王所发数据为:

 

40

30

46

43

30

30

30

30

46

30

31

37

32

0d

字头

设备地址15

标志

读操作

字节型

不打包

数据地址15

数据字节数1

异或

 

 

若正确:

40

30

46

30

31

36

34

37

35

0d

字头

设备地址15

数据字节数1

数据100

异或

 

若不正确:

40

30

46

2a

2a

37

36

0d

字头

设备地址15

**

异或

 

 

 

 

 

例2:

读15号仪表,数据地址为15的数据。

其中数据为100,数据类型为字节,打包。

组态王所发数据为:

 

40

30

46

43

32

30

30

30

46

30

31

37

30

0d

字头

设备地址15

 

XX文库-让每个人平等地提升自我XX文库-让每个人平等地提升自我标志

读操作

字节型

打包

数据地址15

数据字节数1

异或

 

 

若正确:

40

30

46

30

31

36

34

37

35

0d

字头

设备地址15

数据字节数1

数据100

异或

 

若不正确:

40

30

46

2a

2a

37

36

0d

 

设备地址15

**

异或

 

 

 

 

 

 

3.2.上位机发送写命令

字头

设备地址

标志

数据地址

数据字节数

数据…

异或

CR

下位机应答:

若正常:

字头

设备地址

##

异或

CR

若不正常:

字头

设备地址

**

异或

CR

 

例1:

写15号仪表,数据地址为15。

写数据255,数据类型为字,不打包。

组态王所发数据为:

40

30

46

43

35

30

30

30

46

30

32

30

30

46

46

37

34

0d

字头

设备地址15

标志

写操作

字型

不打包

数据地址15

数据字节数2

数据255

 

异或

 

若正确:

40

30

46

23

23

37

36

0d

字头

设备地址15

##

异或

 

若不正确:

40

30

46

2a

2a

37

36

0d

字头

设备地址15

**

异或

 

 

 

 

例2:

写15号仪表,数据地址为15。

写数据65535,数据类型为浮点型,打包。

组态王所发数据为:

40

30

46

43

46

30

30

30

46

30

34

31

30

46

46

46

46

30

30

字头

设备地址15

标志

写操作

浮点型

打包

数据地址15

数据字节数4

数据65535

30

30

0d

 

 

异或

 

 

 

若正确:

40

30

46

23

23

37

36

0d

字头

设备地址15

##

异或

 

若不正确:

40

30

46

2a

2a

37

36

0d

字头

设备地址15

**

异或

 

 

 

3、注:

   仪表内部数据为十六进制表示的十进制数。

如:

实时测量值为500,则用十六进制表示为1F4H。

仪表通讯传输是将上述十六进制数据转化为标准ASCII码(即一字节的16进制数转化为2个ASCII码──高4位ASCII码+低4位ASCII码)。

 如:

上述数据1F4H(16进制),传输时,转化为ASCII码则为30H、31H、46H、34H。

此浮点数格式的转换:

1)ASCII码到浮点数:

 

floatC4toD(char*c)

{

      BYTE    Hd[30],Jiema[30];

      float  DTc[30];

      float Decimal=0;

 

      memset(Hd,0,sizeof(Hd));

      memset(Jiema,0,sizeof(Jiema));

      memset(DTc,0,sizeof(DTc));

 

      float  returnflo=0;

      BOOL    ShuFU=FALSE,JieFU=FALSE;

 

      if((c[7]>0x40)&&(c[7]<0x47))

             Hd[7]=((c[7] -0x37)&0x0f);

      elseif((c[7]>0x60)&&(c[7]<0x67))

             Hd[7]=((c[7] -0x57)&0x0f);

      else

             Hd[7]=((c[7] -0x30)&0x0f);

 

      if((c[6]>0x40)&&(c[6]<0x47))

             Hd[6]=((c[6] -0x37)&0x0f);

      elseif((c[6]>0x60)&&(c[6]<0x67))

             Hd[6]=((c[6] -0x57)&0x0f);

      else

             Hd[6]=((c[6] -0x30)&0x0f);

 

      DTc[2]=(float)(((float)(Hd[6]*16.0)+(float)(Hd[7]))/256.0);

 

      if((c[5]>0x40)&&(c[5]<0x47))

             Hd[5]=((c[5] -0x37)&0x0f);

      elseif((c[5]>0x60)&&(c[5]<0x67))

             Hd[5]=((c[5] -0x57)&0x0f);

      else

             Hd[5]=((c[5] -0x30)&0x0f);

 

      if((c[4]>0x40)&&(c[4]<0x47))

             Hd[4]=((c[4] -0x37)&0x0f);

      elseif((c[4]>0x60)&&(c[4]<0x67))

             Hd[4]=((c[4] -0x57)&0x0f);

      else

             Hd[4]=((c[4] -0x30)&0x0f);

 

      DTc[1]=(float)((((float)(Hd[4]*16.0)+(float)Hd[5])+DTc[2])/256.0);

 

      if((c[3]>0x40)&&(c[3]<0x47))

             Hd[3]=((c[3] -0x37)&0x0f);

      elseif((c[3]>0x60)&&(c[3]<0x67))

             Hd[3]=((c[3] -0x57)&0x0f);

      else

             Hd[3]=((c[3] -0x30)&0x0f);

 

      if((c[2]>0x40)&&(c[2]<0x47))

             Hd[2]=((c[2] -0x37)&0x0f);

      elseif((c[2]>0x60)&&(c[2]<0x67))

             Hd[2]=((c[2] -0x57)&0x0f);

      else

            Hd[2]=((c[2] -0x30)&0x0f);

 

      Decimal=(float)(((float)(Hd[2]*16)+(float)(Hd[3])+DTc[1])/256.0);

 

      if((c[1]>0x40)&&(c[1]<0x47))

             Jiema[1]=((c[1] -0x37)&0x0f);

      elseif((c[1]>0x60)&&(c[1]<0x67))

             Jiema[1]=((c[1] -0x57)&0x0f);     

      else

             Jiema[1]=((c[1] -0x30)&0x0f);

 

      if((c[0]>0x40)&&(c[0]<0x47))

             Jiema[0]=((c[0] -0x37)&0x0f);

      elseif((c[0]>0x60)&&(c[0]<0x67))

             Jiema[0]=((c[0] -0x57)&0x0f);

      else

             Jiema[0]=((c[0] -0x30)&0x0f);

 

 

      ShuFU=((Jiema[0]&0x08)>>3)>0;

      JieFU=((Jiema[0]&0x04)>>2)>0;

 

      Jiema[2]=(Jiema[0]&0x03)*16+Jiema[1];

      

      if(JieFU)

             returnflo=(float)pow(2,(-1)*Jiema[2])*Decimal;

      else

             returnflo=(float)pow(2,Jiema[2])*Decimal;

 

      if(ShuFU)

             returnflo=(-1)*returnflo;

 

      returnreturnflo;

}

2)浮点数到ASCII码:

 

voidD4toC(char*c,floatd)

{

   BYTE   i=0,Jiema=0;

      char   inbyte1[30];

      BOOL   ShuFu=FALSE,JieFu=FALSE;

      int    inbyte2=0,inbyte3=0,inbyte4=0;

      char   afterbyte2[30],afterbyte3[30],afterbyte4[30];

      float  F_afterbyte2=0,F_afterbyte3=0,F_afterbyte4=0;

 

      memset(inbyte1,0x30,sizeof(inbyte1));

      memset(afterbyte2,0x30,sizeof(afterbyte2));

      memset(afterbyte3,0x30,sizeof(afterbyte3));

      memset(afterbyte4,0x30,sizeof(afterbyte4));

      

      inbyte1[10]=0x0;

      afterbyte2[10]=0x0;

      afterbyte3[10]=0x0;

      afterbyte4[10]=0x0;

      

      if(d==0)

      {

             for(intj=0;j<8;j++)

                    c[j]=0x30;

             return;

      }

      if(d<0)

      {

             ShuFu=TRUE;

             d=(-1)*d;

      }

      

      while(d>1)

      {

             d=(float)(d/2.0);

             i++;

      }

 

      while(d<=0.5)

      {

             JieFu=TRUE;

             d=(float)(d*2.0);

             i++;

      }

 

      if(d==1)

      {

             for(intj=2;j<8;j++)

                    c[j]=0x46;         

      }    

      else

      {    

             inbyte2=(int)(d*256);

             F_afterbyte2=(d*256)-(int)(d*256);

             inbyte3=(int)(F_afterbyte2*256);

             F_afterbyte3=(F_afterbyte2*256)-(int)(F_afterbyte2*256);

             inbyte4=(int)(F_afterbyte3*256);

             F_afterbyte4=(F_afterbyte3*256)-(int)(F_afterbyte3*256);

 

             itoa(inbyte2,afterbyte2,16);

             itoa(inbyte3,afterbyte3,16);

             itoa(inbyte4,afterbyte4,16);

 

             if(inbyte2==0)

        

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 其它

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2