modbus rtu C++ 代码
时间: 2025-05-26 13:26:19 浏览: 16
### Modbus RTU C++ 实现代码示例
以下是基于 Modbus RTU 协议的一个简单 C++ 实现示例。此代码展示了如何通过串口发送请求并接收响应数据。
#### 主要功能描述
该实现包括以下几个部分:
1. 初始化串口通信。
2. 构建 Modbus 请求帧。
3. 发送请求帧并通过串口读取响应帧。
4. 解析接收到的数据包以验证其有效性。
```cpp
#include <iostream>
#include <string.h> // For memset, memcpy functions.
#include <unistd.h> // For sleep function on Linux systems.
#include "modbus_rtu.hpp"
// Function to calculate CRC16 checksum for a given buffer.
uint16_t calculateCRC(const uint8_t* data, int length) {
uint16_t crc = 0xFFFF;
for(int i = 0; i < length; ++i){
crc ^= data[i];
for(int j=0; j<8; ++j){
if(crc & 0x0001){
crc >>= 1;
crc ^= 0xA001;
}
else{
crc >>= 1;
}
}
}
return htons(crc); // Ensure correct byte order.
}
class ModbusRTUClient {
public:
void sendRequest(uint8_t slaveId, uint8_t functionCode, uint16_t address, uint16_t quantity);
private:
uint8_t requestBuffer[256]; // Buffer for storing outgoing requests.
uint8_t responseBuffer[256]; // Buffer for incoming responses.
bool validateResponse();
};
void ModbusRTUClient::sendRequest(uint8_t slaveId, uint8_t functionCode, uint16_t address, uint16_t quantity) {
// Clear buffers before use.
memset(requestBuffer, 0, sizeof(requestBuffer));
memset(responseBuffer, 0, sizeof(responseBuffer));
// Build the MODBUS frame header.
requestBuffer[0] = slaveId; // Slave ID.
requestBuffer[1] = functionCode; // Function Code (e.g., Read Coils).
requestBuffer[2] = static_cast<uint8_t>(address >> 8); // High Byte of Address.
requestBuffer[3] = static_cast<uint8_t>(address & 0xFF); // Low Byte of Address.
requestBuffer[4] = static_cast<uint8_t>(quantity >> 8); // High Byte of Quantity.
requestBuffer[5] = static_cast<uint8_t>(quantity & 0xFF); // Low Byte of Quantity.
// Calculate and append CRC16 checksum at end of message.
uint16_t crcValue = calculateCRC(requestBuffer, 6);
requestBuffer[6] = static_cast<uint8_t>(crcValue >> 8); // High Byte of CRC.
requestBuffer[7] = static_cast<uint8_t>(crcValue & 0xFF); // Low Byte of CRC.
// Send the constructed packet over serial port here...
std::cout << "Sending Request..." << std::endl;
usleep(1000 * 100); // Simulate delay for sending/receiving packets.
// Receive Response from device into `responseBuffer`...
if(validateResponse()) {
std::cout << "Valid Response Received!" << std::endl;
} else {
std::cerr << "Invalid or Corrupted Response." << std::endl;
}
}
bool ModbusRTUClient::validateResponse() {
// Validate received bytes against expected format including CRC check.
size_t respLength = strlen(reinterpret_cast<char*>(responseBuffer));
if(respLength >= 4){ // Minimum valid modbus rtu response has more than 4 bytes excluding CRC.
uint16_t calculatedCRC = calculateCRC(responseBuffer, respLength - 2);
uint16_t receivedCRC = ((static_cast<uint16_t>(responseBuffer[respLength-2]) << 8 ) |
static_cast<uint16_t>(responseBuffer[respLength-1]));
return (calculatedCRC == receivedCRC && responseBuffer[0]==requestBuffer[0]);
}
return false;
}
```
以上是一个简单的 Modbus RTU 客户端类的实现[^2],它包含了构建和解析 Modbus 帧的核心逻辑以及校验机制。
---
### 关键点说明
1. **CRC 计算**: 使用标准的 CRC16 校验算法来确保传输过程中数据的一致性和完整性。
2. **字节顺序处理**: 在计算 CRC 和打包/解包数据时需要注意高低位字节顺序问题,通常需要调用函数如 `htons()` 或手动调整字节序。
3. **错误检测与恢复**: 需要在实际应用中加入更多的异常捕获逻辑以便于调试和维护系统稳定性。
阅读全文
相关推荐

















