2017-01-26 11:25 PM
I am trying to use the hardware peripheral on the STM32F072 to calculate a 16-bit CRC for a modbus RTU application.
The hardware peripheral offers twice the speed compared to my software implementation. I am getting the incorrect CRC back and cannot figure out where I am doing what wrong.
/* USER CODE BEGIN 0 */
#define MODBUS_CRC_POLY 0xA001
/* USER CODE END 0 */
CRC_HandleTypeDef hcrc;
/* CRC init function */
void MX_CRC_Init(void)
{
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.Init.GeneratingPolynomial = MODBUS_CRC_POLY;
hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
hcrc.Init.InitValue = 0xFFFF;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
if (HAL_CRC_Init(&hcrc) != HAL_OK)
{
Error_Handler();
}
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
The buffer that holds the comms from Uart:
unsigned char commsBuffer[150]; �?
If I send two bytes, 0x03 and 0x02 I expect a CRC of 0x8
https://www.lammertbies.nl/comm/info/crc-calculation.html
I get this CRC when I run it through the software implementation, from the hardware peripheral I get 0x9
Software Call:
uwCRCValue = CRC16_2(commsBuffer, 0x02);�?
Peripheral Call:
uwCRCValue = HAL_CRC_Calculate(&hcrc, (uint32_t *)&commsBuffer, 0x02);�?
The SoftwareImplementation function was from this forum:
unsigned int CRC16_2(unsigned char *buf, int len)
{
unsigned int crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
return crc;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Can anyone spot what I am doing wrong please?
#crc #rtu #crc-16 #modbusSolved! Go to Solution.
2017-01-27 09:46 AM
Posted on January 27, 2017 at 18:46
Hi
Botha.Antonie
,
Differences might exist in CRC computations provided by different online calculators, depending on implementation, endianess management, final xor, ...
For CRC16 modbus computation, some are using : 0x8005 polynomial (reversal of 0xA001), input reversed, output reversed.
Could you check if applying below modifications in your HAL CRC configuration, helps reaching expected values ?
&sharpdefine MODBUS_CRC_POLY 0x8005
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; >hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
2017-01-27 09:46 AM
Posted on January 27, 2017 at 18:46
Hi
Botha.Antonie
,
Differences might exist in CRC computations provided by different online calculators, depending on implementation, endianess management, final xor, ...
For CRC16 modbus computation, some are using : 0x8005 polynomial (reversal of 0xA001), input reversed, output reversed.
Could you check if applying below modifications in your HAL CRC configuration, helps reaching expected values ?
&sharpdefine MODBUS_CRC_POLY 0x8005
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; >hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
2017-01-29 11:22 PM
Thank you very much, this solves my incorrect output! Appreciated - very much.
2017-01-30 05:44 AM
Your software method is the least efficient one, there are faster software methods.
https://community.st.com/0D50X00009XkgXtSAJ
Watch for thread-safe implementations using hardware.