帧格式 帧是数据信息传输的基本单元,帧应包含起始符、数据帧总长度、控制字、数据标识码、数据域、 CRC校验码和结束符,具体内容见表E.1。 表E.1 帧格式定义表 名称 字节数 备注 起始符 1 固定常量 0x68,标识一帧信息的开始 数据帧总长度 2 从(包含)数据帧总长度到(包含)结束符之间的字节数 协议代码 1 1 字节 Hex 码,取值范围 0~255,本协议默认 0x03 协议版本 1 1 字节 Hex 码,取值范围 0~255,当前商用发布版本 0x00 控制字 1 Bit7 指令交互类型,值分为 1 和 0。 1:上行指令,指非民用燃气表向采集系统发出的指令; 0:下行指令,指采集系统向非民用燃气表发出的指令。 Bit6 有后续帧标识,1:有后续帧;0:无后续帧; Bit5 | Bit0 指令控制码,共分为如下几类: 1: 远程通道 2: 本地通道 数据域 n 内容根据控制字和数据标识码而变化 CRC 校验码 2 从(包含)数据帧总长度到(包含)数据域,CRC16 校验 结束符 1 固定常量 0x16,标识一帧的结束,用C编写函数,内部指针地址传值
时间: 2024-04-10 11:34:31 浏览: 133
下面是一个使用C语言编写的函数,用于构建帧并计算CRC校验码:
```c
#include <stdint.h>
#define START_FLAG 0x68
#define END_FLAG 0x16
void buildFrame(uint8_t *frame, uint16_t dataLength, uint8_t controlByte, uint8_t *data, uint16_t dataSize) {
// 指针地址传值,保存当前位置的指针
uint8_t *ptr = frame;
// 添加起始符
*ptr++ = START_FLAG;
// 添加数据帧总长度(低字节在前,高字节在后)
*ptr++ = dataLength & 0xFF; // 低字节
*ptr++ = (dataLength >> 8) & 0xFF; // 高字节
// 添加协议代码
*ptr++ = 0x03;
// 添加协议版本
*ptr++ = 0x00;
// 添加控制字
*ptr++ = controlByte;
// 添加数据域
for (int i = 0; i < dataSize; i++) {
*ptr++ = data[i];
}
// 计算CRC校验码
uint16_t crc = calculateCRC(frame + 1, ptr - frame - 1);
// 添加CRC校验码(低字节在前,高字节在后)
*ptr++ = crc & 0xFF; // 低字节
*ptr++ = (crc >> 8) & 0xFF; // 高字节
// 添加结束符
*ptr++ = END_FLAG;
}
uint16_t calculateCRC(uint8_t *data, uint16_t dataSize) {
uint16_t crc = 0xFFFF;
for (int i = 0; i < dataSize; i++) {
crc ^= data[i];
for (int j = 0; j < 8; j++) {
if (crc & 0x0001) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
```
以上代码中,`buildFrame`函数用于构建帧,它接受起始符、数据帧总长度、控制字、数据域和数据域大小作为参数。函数内部使用指针传递地址,按照帧格式逐个添加各个字段的值。然后,调用`calculateCRC`函数计算CRC校验码,并将其添加到帧中。最后,添加结束符。
`calculateCRC`函数用于计算CRC校验码。它接受数据和数据大小作为参数,并使用CRC-16算法计算校验码。
希望这能满足你的需求!如果还有其他问题,请随时提问。
阅读全文