KommunikationVereinbarung(modbus–RTU) 仪表设置:pst 01——中TF = 1,D39系列要选Befehl方式2
一、老Vereinbarung 兼容老Vereinbarung
1.主机读仪表Daten
| 等待 | Bytes0 | 1 | 2 | 3 |
| 四个Bytes的Zeit | 1~247 | x03 | 启始Adresse高8 | 低8 |
| 仪表Adresse | Funktion代码 | 所要读的Register.开始Adresse | ||
| 4 | 5 | 6 | 7 | 等待 |
| N/2个Bytes高8 | 低8 | CRC16低8 | CRC16高8 | 三个Bytes的Zeit |
| Senden SieAnzahl | CRC16Prüfungen | |||
Daten以ASII传送
2.仪表返馈
正常回应
| Bytes0 | 1 |
| 1~247 | 0x03 |
| 仪表Adresse | Funktion代码 |
| 2 | 3 | 3+n | 3+n | ||
| N | Daten0 | …… | DatenN(偶数) | CRC16L | CRC16h |
| DatenLänge | Daten | ||||
1)称重DatenLesen指令
| Funktion | 所要读的Register.开始Adresse(Adresse高8位) | 所要读的Register.开始Adresse(Adresse低8位) | |
| 1 | 读毛重 | 0x00 | 0x01 |
| 2 | 读皮重 | 0x00 | 0x02 |
| 3 | 读净重 | 0x00 | 0x03 |
| 4 | 读总内码 | 0x00 | 0x07 |
| 5 | 读DieiNr.Der Sensor内码异常时得zu-999999 | 0x00 | 0x0A+i(i=1~16) |
Senden Sie
| 0 | 1 | 2 | 3 | 4 |
| 仪表Adresse | 0x03 | Adresse高8位 | Adresse低8位 | 0x00 |
| 5 | 6 | 7 |
| 0x04 | CRC16L | CRC16H |
返回
| 0 | 1 | 2 | 3 | 5 | 6 |
| 仪表Adresse | 0x03 | 0x08 | 符Nr.-或data6 | Data5 | Data4 |
| 7 | 8 | 9 | 10 | 11 |
| Data3 | Data2 | Data1 | Data0 | 小数点(右至左) |
| 12 | 13 |
| CRC16L | CRC16H |
例子:
1、Lesengegenwärtig毛重
Senden Sie:01 03 00 01 00 04 15 C9
Empfang:若gegenwärtig毛重为0
01 03 08 30 30 30 30 30 30 30 30 F8 2F (最后两个Bytes为CRC16Prüfcode)
若gegenwärtig毛重为1240
01 03 08 30 30 30 31 32 34 30 30 85 96
2、Fern entfernt置零
Senden Sie: 01 06 00 01 00 17 98 04
Empfang: 01 06 00 01 00 17 98 04
Häufige Fragen:
1、仪表连续Senden Sie(如TF=0)时,电脑Die Serie能收zuDaten,但用指令方式仍无Antwort
原因: 1)仪表ParameterFehler.,D2008、D12系列仪表TF = 1;D39系列仪表为Befehl方式2
2)仪表Die Serie故障,可通过test 08 进行自检。
3)电脑Die Serie故障,将接Die Serie2和3短路,然后通过Die SerieWerkzeugeSenden SieDaten,看其能否收zu自己Senden Sie的相同的Daten。
4)接线问题,仪表9芯的3Nr.脚(RXD)为Empfang脚,需要与电脑的2Nr.脚(TXD)Verbindung
5)仪表虽支持modbus RTU Vereinbarung,但modbus 发指令时有要求,如读毛重,其Register-Adresse为40001.此时必须一次性读4个字(40001~40004),否则无应答。
2、Daten如何解释
以下为读毛重
| Adresse | 内容 | 举例(重Quantität1234567) | 举例(重Quantität-23456.7) |
| 40001 | 符Nr.-或data6,Data5 | 0x31,0x32 | 0x2d,0x32 |
| 40002 | Data4,Data3 | 0x33,0x34 | 0x33,0x34 |
| 40003 | Data2,Data1 | 0x35,0x36 | 0x35,0x36 |
| 40004 | Data0,小数点+0x30 | 0x37,0x30 | 0x37,0x31 |
以下为读净重
| Adresse | 内容 | 举例(重Quantität1234567) | 举例(重Quantität-23456.7) |
| 40003 | 符Nr.-或data6,Data5 | 0x31,0x32 | 0x2d,0x32 |
| 40004 | Data4,Data3 | 0x33,0x34 | 0x33,0x34 |
| 40005 | Data2,Data1 | 0x35,0x36 | 0x35,0x36 |
| 40006 | Data0,小数点+0x30 | 0x37,0x30 | 0x37,0x31 |
以下是西门子 200 smart 的Beispiel:
读毛重:

特别要注意:以上40002对应仪表的40001.
接下来再写个子程序:

子程序Schnittstelle:

代码:(部Unterteilung)

