制作静态网站制作,小程序api有哪些,浦东新区苏州网站建设,用阿里云服务器做盗版小说网站吗作者#xff1a; Herman Ye Galbot Auromix 测试环境#xff1a; Ubuntu20.04 更新日期#xff1a; 2023/08/30 注1#xff1a; Auromix 是一个机器人爱好者开源组织。 注2#xff1a; 本文在更新日期经过测试#xff0c;确认有效。
笔者出于学习交流目的#xff0c; 给…作者 Herman Ye Galbot Auromix 测试环境 Ubuntu20.04 更新日期 2023/08/30 注1 Auromix 是一个机器人爱好者开源组织。 注2 本文在更新日期经过测试确认有效。
笔者出于学习交流目的 给出以下ModbusCRC16校验常用的四种函数以及完整示例代码
1.计算CRC
注意 此处在末尾进行了高低位交换可根据需求删减代码交换高低位顺序。
/*** brief Calculate the Modbus CRC-16 checksum for a given data vector.** This function calculates the CRC-16 checksum using the Modbus protocol* polynomial for the provided data vector.** param data The vector of bytes for which to calculate the CRC-16 checksum.* return The calculated CRC-16 checksum value as an unsigned short.*/
unsigned short calculateModbusCRC16(const vectoruint8_t data)
{int length data.size();unsigned short CRC 0xFFFF; // Initial valuefor (int i 0; i length; i){CRC CRC ^ data[i]; // XOR byte into the least significant byte of CRCfor (int j 0; j 8; j){if (CRC 1){CRC 1;CRC ^ 0xA001;}else{CRC 1;}}}// Swap the bytes of the CRC to match Modbus conventionunsigned short swappedCRC ((CRC 8) 0xFF) | ((CRC 0xFF) 8);return swappedCRC;
}2.添加CRC校验位
注意 此处进行了高低位交换可根据需求删减代码交换高低位顺序。
/*** brief Add Modbus CRC-16 to a data vector.* * This function calculates the Modbus CRC-16 checksum for the provided data vector* and appends the high and low bytes of the CRC to the end of the data vector.* * param data The data vector to which the CRC will be added.*/
void addModbusCRC16(vectoruint8_t data)
{// Calculate the CRC-16 checksumunsigned short crc calculateModbusCRC16(data);// Append the high byte of CRC to the data vectordata.push_back((crc 8) 0xFF);// Append the low byte of CRC to the data vectordata.push_back(crc 0xFF);
}3.删除CRC校验位
/*** brief Remove Modbus CRC-16 from a vector of data.* * This function takes a vector of data with Modbus CRC-16 at the end and removes* the CRC-16 bytes from the end of the vector, effectively stripping the CRC-16* checksum from the data.* * param dataWithCRC A reference to the vector containing the data with CRC-16.* * note This function does not perform any CRC-16 validation or calculation. It* assumes that the last two bytes of the vector represent the CRC-16 checksum* and removes them regardless of their validity.* * warning It is the responsibility of the caller to ensure that the input vector* has a length of at least 2, as this function does not perform length checking.* If the length is less than 2, an error message is printed to the standard error* stream, and no modifications are made to the input vector.*/
void removeModbusCRC16(vectoruint8_t dataWithCRC) {int length dataWithCRC.size();// Error checkif (length 2) {cerr Invalid data length endl;return;}// Delete CRC at the enddataWithCRC.resize(length - 2);
}4.比较CRC校验位
/*** brief Compare Modbus CRC-16* * This function compares the CRC-16 checksum in the given data with the calculated CRC-16 checksum* of the data without the CRC bytes. If they match, it indicates that the data is intact and has not* been corrupted during transmission.* * param dataWithCRC A vector containing the data along with the CRC-16 checksum bytes.* return True if the calculated CRC-16 matches the original CRC-16, indicating data integrity.* False if the data length is invalid or if the CRCs do not match.*/
bool compareModbusCRC16(const vectoruint8_t dataWithCRC) {int length dataWithCRC.size();// Error checkif (length 2) {cerr Invalid data length endl;return false;}// Get data without CRCvectoruint8_t dataWithoutCRC(dataWithCRC.begin(), dataWithCRC.end() - 2);// Calculate CRC-16 checksumunsigned short calculatedCRC calculateModbusCRC16(dataWithoutCRC);// Get original CRC-16 checksum from the last two bytes of the dataunsigned short originalCRC (dataWithCRC[length - 2] 8) | dataWithCRC[length - 1];return originalCRC calculatedCRC;
}5.完整示例代码
#include iostream
#include vector
#include iomanip
using namespace std;/*** brief Calculate the Modbus CRC-16 checksum for a given data vector.** This function calculates the CRC-16 checksum using the Modbus protocol* polynomial for the provided data vector.** param data The vector of bytes for which to calculate the CRC-16 checksum.* return The calculated CRC-16 checksum value as an unsigned short.*/
unsigned short calculateModbusCRC16(const vectoruint8_t data)
{int length data.size();unsigned short CRC 0xFFFF; // Initial valuefor (int i 0; i length; i){CRC CRC ^ data[i]; // XOR byte into the least significant byte of CRCfor (int j 0; j 8; j){if (CRC 1){CRC 1;CRC ^ 0xA001;}else{CRC 1;}}}// Swap the bytes of the CRC to match Modbus conventionunsigned short swappedCRC ((CRC 8) 0xFF) | ((CRC 0xFF) 8);return swappedCRC;
}/*** brief Add Modbus CRC-16 to a data vector.* * This function calculates the Modbus CRC-16 checksum for the provided data vector* and appends the high and low bytes of the CRC to the end of the data vector.* * param data The data vector to which the CRC will be added.*/
void addModbusCRC16(vectoruint8_t data)
{// Calculate the CRC-16 checksumunsigned short crc calculateModbusCRC16(data);// Append the high byte of CRC to the data vectordata.push_back((crc 8) 0xFF);// Append the low byte of CRC to the data vectordata.push_back(crc 0xFF);
}/*** brief Remove Modbus CRC-16 from a vector of data.* * This function takes a vector of data with Modbus CRC-16 at the end and removes* the CRC-16 bytes from the end of the vector, effectively stripping the CRC-16* checksum from the data.* * param dataWithCRC A reference to the vector containing the data with CRC-16.* * note This function does not perform any CRC-16 validation or calculation. It* assumes that the last two bytes of the vector represent the CRC-16 checksum* and removes them regardless of their validity.* * warning It is the responsibility of the caller to ensure that the input vector* has a length of at least 2, as this function does not perform length checking.* If the length is less than 2, an error message is printed to the standard error* stream, and no modifications are made to the input vector.*/
void removeModbusCRC16(vectoruint8_t dataWithCRC) {int length dataWithCRC.size();// Error checkif (length 2) {cerr Invalid data length endl;return;}// Delete CRC at the enddataWithCRC.resize(length - 2);
}/*** brief Compare Modbus CRC-16* * This function compares the CRC-16 checksum in the given data with the calculated CRC-16 checksum* of the data without the CRC bytes. If they match, it indicates that the data is intact and has not* been corrupted during transmission.* * param dataWithCRC A vector containing the data along with the CRC-16 checksum bytes.* return True if the calculated CRC-16 matches the original CRC-16, indicating data integrity.* False if the data length is invalid or if the CRCs do not match.*/
bool compareModbusCRC16(const vectoruint8_t dataWithCRC) {int length dataWithCRC.size();// Error checkif (length 2) {cerr Invalid data length endl;return false;}// Get data without CRCvectoruint8_t dataWithoutCRC(dataWithCRC.begin(), dataWithCRC.end() - 2);// Calculate CRC-16 checksumunsigned short calculatedCRC calculateModbusCRC16(dataWithoutCRC);// Get original CRC-16 checksum from the last two bytes of the dataunsigned short originalCRC (dataWithCRC[length - 2] 8) | dataWithCRC[length - 1];return originalCRC calculatedCRC;
}int main() {// Example data 1vectoruint8_t deviceData1 {0x01, 0x10, 0x00, 0x02, 0x00, 0x06, 0x0C, 0x41, 0x20,0x00, 0x00, 0x42, 0xC8, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00,0x84, 0xC1}; // Example CRC: 0x84, 0xC1// Print original datacout Original data 1: ;for (uint8_t byte : deviceData1) {cout hex uppercase setw(2) setfill(0) (int)byte ;}cout endl;bool comparedResultcompareModbusCRC16(deviceData1);if (comparedResult)coutCompared result: TRUEendl;elsecoutCompared result: FALSEendl;// Example data 2coutendl;vectoruint8_t deviceData2 {0x01, 0x06, 0x00, 0x00, 0x01, 0x02, 0x02};// Example CRC: 0xDA, 0xC7cout Original data 2: ;for (uint8_t byte : deviceData2) {cout hex uppercase setw(2) setfill(0) (int)byte ;}cout endl;// Add CRC and print modified dataaddModbusCRC16(deviceData2);cout Add CRC to original data 2: ;for (uint8_t byte : deviceData2) {cout hex uppercase setw(2) setfill(0) (int)byte ;}cout endl;// Remove CRC from dataremoveModbusCRC16(deviceData2);cout Remove CRC from modified data 2: ;for (uint8_t byte : deviceData2) {cout hex uppercase setw(2) setfill(0) (int)byte ;}cout endl; return 0;
}