用于嵌入式系统 lpcxpresso 的 C 语言 Modbus 实现
Modbus implementation in C for embedded system lpcxpresso
我是 modbus 的新手,我必须将 lpcxpresso 基板编程为主机,以使用 RS485 Modbus 协议从功率计收集读数。
通过阅读modbus.org的规范,熟悉协议(关于PDU ADU帧、功能码、主从)。
但是我在用C写代码的时候遇到了困难
所以我的问题是:
- 是否必须在开始连接时打开连接、设置波特率等?
- 我正在考虑将帧作为 byte[] 发送。这个对吗?或者还有其他方法吗?
- 发送的数据必须是十六进制,还是二进制或整数?
- CRC 生成和校验。
我将非常感谢所有类型的帮助和帮助:) 如果问题不是很具体或太基础,我深表歉意
第 1 步:暂时忘掉电能表和 modbus。最重要的是让硬件正常工作。 RS485简单来说就是串口。阅读手册,了解如何初始化硬件上的串行端口,并将单个字节发送到您的 PC 并返回。然后将数百个字节发送到 PC 并返回。
第 2 步:让硬件上的计时器也正常工作。 Modbus 协议对时序有一些要求,因此您也需要它。
第 3 步:获取 modbus 规范。它将解释协议格式和校验和。使用 modbus 库或自己编写。在继续使用能量计之前,请确保它可以与 PC 一起使用。
第 4 步:如果您遇到问题,请在 SO 上提出具体问题。
首先:是ModBus RTu还是ASCII?
- 当然可以。您需要按照规格说明指定所有内容。
- 是的,它是一个 unsigned char[]。结构由规格描述。
- 这个问题没有意义:你总是以“记忆”的形式发送信息
转储”,但是对于 RTU,您每个内存字节发送 1 个字节,以防
ASCII 你发送每个内存字节 2 个字节。例如。如果你必须发送一个
字节 0xAE:RTU=0xAE - ASCII= 0x41 0x45。在 RTU 的情况下,如果您必须发送一个 int(4 字节),您将发送这些字节,因为它们存储在内存中,例如:12345 将作为 0x00 0x00 0x30 0x39(大端)、0x39 0x30 0x00 0x00(小端)发送字节序)。
- CRC 的计算在规范中有说明。在我的旧 CBuilder 组件的代码下方
unsigned short TLPsComPort::Calculate_CRC16 ( int Message_Length, char *Message
{
char Low_CRC;
char Bit;
// Constant of ModBus protocol
unsigned short CONSTANT = 0xA001;
unsigned short CRC_REGISTER = 0xFFFF;
for (int i=0; i<Message_Length; i++)
{
Low_CRC = CRC_REGISTER;
Low_CRC = *(Message+i) ^ Low_CRC;
CRC_REGISTER = ((CRC_REGISTER & 0xFF00) | (Low_CRC & 0x00FF));
for (int j=0; j<8;j++)
{
Bit = CRC_REGISTER & 0x0001;
CRC_REGISTER = (CRC_REGISTER >> 1) & 0x7FFF;
if (Bit) CRC_REGISTER = CRC_REGISTER ^ CONSTANT;
}
}
return CRC_REGISTER;
}
我是 modbus 的新手,我必须将 lpcxpresso 基板编程为主机,以使用 RS485 Modbus 协议从功率计收集读数。
通过阅读modbus.org的规范,熟悉协议(关于PDU ADU帧、功能码、主从)。 但是我在用C写代码的时候遇到了困难
所以我的问题是:
- 是否必须在开始连接时打开连接、设置波特率等?
- 我正在考虑将帧作为 byte[] 发送。这个对吗?或者还有其他方法吗?
- 发送的数据必须是十六进制,还是二进制或整数?
- CRC 生成和校验。
我将非常感谢所有类型的帮助和帮助:) 如果问题不是很具体或太基础,我深表歉意
第 1 步:暂时忘掉电能表和 modbus。最重要的是让硬件正常工作。 RS485简单来说就是串口。阅读手册,了解如何初始化硬件上的串行端口,并将单个字节发送到您的 PC 并返回。然后将数百个字节发送到 PC 并返回。
第 2 步:让硬件上的计时器也正常工作。 Modbus 协议对时序有一些要求,因此您也需要它。
第 3 步:获取 modbus 规范。它将解释协议格式和校验和。使用 modbus 库或自己编写。在继续使用能量计之前,请确保它可以与 PC 一起使用。
第 4 步:如果您遇到问题,请在 SO 上提出具体问题。
首先:是ModBus RTu还是ASCII?
- 当然可以。您需要按照规格说明指定所有内容。
- 是的,它是一个 unsigned char[]。结构由规格描述。
- 这个问题没有意义:你总是以“记忆”的形式发送信息 转储”,但是对于 RTU,您每个内存字节发送 1 个字节,以防 ASCII 你发送每个内存字节 2 个字节。例如。如果你必须发送一个 字节 0xAE:RTU=0xAE - ASCII= 0x41 0x45。在 RTU 的情况下,如果您必须发送一个 int(4 字节),您将发送这些字节,因为它们存储在内存中,例如:12345 将作为 0x00 0x00 0x30 0x39(大端)、0x39 0x30 0x00 0x00(小端)发送字节序)。
- CRC 的计算在规范中有说明。在我的旧 CBuilder 组件的代码下方
unsigned short TLPsComPort::Calculate_CRC16 ( int Message_Length, char *Message
{
char Low_CRC;
char Bit;
// Constant of ModBus protocol
unsigned short CONSTANT = 0xA001;
unsigned short CRC_REGISTER = 0xFFFF;
for (int i=0; i<Message_Length; i++)
{
Low_CRC = CRC_REGISTER;
Low_CRC = *(Message+i) ^ Low_CRC;
CRC_REGISTER = ((CRC_REGISTER & 0xFF00) | (Low_CRC & 0x00FF));
for (int j=0; j<8;j++)
{
Bit = CRC_REGISTER & 0x0001;
CRC_REGISTER = (CRC_REGISTER >> 1) & 0x7FFF;
if (Bit) CRC_REGISTER = CRC_REGISTER ^ CONSTANT;
}
}
return CRC_REGISTER;
}