-
Modbus CRC using an STM32 controller
10/26/2025 at 20:10 • 0 commentsThe 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.
Kris Winer
AVR
Friedrich Menges
Adam Munich
gamaral
Frank Vigilante
Michel
tiefpunkt
icstation
Bruce Land
ken.do
Stefan Wagner
Madhav M Nair
Oktopod Studio
Eduard
Nikola
Thanx for following my project Mini UPDI Programmer !