资源描述
河北省公共环境数据在线监测设备RS232串口协议
一. 有关串行通信的物理标准和数据采集系统结构
1. 信号线的定义:在线设备采用三线制DB9/M(针)标准RS232-C接口输出。
2. 信号的定义
起始位: 1位
数据位: 8位
校验位: 无
停止位: 1位
3. 传输速率
Baud Rate=2400 bps
4. 数据采集系统的结构
数据采集系统为主从结构;
记录仪(主)
在线设备 (从)
RS232
二. 命令包格式及应用示例
1、命令包格式
<命令包头><命令码><指定污染因子的个数><污染因子1代码><污染因子2代码>……<污染因子n代码><CRC><命令包尾>
命令包头 (共1个字节)
0x02;
命令码(共1个字节)
0x00立即回传指定污染因子代码的测量数据;
0x01立即回传全部测量数据;
③ 指定污染因子的个数(共1个字节)
④ 污染因子1….n代码 [共(2 x n)个字节]
见附件1:公共环境数据污染因子代码规范;
⑤ CRC校验码(共2个字节)
功能:对项所包含的字节进行16位CRC校验;
计算方法:
见附件3:CRC校验码的计算方法;
⑥ 命令包尾 (共1个字节)
0x03;
2、应用示例
(1)立即回传指定污染因子代码的测量数据命令包
①确定上传的测量数据
指定测量数据1-----TSP TSP的污染因子代码=0x2485
指定测量数据2-----PM10 PM10的污染因子代码=0x2486
指定测量数据3-----SO2 SO2的污染因子代码=0x2402
指定测量数据4-----NO2 NO2的污染因子代码=0x2467
②命令体的内容
命令码=0x00
指定污染因子的个数=0x04
污染因子1代码(TSP)=0x2485
污染因子2代码(PM10)=0x2486
污染因子3代码(SO2)=0x2402
污染因子4代码(NO2)=0x2467
CRC校验码的计算:
计算校验码的范围=[命令码+指定污染因子的个数+污染因子1…4代码]
=[00042485248624022467]
CRC校验码= A3F4
③命令体的组成:
命令体(HEX)=00042485248624022467 A3F4
④命令体的转换:
命令体(HEX)----à命令体(ASCII)
命令体(ASCII)= 303030343234383532343836323430323234363741334634
⑤命令包的组成:
命令包=命令包头+命令体(ASCII)+ 命令包尾
命令包=0230303034323438353234383632343032323436374133463403
(2)立即回传全部测量数据命令包
①命令体的内容
命令码=0x01
指定污染因子的个数=0x00
CRC校验码的计算:
计算校验码的范围=[命令码+指定污染因子的个数]=[0100]
CRC校验码= 3331
③命令体的组成:
命令体(HEX)=01003331
④命令体的转换:
命令体(HEX)----à命令体(ASCII)
命令体(ASCII)= 3031303033333331
⑤命令包的组成:
命令包=命令包头+命令体(ASCII)+ 命令包尾
命令包=02303130303333333103
三、在线设备上传数据包格式及应用示例
1、 数据包格式
<数据包头><命令码><污染因子的个数><污染因子1代码><污染因子1 的数据><污染因子2代码><污染因子2 的数据>……<污染因子n代码><污染因子n 的数据><CRC><数据包尾>
① 数据包头 (共1个字节)
0x02 ;
②命令码(共1个字节)
0x00立即回传指定污染因子代码的测量数据;
0x01立即回传全部测量数据;
③污染因子的个数(共1个字节)
④污染因子1…n代码
见附件1:公共环境数据污染因子代码规范;
⑤污染因子1…n 的数据
见附件2:公共环境数据格式规范;
⑥ CRC校验码(共2个字节)
功能:对⑤项所包含的字节进行16位CRC校验;
计算方法:
见附件3:CRC校验码的计算方法;
⑦命令包尾 (共1个字节)
0x03;
2、应用示例
(1) 上传污染因子测量数据的数据包1
①污染因子的测量数据
TSP=0.03 mg/Nm3 (乘1000取整)=0x001E
PM10=0.04 mg/Nm3 (乘1000取整)=0x0028
SO2 = 0.25 mg/Nm3 (乘1000取整)=0x00FA
NO2 =0.02 mg/Nm3 (乘1000取整) =0x0014
②数据体的内容
命令码=0x00
上传污染因子测量数据的个数=0x04
污染因子1…4的代码及污染因子1…4的测量数据:
污染因子1代码(TSP)=0x2485
污染因子1的测量数据=0x001E
污染因子2代码(PM10)=0x2486
污染因子2的测量数据=0x0028
污染因子3代码(SO2)=0x2402
污染因子3的测量数据=0x00FA
污染因子4代码(NO2)=0x2467
污染因子4的测量数据=0x0014
CRC校验码的计算:
计算校验码的范围=[命令码+上传污染因子测量数据的个数+<污染因子1代码><污染因子1 的数据><污染因子2代码><污染因子2 的数据>……<污染因子4代码><污染因子4 的数据>=[00042485001E24860028240200FA24670014]
CRC校验码= 3F51
③数据体的组成:
数据体(HEX)=00042485001E24860028240200FA246700143F51
④数据体的转换:
数据体(HEX)----à命令体(ASCII)
数据体(ASCII)=
30303034323438353030314532343836303032383234303230304641323436373030313433463531
⑤数据包的组成:
数据包=数据包头+数据体(ASCII)+ 数据包尾
数据包=
023030303432343835303031453234383630303238323430323030464132343637303031343346353103
四、说明
1、省环保局根据实际需要可扩展和修改代码表中的污染因子代码;
2、省环保局根据实际测量数据精度的需要可改变数据的取整方式;
3、各相关在线仪表生产厂家应通过在线仪表的面板操作,能简便地调整污染因子代码和数据的取整方式;
附件1:公共环境数据污染因子代码规范
一、 污染因子代码表示方法(2Byte)
高字节(高8位)
低字节(低8位)
污染因子数据长度
污染因子分类码
污染因子
D15
D14
D13
D12
D11
D10
D9
D8
D7
D6
D5
D4
D3
D2
D1
D0
R
注:D15=R-----保留位,用于以后功能扩展,缺省值=0。
二、 污染因子分类码
1、 地表水类:
分类码=0x03
高字节(高8位)
污染因子数据长度
污染因子代码分类
D15
D14
D13
D12
D11
D10
D9
D8
R
×
×
×
0
0
1
1
2、 空气质量类:
分类码=0x04
高字节(高8位)
污染因子数据长度
污染因子代码分类
D15
D14
D13
D12
D11
D10
D9
D8
R
×
×
×
0
1
0
0
3、 噪声类:
分类码=0x05
高字节(高8位)
污染因子数据长度
污染因子代码分类
D15
D14
D13
D12
D11
D10
D9
D8
R
×
×
×
0
1
0
1
三、 污染因子数据长度
根据不同类型的在线仪表,预先设定的该在线仪表上传某污染因子数据的长度;
如:设定的COD数据长度=0x02,当前监测的COD数据=20mg/L,在线仪表上传的该污染因子数据=0x0014 mg/L;
设定的COD数据长度=0x03,当前监测的COD数据=20mg/L,在线仪表上传的该污染因子数据=0x000014 mg/L;
四、 污染因子
用低字节表示某类污染因子;
五、 污染因子代码表(省环保局根据实际需要可扩展和修改代码表中的污染因子代码)
1、地表水类
序号
污染因子
单位
污染因子分类码
污染因子代码
1
PH
0x03
0x0301
2
BOD
mg/L
0x03
0x030A
3
CODcr
mg/L
0x03
0x030B
4
TOC
mg/L
0x03
0x030F*
5
平均流速
m3/s
0x03
0x0310
6
水温
℃
0x03
0x0311
7
水深
m
0x03
0x0312
8
溶解氧
mg/L
0x03
0x0313
9
CODmn
mg/L
0x03
0x033A
10
总氮
mg/L
0x03
0x033B
11
氨氮
mg/L
0x03
0x033C*
12
石油类
mg/L
0x03
0x0350*
13
总磷
mg/L
0x03
0x0365*
14
浊度
度
0x03
0x0315
15
电导率
μS/cm
0x03
0x0316
2、空气(大气)质量类
序号
污染因子
单位
污染因子分类码
污染因子代码
1
SO2
mg/Nm3
0x04
0x0402
2
CO
mg/ Nm3
0x04
0x0404
3
NO2
mg/ Nm3
0x04
0x0467
4
O3
mg/ Nm3
0x04
0x0471
5
降尘
mg/ Nm3
0x04
0x0472
6
湿度
%
0x04
0x0473
7
气温
℃
0x04
0x0481
8
大气压
KPa
0x04
0x0482
9
风速
m/s
0x04
0x0483
10
风向
0x04
0x0484
11
TSP
mg/Nm3
0x04
0x0485
12
PM10
mg/Nm3
0x04
0x0486
13
3、噪声类
序号
污染因子
单位
污染因子分类码
污染因子代码
1
噪声
dB
0x05
0x0501
六、 污染因子数据长度+污染因子代码的应用
1、某监测地表水类COD的在线仪表;
设定上传COD的数据长度为2字节=0x02;
污染因子代码=0x030B
该在线仪表COD的(污染因子数据长度+污染因子代码)=0x230B。
2、某监测地表水类PH的在线仪表;
设定上传PH的数据长度为2字节=0x02;
污染因子代码=0x0301
该在线仪表PH的(污染因子数据长度+污染因子代码)=0x2301。
3、某监测空气(大气)质量类SO2的在线仪表;
设定上传SO2的数据长度为2字节=0x02;
污染因子代码=0x0402
该在线仪表SO2的(污染因子数据长度+污染因子代码)=0x2402
附件2:公共环境数据格式规范
(省环保局根据实际测量数据精度的需要可改变数据的取整方式)
1、地表水类
举例
序号
污染因子
单位
数据长度
(Byte)
实测值
上传数据
(HEX)
备注
1
CODcr
mg/L
2
20
0x0014
取整
2
CODmn
mg/L
2
12.3
0x04CE
乘100取整
3
氨氮
mg/L
2
0.15
0x000F
乘1000取整
4
PH
2
6.8
0x02A8
乘100取整
5
BOD
mg/L
2
4.2
0x01A4
乘100取整
6
溶解氧
2
5.5
0x0226
乘100取整
7
石油类
mg/L
2
0.03
0x0003
乘1000取整
水深
m
2
1.5
0x0096
乘100取整
8
平均流速
m/s
2
4.6
0x01CC
乘100取整
9
水温
℃
1
+25
0x19
取整
10
总氮
mg/L
2
0.025
0x0019
乘1000取整
11
总磷
mg/L
2
0.012
0x000C
乘1000取整
12
TOC
mg/L
2
56.05
0x00DAF2
乘100取整
13
浊度
度
2
6
0x0006
取整
14
电导率
μS/cm
2
+25
0x0019
取整
2、空气(大气)质量类
举例
序号
污染因子
单位
数据长度(Byte)
实测值
上传数据
(HEX)
备注
1
SO2
mg/Nm3
2
0.25
0x00FA
乘1000取整
2
NO2
mg/ Nm3
2
0.02
0x0014
乘1000取整
3
CO
mg/ Nm3
9.1
0x238C
乘1000取整
4
O3
mg/ Nm3
2
0.05
0x0032
乘1000取整
5
降尘
T/Km2.月
2
12
0x2EE0
乘1000取整
6
湿度
%
1
70
0x46
取整
7
气温
℃
1
+25
0x19
高位=0
-25
0x99
高位=1
8
大气压
KPa
3
101.20
0x018B50
乘1000取整
9
风速
m/s
2
1.5
0x05DC
乘1000取整
10
风向
1
11
TSP
mg/Nm3
2
0.03
0x001E
乘1000取整
12
PM10
mg/Nm3
2
0.04
0x0028
乘1000取整
3、噪声类
举例
序号
污染因子
单位
数据长度
(Byte)
实测值
上传数据
(HEX)
备注
1
噪声
dB
1
40
0x28
取整
附件3:CRC校验码的计算方法
1、原理
现在,应用最广泛、功能最强大的检错码是循环冗余校验码(Cyclical Redundancy Check,缩写为CRC),CRC的基本原理是将一段信息看成一个很长的二进制数(例如将一段128字节的信息看成一个1024位的二进制数),然后用一个特定的数(例如二进制数1,0001,0000,0010,0001B,即十六进制数11021H)去除它,最后将余数作为校验码附在信息之后一起传送(或存储),在进行接收(或读出)时进行同样的处理,如有差错就可以发现。我们也可以采用软件方法生成CRC,用在数据的通讯或存储中,从而提高系统的检错能力。
l 先确定除数:按CCITT(国际电话和电报咨询委员会)规定,采用17比特的二进制数1,0001,0000,0010,0001B,即十六进制11021H。
l 数据块大小:128字节(即1024比特)。
l CRC校验的长度:2字节(即16比特),附在数据块之后。
l CRC生成算法中除法的实现:在计算机中,除法是通过一系列的减法来完成的。采用普通除法进行计算非常麻烦,而且余数有可能超过16比特(例如余数为17比特的10FA3H),故在CRC算法中采用的模2除法,即用“异或”操作代替减法操作,从而不考虑借位问题,余数也可以保证在16比特之内。
l CRC生成算法的步骤:先在128字节数据块之后补上两个字节的零,扩充成130字节;然后从高位到低为进行模2除法,最后的余数就是CRC校验码,将其存放在补零的位置上即可。模2除法的操作过程是:从被除数高端(数据块的开始端)开始,取17比特,如果最高位为0,得1比特的商0,被除数不用减去除数;如果最高位为1,得1比特的商1,被除数就要“减去”除数。我们用异或操作代替减法后,由于除数和被除数的最高位都为1,异或操作的结果必然是0,故余数必然在16比特之内,实际操作时就可以进行16比特的异或操作。整个模2除法的过程可以概括为从高位到低位按二进制扫描被除数,对每一位进行判断,如果是0(商是0),则不用处理,如果是1(商是1),就将其后的16比特(0001,0000,0010,0001B)进行异或操作。130字节的被除数要进行1024次处理,得到的1024位的商均被舍去,剩下16比特余数就是我们需要CRC校验码。在处理过程中,扫描被除数的过程是用移位操作来完成的。
l CRC计算流程如左图所示。
2、 16位CRC校验码的51汇编源程序:
①发送方计算CRC的程序如下:
START EQU 2000H ;数据块首址。
CRCOUT: MOV DPTR,#START+80H ;将CRC存放单元初始化为零
CLR A
MOVX @DPTR,A
INC DPTR
MOVX @DPTR,A
LCALL CRC ;计算CRC.
MOV DPTR,#START+80H ;将计算结果存放在数据块之后。
MOV A,R2
MOVX @DPTR,A
INC DPTR
MOV A,R3
MOVX @DPTR,A
RET
CRC: MOV DPTR,#START ;(CRC计算模块)先取两字节数据,作为最初的被除数。
MOVX A,@DPTR
MOV R2,A
INC DPTR
MOVX A,@DPTR
MOV R3,A
MOV R7,#80H ;后128字节依次作为被除数的补充
CRC1: INC DPTR
MOVX A,@DPTR ;取一字节数据,作为被除数的补充。
MOV R4,A
MOV R5,#8 ;每个字节要进行8次模2除法。
CRC2: MOV A,R4 ;三个字节被除数的当前余数左移一位
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
MOV A,R2
RLC A
MOV R2,A
JNC CRC3 ;移出的最高位是0,不用处理。
XRL A,#10 ;移出最高位是1,进行模2处理。
MOV R2,A
MOV A,R3
XRL A,#21H
MOV R3,A
CRC3 DJNZ R5,CRC2 ;处理完一个字节。
DJNZ R7,CRC1 ;处理完全部数据。
RET ;CRC校验码在R2R3中。
l 收方的验错方法:收方接收到130字节的数据后,对其进行CRC校验,结果为零表示没有差错。检错原理分析如下:
在发送方的处理过程中:128字节数据快 + 2字节零 = 商 × 除数 + 2字节CRC
因为 2字节零 + 2字节CRC = 2字节CRC
故发送方发出的信息 128字节数据块 + 2字节CRC
=128字节数据块 + (2字节零 + 2字节CRC)
=(128字节数据块 + 2字节零)+ 2字节CRC
= 商 × 除数 + 2字节CRC + 2字节CRC
这说明,发送方的原始数据块中本来包含着一个余数CRC,正式发出的数据块中又加上一个余数CRC,两个CRC在模2运算中相互对消,如果收方接收无误,进行CRC计算后,余数就应该为零,这是130个字节数据块中的前128个字节就是有效数据块。收方接收到130字节数据之后的校验程序如下:
②接收方计算CRC的程序如下:
START EQU 2000H ;数据区首址
ERR BIT 00H ;出错标志
CHECK: CLR ERR ;出错标志初始化。
LCALL CRC ;计算CRC。
MOV A,R2 ;结果为零否?
ORL A,R3
JZ CHKE
SETB ERR ; 结果不为零,设立出错标志。
CHKE: RET
3、16位CRC校验码的C源程序:
//例如:求三个字节AA AA AA(16进制)的CRC校验码
在三字节后加上两个字节的0x00,字符指针ptr指向此串,count此时为3,
//求得的CRC校验码是9C48
int calcrc( char *ptr, int count ) //求CRC的calcrc函数,ptr是指向字符数组的指针
{ //count是待求CRC校验码的字节数
int i;
unsigned int crc; //要返回的CRC,16位的
unsigned char crc1,crc2,crc3; //指向数组中连续的三个字符(byte),8位的
crc1 = *ptr++ ;
crc2 = *ptr++ ;
while (--count >= 0) {
crc3 = *ptr++ ; //在while中补充下一个字符(8个bit)
for (i = 0; i < 8; ++i)
{
if (crc1 & 0x80) //判断crc1高位是否为1
{
crc1 = crc1 << 1; //移出高位
if(crc2 & 0x80) //判断crc2高位是否为1
{
crc1=crc1 | 0x01; //crc1低位由0变1
}
crc2 = crc2 << 1; //crc2移出高位
if(crc3 & 0x80) //判断crc3高位是否为1
{
crc2=crc2 | 0x01; //crc2低位由0变1
}
crc3=crc3<<1; //crc3移出高位
crc1=crc1 ^ 0x10; //前8bit与0x10异或
crc2=crc2 ^ 0x21; //后8bit与0x21异或
}
else //如果crc1高位不为1,只移位不做异或
{
crc1 = crc1 << 1;
if(crc2 & 0x80)
{
crc1=crc1 | 0x01;
}
crc2 = crc2 << 1;
if(crc3 & 0x80)
{
crc2=crc2 | 0x01;
}
crc3=crc3<<1;
}
}//for
}//while
crc=(crc1<<8)+crc2; //返回的16位的crc校验码
return (crc);
}//calcrc
展开阅读全文