当前位置:文档之家› 通信协议模板(ASCII)

通信协议模板(ASCII)

returnreturnflo;
}
2)浮点数到ASCII码:
/*
in:char*c:
存储浮点数转换后的ASCII码字符。
Floatd:
要转换的浮点数。
Return:无。
*/
voidD4toC(char*c,floatd)
{
BYTEi=0,Jiema=0;
charinbyte1[30];
BOOLShuFu=FALSE,JieFu=FALSE;
组态王与单片机协议
1.通讯口设置:
通讯方式:RS-232,RS-485,RS-422均可。
波特率:由单片机决定(2400,4800,9600and19200bps)。
字节数据格式:由单片机决定。
起始位
数据位
校验位
停止位
注意:在组态王中设置的通讯参数如波特率,数据位,停止位,奇偶校验必须与单片机编程中的通讯参数一致
★四字节浮点数格式:
(1)第一字节
(2)第二字节
(3)第三字节
(4)第四字节
注:数符=0——正,数符=1——负阶符=0——正,阶符=1——负
D7D6D5~D0
★浮点数可表示范围:-1×232~1×232
★数符:1位阶符:1位阶码:6位
例:流量积算控制仪表瞬时流量测量值数据=100.210
转换成浮点数:100.210=270.7828125=0716+C816+6616+6616
如:上述数据1F4H(16进制),传输时,转化为ASCII码则为30H、31H、46H、34H。
6.此浮点数格式的转换:
1)ASCII码到浮点数:
/*
in:char*c
要转化的ASII码字符,应为4个字符。
Return:转换后的浮点数。
*/
floatC4toD(char*c)
{
BYTEHd[30],Jiema[30];
第一字节
第二字节
第三字节
第四字节
传输格式如下:
第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码)。
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码
intinbyte2=0,inbyte3=0,inbyte4=0;
charafterbyte2[30],afterbyte3[30],afterbyte4[30];
floatF_afterbyte2=0,F_afterbyte3=0,F_afterbyte4=0;
Jiema[2]=(Jiema[0]&0x03)*16+Jiema[1];
if(JieFU)
returnflo=(float)pow(2,(-1)*Jiema[2])*Decimal;
else
returnflo=(float)pow(2,源自文库iema[2])*Decimal;
if(ShuFU)
returnflo=(-1)*returnflo;
寄存器名称
dd上限
dd下限
数据类型
Xdd
65535
0
FLOAT/BYTE/UINT
斜体字dd代表数据地址,此地址与单片机的数据地址相对应。
注意:在组态王中定义变量时,一个X寄存器根据所选数据类型(BYTE,UINT,FLOAT)的不同分别占用一个、两个,四个字节,定义不同的数据类型要注意寄存器后面的地址,同一数据区内不可交叉定义不同数据类型的变量。为提高通讯速度建议用户使用连续的数据区。
通讯尝试恢复命令(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,数据类型为字节,打包。组态王所发数据为:
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);
设备地址
标志
数据地址
数据字节数
数据…
异或
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
+第二字节高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、在单片机中定义从地址0开始的数据类型为BYTE型的变量:
则在组态王中定义相应的变量的寄存器为X0、X1、X2、X3、X4。。。。。。。。,数据类型为BYTE,每个变量占一个字节
2、在单片机中定义从地址100开始的数据类型为UINT型的变量:
则在组态王中定义相应的变量的寄存器为X100、X102、X104、X106、X108。。。。。。。。,数据类型UINT,每个变量占两个字节
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.上位机发送写命令
字头
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[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))
2.在组态王中定义设备地址的格式
格式:##.#
前面的两个字符是设备地址,范围为0-255,此地址为单片机的地址,由单片机中的程序决定;
后面的一个字符是用户设定是否打包,“0”为不打包、“1”为打包,用户一旦在定义设备时确定了打包,组态王将处理读下位机变量时数据打包的工作。
3.在组态王中定义的寄存器格式
=30ASCII+37ASCII+43ASCII+38ASCII+36ASCII+36ASCII+36ASCII+36ASCII
小数部份:0.78281250.7828125256=200.40.4256=102.40.4256=102.4
10进制:
第一字节
第二字节
第三字节
第四字节
十六进制:ASCII码:
3、在单片机中定义从地址200开始的数据类型为FLOAT型的变量:
则在组态王中定义相应的变量的寄存器为X200、X204、X208、X212。。。。。。。,数据类型FLOAT,每个变量占四个字节
3.组态王与单片机通讯的命令格式:
读写格式(除字头、字尾外所有字节均为ASCII码)
字头
设备地址
标志
数据地址
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;
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[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;
bit3bit2=1x,数据类型为浮点数。
数据地址:2字节4个ASCII码,0x0000~0xffff
数据字节数:1字节2个ASCII码,1—100,实际读写的数据的字节数。
数据…:为实际的数据转换为ASCII码,个数为字节数乘2。
异或:异或从设备地址到异或字节前,异或值转换成2个ASCII码
CR:0x0d。
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))
数据字节数
数据…
异或
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,数据类型为字。
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))
标志
写操作
字型
不打包
数据地址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
相关主题