modbus_crc.c
#include "modbus_crc.h"
#include "stdio.h"
uint16_t MODBUS_RTU_CRC16(uint8_t *ptr, uint32_t len)
{
uint8_t crcArray[2] = {0};
MODBUS_RTU_CRC16ToArray(ptr, len, crcArray);
if((len + 2) < 300)
{
*(ptr + len) = crcArray[0];
*(ptr + len + 1) = crcArray[1];
}
return ((((uint16_t)crcArray[0]) << 8) | crcArray[1]);
}
void MODBUS_RTU_CRC16ToArray(uint8_t *ptr, uint32_t len, uint8_t *array)
{
int cs = 0xffff;
for (int i = 0; i < len; i++)
{
cs ^= ptr[i];
for (int j = 0; j < 8; j++)
{
if (cs & 1 == 1)
{
cs >>= 1;
cs ^= 0xa001;
}
else
{
cs >>= 1;
}
}
}
array[0] = cs & 0xff; // 校验码的低字节
array[1] = (cs & 0xff00) >> 8; // 校验码的高字节
}
modbus_crc.h
#ifndef __MODBUS_CRC_H__
#define __MODBUS_CRC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f1xx_hal.h"
#define HIG_UINT16(a) ( ((a)>>8) & 0xFF )
#define LOW_UINT16(a) ( (a) & 0xFF )
#define HIG_UINT8(a) ( ((a)>>4) & 0x0F )
#define LOW_UINT8(a) ( (a) & 0x0F )
// modbus crc16校验
// ptr modbus字符串
// len 长度
// return crc字符
uint16_t MODBUS_RTU_CRC16(uint8_t *ptr, uint32_t len);
// modbus crc16校验数据存在array里面
// ptr modbus字符串
// len 长度
// array 需要写入的数组
void MODBUS_RTU_CRC16ToArray(uint8_t *ptr, uint32_t len, uint8_t *array);
#ifdef __cplusplus
}
#endif
#endif /*__MODBUS_CRC_H__ */
使用方法
uint8_t Modbus_RTU_TX_Buff[300] = {0};
Modbus_RTU_TX_Buff[0] = 0x01;
Modbus_RTU_TX_Buff[1] = 0x03;
Modbus_RTU_TX_Buff[2] = 0x00;
Modbus_RTU_TX_Buff[3] = 0x01;
Modbus_RTU_TX_Buff[4] = 0x00;
Modbus_RTU_TX_Buff[5] = 0x01;
MODBUS_RTU_CRC16(Modbus_RTU_TX_Buff, 6);