通信プロトコル(modbus--RTU) 仪表設定:pst 01------中TF = 1,D39系列要选命令方式2
一、老协议 兼容老协议
1.マスター读仪表データ
| 待機中 | byte0 | 1 | 2 | 3 |
| 四バイト単位。的时间 | 1~247 | x03 | 启始アドレス高8 | 低8 |
| 仪表アドレス | 功能代码 | 所要读的レジスタ开始アドレス | ||
| 4 | 5 | 6 | 7 | 待機中 |
| N/2バイト単位。高8 | 低8 | CRC16低8 | CRC16高8 | 三バイト単位。的时间 |
| 送信数量 | CRC16チェック | |||
データ以ASII传送
2.仪表返馈
正常回应
| byte0 | 1 |
| 1~247 | 0x03 |
| 仪表アドレス | 功能代码 |
| 2 | 3 | 3+n | 3+n | ||
| N | data0 | …… | dataN(偶数) | CRC16L | CRC16h |
| データ長さ | data | ||||
1)称重データ読み取り指令
| Function | 所要读的レジスタ开始アドレス(アドレス高8位) | 所要读的レジスタ开始アドレス(アドレス低8位) | |
| 1 | 读毛重 | 0x00 | 0x01 |
| 2 | 读皮重 | 0x00 | 0x02 |
| 3 | 读净重 | 0x00 | 0x03 |
| 4 | 读总内码 | 0x00 | 0x07 |
| 5 | 读第i号センサーは内码異常时得到-999999 | 0x00 | 0x0A+i(i=1~16) |
send
| 0 | 1 | 2 | 3 | 4 |
| 仪表アドレス | 0x03 | アドレス高8位 | アドレス低8位 | 0x00 |
| 5 | 6 | 7 |
| 0x04 | CRC16L | CRC16H |
戻る
| 0 | 1 | 2 | 3 | 5 | 6 |
| 仪表アドレス | 0x03 | 0x08 | 符号-或data6 | Data5 | Data4 |
| 7 | 8 | 9 | 10 | 11 |
| Data3 | Data2 | Data1 | Data0 | 小数点(右至左) |
| 12 | 13 |
| CRC16L | CRC16H |
例子:
1、読み取り当前毛重
send:01 03 00 01 00 04 15 C9
receive:若当前毛重为0
01 03 08 30 30 30 30 30 30 30 30 F8 2F (最后两バイト単位。为CRC16チェックコード)
若当前毛重为1240
01 03 08 30 30 30 31 32 34 30 30 85 96
2、远程置零
send: 01 06 00 01 00 17 98 04
receive: 01 06 00 01 00 17 98 04
common problems:
1、仪表连续送信(如TF=0)时,电脑シリアルポート能データの受信,但用指令方式仍応答なし。
原因: 1)仪表参数エラー,D2008、D12系列仪表TF = 1;D39系列仪表为命令方式2
2)仪表シリアルポート故障,可経由test 08 进行自检。
3)电脑シリアルポート故障,将接シリアルポート2和3ショート,然后経由シリアルポート工具送信データ,看其能否收到自己送信的相同的データ。
4)配線問題,仪表9芯的3号脚(RXD)为受信脚,需要与电脑的2号脚(TXD)connect
5)仪表虽サポートmodbus RTU Protocol,但modbus 发指令时有要求,如读毛重,其レジスター·アドレス为40001.此时必须一次性读4个字(40001~40004),否则无应答。
2、データ如何解释
以下为读毛重
| address | 内容 | 举例(重量1234567) | 举例(重量-23456.7) |
| 40001 | 符号-或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 |
以下为读净重
| address | 内容 | 举例(重量1234567) | 举例(重量-23456.7) |
| 40003 | 符号-或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 的サンプル:
读毛重:

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

子程序接口:

代码:(部分)

