The Modbus RTU protocol calls for the calculation of the CRC for each message transmitted.
From the perspective of an STM32 controller the CRC calculation properties are :
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; hcrc.Init.GeneratingPolynomial = 32773; hcrc.Init.CRCLength = CRC_POLYLENGTH_16B; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
In hexadecimal notation the polynomial value is 0x8005. Equivalent to using this polynomial in the MX configurator : X15+X2+X0. The CRC can be calculated by the hardware CRC block by using this function:
uint16_t hwCalcCrc(uint8_t *d, int bytes)
{
int i;
hcrc.Instance->CR |= 1;// Reset the calculator
for (i=0; i<bytes; i++)
*(__IO uint8_t *)(__IO void *)(&hcrc.Instance->DR) = d[i];
return hcrc.Instance->DR;
}
The C pre-processor replaces volatile for the __IO macro. So, this is a trick to keep the compiler from optimizing out repeated writes to the same static register.
// WORKS: *(__IO uint8_t *)(__IO void *)(&hcrc.Instance->DR) = d[i]; // DOESN'T WORK hcrc.Instance->DR = d[i];
Test message:
The CRC of
[ 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x02, 0xAA, 0xAA]
is 0x8f58.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.