地磅数据格式描述
顶松通信协议是一种基于 Ascii 码字节的主从式协议,每个下位机(仪表)都有一个唯一地址,上位机发送指令到指定地址的下位机,下位机收到命令以后,如果校验正确则返回相应信息。上位机收到正确回答以后进行处理,一定时间未收到,视为通信超时。
上位机发送数据格式
仪表返回数据格式
命令A 主要是获取当前称量的净重跟皮重
由于我只关心净重 所以就用这个指令
通过串口助手看到一个示例重量
//(STX)Aa±nnnnnnpttttttefu(CHK)(ETX)
//02 41 61 2B [30 30 30 30 31 38] 30 [30 30 30 30 30 30] 30 60 20 40 03
//(CHK) = (XON) xor (ADDR) xor (CMD) xor (DATA1) xor (DATA2) xor … xor (DATAn) or (0x40)
根据协议可知
0x02代表开始
0x41代表A
0x61代表a
0x2B代表符号
[0x30 0x30 0x30 0x30 0x31 0x38] 代表净重数据
0x30 代表小数点的位数
[0x30 0x30 0x30 0x30 0x30 0x30] 代表皮重数据
0x30 代表e 具体含义没深究
0x60 代表f 具体含义没深究
0x20 代表u 具体含义没深究
0x40 代表校验
0x03 代表结束
根据以上分析设计一个结构体如下
typedef struct
{
uint8_t xon; //0x02 STX
uint8_t addr; //0x41 A
uint8_t cmd; //0x61 a
uint8_t fhao; //0x2B + 0x2D -
uint8_t data1[6]; //数据6位
uint8_t dot; //小数点
uint8_t data2[6]; //数据6位
uint8_t err; //错误
uint8_t feat; //特征
uint8_t rese; //保留
uint8_t check; //校验
uint8_t xoff; //结束符
}Ds_Pack_t;
定义一个结构体 并给初值
Ds_Pack_t Ds_Pack=
{
0x02,
0x41,
0x61,
0x2B,
{
0x35,0x30,0x30,0x30,0x31,0x38},
0x32,//小数点数
{
0x30,0x30,0x30,0x30,0x30,0x30},
0x30,
0x60,
0x20,
0x47,//这个校验值是需要计算得出
0x03
};
先编写一个校验函数
编写原则:
将本数据帧校验码以前所有的字节数据异或,然后与 0x40 进行或运算
(CHK) = (XON) xor (ADDR) xor (CMD) xor (DATA1) xor (DATA2) xor … xor (DATAn) or (0x40)
uint8_t Calculate_Check(const Ds_Pack_t *packet)
{
uint8_t checksum;
checksum = (packet->xon) ^ (packet->addr) ^ (packet->cmd) ^ (packet->fhao);
for (uint8_t i = 0; i < sizeof(packet->data1); i++)
{
checksum ^= packet->data1[i];
}
checksum ^= packet->dot;
for (uint8_t i = 0; i < sizeof(packet->data2); i++)
{
checksum ^= packet->data2[i];
}
checksum ^= packet->err ^ packet->feat ^ packet->rese;
checksum = checksum | 0x40;//注意这里是或运算
return checksum;
}
测试校验函数是否正常
int main(void)
{
// 输出结构体中各个字段的值
Print_info(&Ds_Pack);
// 计算校验和
uint8_t Check = Calculate_Check