二、新Vereinbarung
只有以下版本支持:
仪表:D2008型(DF)、D12-YF–V09版本 D2008-W —V13版本,KL-MPLC的com2Vereinbarung1
| Register-Adresse | |
| 40060 | StatusBit0:开机零点Bestätigen中 0:已Bestätigen 1:正在Bestätigen中Bit1:超载 0:正常 1:超载Bit2:稳定 0:不稳定 2:稳定 Bit3:去皮 0:没有去皮 1:去皮StatusBit4:零点 0:没在零点 1:零位区Bit5:计QuantitätDatenWirksam 0:Unwirksam 1:Wirksam Bit6: Der Sensor出错 0:通讯正常 1: 异常Bit7: 备用Bit8~15: Der Sensor个数 |
| 40061 | Der SensorStatus 0:正常 1:异常 Bit16:1Nr. Bit17:2Nr.…Bit31:16Nr. |
| 40062-40063 | 毛重:float |
| 40064-40065 | 皮重:float |
| 40066-40067 | 净重:float |
| 40068-40069 | Die ersteDer Sensor内码:float |
| 40070-40071 | Der zweiteDer Sensor内码:float |
| … | … |
| 40098-40099 | Der 16.Der Sensor内码:float |
| 40100 | Der SensorStatus 0:正常 1:异常 Bit16:17Nr. Bit17:18Nr.…Bit31:32Nr. |
| 40101-40102 | Die17Nr.Der Sensor内码:float |
| 40103-40104 | Die18Nr.Der Sensor内码:float |
| … | … |
| 40131-40132 | Die32Nr.Der Sensor内码:float |
约定:
当秤台计QuantitätDatenUnwirksam:仪表的净重为-999999,如果小数点为3位,则为-999.999
置零:向Adresse40001写0x0017;
2、Modbus主机配置:
Die一项:Auswahl为RTU
Die二项:

如:

Die三项:floatFormat zeigen设置:

Die三项:Alles显Beispiel子:

3、Related解码代码:Empfangen von Bytes转化为浮点型
定义Daten结构:
typedef union noneTYPE32DATABYTE
{
struct{
INT32U onebyte0:8;
INT32U onebyte1:8;
INT32U onebyte2:8;
INT32U onebyte3:8;
}onebyte;
INT32U One32data;
FP32 FP32data;
}TYPE32DATABYTE;
代码:
原如Empfang4个Bytes (按Empfang顺序)--Rdata[0],Rdata[1],Rdata[2]和Rdata[3]
float FP32data;
TYPE32DATABYTE P_temp;
P_temp.onebyte.onebyte1 = Rdata[0];
P_temp.onebyte.onebyte0 = Rdata[1];
P_temp.onebyte.onebyte3 = Rdata[2];
P_temp.onebyte.onebyte2 = Rdata[3];
F_temp = P_temp.FP32data;//F_temp就是Ergebnis在西门子 200smart中Bytes转浮点型Operationen如下:
例:浮点数 123.456 对应[0]=0x79 0xe9,0xf6,[3]=0x42
PLC梯形图转化:

效果:

常用例子1:读毛重
仪表显示毛重68,皮重为0
发:01 03 00 42 00 02 64 1F
收: 01 03 04 00 00 42 88 CA F5
常用例子2:Fern entfernt置零
Senden Sie: 01 06 00 01 00 17 98 04
Empfang: 01 06 00 01 00 17 98 04
CRC16Prüfcode算法:
/* CRC hoch位Bytes值表 */
const unsigned char auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;
/* CRC低位Bytes值表*/
const unsigned char auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
/******************************************************
函数名: INT16U crc16(unsigned char *puchMsg, INT16U usDataLen)
Funktion: 根据Charaktere串puchMsg 及Länge产生一个CRC16
输入:unsigned char *puchMsg Charaktere串 usDataLen Länge
输出:INT16U CRC16
*******************************************************/
INT16U crc16(unsigned char *puchMsg, INT16U usDataLen) //根据Charaktere串puchMsg 及Länge产生一个CRC16
{
unsigned char uchCRCHi = 0xFF ; /* 高CRCBytes初始化 */
unsigned char uchCRCLo = 0xFF ; /* 低CRC Bytes初始化 */
unsigned long uIndex ; /* CRC循环中的索引 */
while (usDataLen--) /* 传输消息缓冲区 */
{
uIndex = uchCRCHi ^ *puchMsg++ ; /* Berechnung von CRC */
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
}
//=======================================================应用:假设要Senden Sie读毛重指令(16 Einführung)
01 03 00 01 00 04
产生Prüfcode的方式
//TXD_C_temps[]存了01 03 00 01 00 04 (6个Bytes)
INT16U crcData ;
ByteCount = 6;//Daten为6Bytes
crcData = crc16(TXD_C_temps,ByteCount );
TXD_C_temps[byteCount] = crcData >> 8;
byteCount++;
TXD_C_temps[byteCount] = crcData & 0xff;
//此时Charaktere串
01 03 00 01 00 04 15 C9
putchars2_8th(TXD_C_temps,byteCount+1);//通过Die SerieSenden Sie
Antwort veröffentlichen