二、新协议
只有以下版本サポート:
仪表:D2008型(DF)、D12-YF--V09版本 D2008-W ---V13版本,KL-MPLC的com2协议1
| register address | |
| 40060 | statusBit0:开机零点確認中 0:已確認 1:正在確認中Bit1:超载 0:正常 1:超载Bit2:稳定 0:不稳定 2:稳定 Bit3:去皮 0:ない去皮 1:去皮ステータスBit4:零点 0:没在零点 1:零位区Bit5:计量データ有效 0:Invalid 1:effective Bit6: センサーは出错 0:通信は正常 1: 異常Bit7: 备用Bit8~15: センサーは个数 |
| 40061 | センサーはステータス 0:正常 1:異常 Bit16:1号 Bit17:2号...Bit31:16号 |
| 40062-40063 | 毛重:float |
| 40064-40065 | 皮重:float |
| 40066-40067 | 净重:float |
| 40068-40069 | The first oneセンサーは内码:float |
| 40070-40071 | the secondセンサーは内码:float |
| ... | ... |
| 40098-40099 | The 16th oneセンサーは内码:float |
| 40100 | センサーはステータス 0:正常 1:異常 Bit16:17号 Bit17:18号...Bit31:32号 |
| 40101-40102 | No.17号センサーは内码:float |
| 40103-40104 | No.18号センサーは内码:float |
| ... | ... |
| 40131-40132 | No.32号センサーは内码:float |
约定:
当秤台计量データ无效:仪表的净重为-999999,もし小数点为3位,则为-999.999
置零:向アドレス40001写0x0017;
2、Modbusマスター設定:
第一项:選択为RTU
第二项:

如:

第三项:float表示格式設定:

第三项:すべて显サンプル子:

3、相关解码代码:受信バイト转化为浮点型
定义データ構造:
typedef union noneTYPE32DATABYTE
{
struct{
INT32U onebyte0:8;
INT32U onebyte1:8;
INT32U onebyte2:8;
INT32U onebyte3:8;
}onebyte;
INT32U One32data;
FP32 FP32data;
}TYPE32DATABYTE;
代码:
原如受信4バイト単位。 (按受信顺序)--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就是结果在シーメンス 200smart中バイト转浮点型操作如下:
例:浮動小数点数 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:远程置零
send: 01 06 00 01 00 17 98 04
receive: 01 06 00 01 00 17 98 04
CRC16チェックコード算法:
/* CRC high位バイト值表 */
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低位バイト值表*/
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)
Function: 根据ストリング·ストリングpuchMsg 及長さ产生一个CRC16
入力:unsigned char *puchMsg ストリング·ストリング usDataLen Length
出力:INT16U CRC16
*******************************************************/
INT16U crc16(unsigned char *puchMsg, INT16U usDataLen) //根据ストリング·ストリングpuchMsg 及長さ产生一个CRC16
{
unsigned char uchCRCHi = 0xFF ; /* 高CRCバイト初期化 */
unsigned char uchCRCLo = 0xFF ; /* 低CRC バイト初期化 */
unsigned long uIndex ; /* CRC循环中的索引 */
while (usDataLen--) /* 传输メッセージバッファ */
{
uIndex = uchCRCHi ^ *puchMsg++ ; /* Calculate CRC */
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
}
//=======================================================应用:假设要送信读毛重指令(hexadecimal)
01 03 00 01 00 04
产生チェックコード的方式
//TXD_C_temps[]存了01 03 00 01 00 04 (6バイト単位。)
INT16U crcData ;
ByteCount = 6;//データ为6バイト
crcData = crc16(TXD_C_temps,ByteCount );
TXD_C_temps[byteCount] = crcData >> 8;
byteCount++;
TXD_C_temps[byteCount] = crcData & 0xff;
//此时ストリング·ストリング
01 03 00 01 00 04 15 C9
putchars2_8th(TXD_C_temps,byteCount+1);//経由シリアルポート送信
Leave a Reply