通信协议详情ASCII.docx
- 文档编号:10033521
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:19
- 大小:79.12KB
通信协议详情ASCII.docx
《通信协议详情ASCII.docx》由会员分享,可在线阅读,更多相关《通信协议详情ASCII.docx(19页珍藏版)》请在冰豆网上搜索。
通信协议详情ASCII
组态王与单片机协议
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
标志
读操作
字节型
打包
数据地址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
**
异或
5.浮点数格式:
4字节浮点数=第一字节高4位ASCII码+第一字节低4位ASCII码
+第二字节高4位ASCII码+第二字节低4位ASCII码
+第三字节高4位ASCII码+第三字节低4位ASCII码
+第四字节高4位ASCII码+第四字节低4位ASCII码
第1字节低4位第2字节低4位第3字节低4位第4字节低4位
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
第1字节高4位第2字节高4位第3字节高4位第4字节高4位
★四字节浮点数格式:
(1)第一字节
(2)第二字节
(3)第三字节
(4)第四字节
注:
数符=0——正,数符=1——负阶符=0——正,阶符=1——负
D7D6D5~D0
★浮点数可表示围:
-1×232~1×232
★数符:
1位阶符:
1位阶码:
6位
例:
流量积算控制仪表瞬时流量测量值数据=100.210
转换成浮点数:
100.210=27⨯0.7828125=0716+C816+6616+6616
=30ASCII+37ASCII+43ASCII+38ASCII+36ASCII+36ASCII+36ASCII+36ASCII
小数部份:
0.7828125⇒0.7828125⨯256=200.4⇒0.4⨯256=102.4⇒0.4⨯256=102.4
10进制:
第一字节
第二字节
第三字节
第四字节
十六进制:
ASCII码:
第一字节
第二字节
第三字节
第四字节
传输格式如下:
第1字节低4位第2字节低4位第3字节低4位第4字节低4位
30
37
43
38
36
36
36
36
第1字节高4位第2字节高4位第3字节高4位第4字节高4位
3、注:
仪表部数据为十六进制表示的十进制数。
如:
实时测量值为500,则用十六进制表示为1F4H。
仪表通讯传输是将上述十六进制数据转化为标准ASCII码(即一字节的16进制数转化为2个ASCII码──高4位ASCII码+低4位ASCII码)。
如:
上述数据1F4H(16进制),传输时,转化为ASCII码则为30H、31H、46H、34H。
6.此浮点数格式的转换:
1)ASCII码到浮点数:
/*
in:
char*c
要转化的ASII码字符,应为4个字符。
Return:
转换后的浮点数。
*/
floatC4toD(char*c)
{
BYTEHd[30],Jiema[30];
floatDTc[30];
floatDecimal=0;
memset(Hd,0,sizeof(Hd));
memset(Jiema,0,sizeof(Jiema));
memset(DTc,0,sizeof(DTc));
floatreturnflo=0;
BOOLShuFU=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码:
/*
in:
char*c:
存储浮点数转换后的ASCII码字符。
Floatd:
要转换的浮点数。
Return:
无。
*/
voidD4toC(char*c,floatd)
{
BYTEi=0,Jiema=0;
charinbyte1[30];
BOOLShuFu=FALSE,JieFu=FALSE;
intinbyte2=0,inbyte3=0,inbyte4=0;
charafterbyte2[30],afterbyte3[30],afterbyte4[30];
floatF_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)
{
c[2]=0x30;
c[3]=0x30;
}
elseif(inbyte2<16)
{
c[2]=0x30;
c[3]=afterbyte2[0];
}
else
{
c[2]=afterbyte2[0];
c[3]=afterbyte2[1];
}
if(inbyte3==0)
{
c[4]=0x30;
c[5]=0x30;
}
elseif(inbyte3<16)
{
c[4]=0x30;
c[5]=afterbyte3[0];
}
else
{
c[4]=afterbyte3[0];
c[5]=afterbyte3[1];
}
if(inbyte4==0)
{
c[6]=0x30;
c[7]=0x30;
}
elseif(inbyte4<16)
{
c[6]=0x30;
c[7]=afterbyte4[0];
}
else
{
c[6]=afterbyte4[0];
c[7]=afterbyte4[1];
}
}
if(JieFu)
{
if(i>0x3f)
i=0x3f;
}
elseif(i>0x32)
i=32;
if(ShuFu)
i=i|0x80;
if(JieFu)
i=i|0x40;
itoa(i,inbyte1,16);
if(inbyte1==0)
{
c[0]=0x30;
c[1]=0x30;
}
elseif(i<16)
{
c[0]=0x30;
c[1]=inbyte1[0];
}
else
{
c[0]=inbyte1[0];
c[1]=inbyte1[1];
}
for(i=0;i<8;i++)
{
if((c[i]>0x60)&&(c[i]<0x67))
c[i]=c[i]-0x20;
}
c[8]=0x00;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 通信协议 详情 ASCII