之前公司485通信是采用软件CRC16,感觉在STM32F7这样的片子上有点浪费了,而且硬件算起来多快啊,手册上写32bit在4个AHB周期完成,16bit在2个AHB周期,8bit在1个AHB周期,如果需要校验的字节数,硬件CRC16带来的效率可高太多了。如果再使用DMA来进行传输,CPU还可以解放。在STM32Cube_FW_F7_V1.7.0\Projects\STM32F767ZI-Nucleo\Examples\CRC\CRC_UserDefinedPolynomial\MDK-ARM工程基础上该的,串口数据以字节方式输入(DMA),如果使用CPU直接计算,需要将4个字节数据凑成32bit。测试了一组数据,与软件CRC16计算的结果一致,计算速度比软件计算快多了。
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* aDataBuffer is 32 bit long*/
- #define BUFFER_SIZE 7
- /* The user defined polynomial*/
- #define CRC_POLYNOMIAL_8B 0xA001
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* CRC handler declaration */
- CRC_HandleTypeDef CrcHandle;
- DMA_HandleTypeDef DmaHandle;
- /* Used for storing CRC Value */
- __IO uint32_t uwCRCValue = 0;
- __IO uint32_t uwCRCValue1 = 0;
- /* Buffer containing the data on which the CRC will be calculated
- (one-word buffer in this example) */
- static const uint32_t aDataBuffer[] = {0x02006D1D,0x0000007C};
- static const uint8_t bDataBuffer[] = {0x1D,0x6D,0x00,0x02,0x7C,0x00,0x00};
- int main(void)
- {
- /* Enable the CPU Cache */
- CPU_CACHE_Enable();
-
- /* STM32F7xx HAL library initialization:
- - Configure the Flash prefetch
- - Systick timer is configured by default as source of time base, but user
- can eventually implement his proper time base source (a general purpose
- timer for example or other time source), keeping in mind that Time base
- duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
- handled in milliseconds basis.
- - Set NVIC Group Priority to 4
- - Low Level Initialization
- */
- HAL_Init();
-
- /* Configure the system clock to 216 MHz */
- SystemClock_Config();
- /* Configure LED1 and LED3 */
- BSP_LED_Init(LED1);
- BSP_LED_Init(LED3);
- /*##-1- Configure the CRC peripheral #######################################*/
- CrcHandle.Instance = CRC;
- /* The default polynomial is not used. It is required to defined it in CrcHandle.Init.GeneratingPolynomial*/
- CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
-
- /* Set the value of the polynomial */
- CrcHandle.Init.GeneratingPolynomial = 0x8005;
-
- /* The user-defined generating polynomial generates a
- 8-bit long CRC */
- CrcHandle.Init.CRCLength = CRC_POLYLENGTH_16B;
- /* The default init value is used */
- CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
- /* The input data are not inverted */
- CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;//CRC_INPUTDATA_INVERSION_NONE;
- /* The output data are not inverted */
- CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;//CRC_OUTPUTDATA_INVERSION_DISABLE;
- /* The input data are 32-bit long */
- CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
-
- CrcHandle.Init.InitValue = 0x0000FFFF;
- if (HAL_CRC_Init(&CrcHandle) != HAL_OK)
- {
- /* Initialization Error */
- Error_Handler();
- }
-
-
- __HAL_RCC_DMA2_CLK_ENABLE();
- DmaHandle.Init.Channel = DMA_CHANNEL_0;
- DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY;
- DmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
- DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE;
- DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
- DmaHandle.Init.MemInc = DMA_MINC_DISABLE;
- DmaHandle.Init.Mode = DMA_NORMAL;
- DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE;
- DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
- DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE;
- DmaHandle.Init.Priority = DMA_PRIORITY_VERY_HIGH ;
- DmaHandle.Instance = DMA2_Stream0;
-
- if(HAL_DMA_Init(&DmaHandle) != HAL_OK)
- {
- Error_Handler();
- }
- __HAL_CRC_DR_RESET(&CrcHandle);
-
- if( HAL_DMA_Start(&DmaHandle,(uint32_t)bDataBuffer, (uint32_t)&CRC->DR, BUFFER_SIZE ) != HAL_OK)
- {
- Error_Handler();
- }
- while(__HAL_DMA_GET_FLAG(&DmaHandle,DMA_FLAG_TCIF0_4) == 0);
- __HAL_DMA_CLEAR_FLAG(&DmaHandle,DMA_FLAG_TCIF0_4);
- uwCRCValue1 = CRC->DR;
- /*##-2- Compute the CRC of "aDataBuffer" ###################################*/
- uwCRCValue = HAL_CRC_Calculate(&CrcHandle, (uint32_t *)aDataBuffer, BUFFER_SIZE);
-
- /*##-3- Compare the CRC value to the Expected one ##########################*/
- if (uwCRCValue != uwExpectedCRCValue)
- {
- /* Wrong CRC value: Turn LED3 on */
- Error_Handler();
- }
- else
- {
- /* Right CRC value: Turn LED1 on */
- BSP_LED_On(LED1);
- }
- /* Infinite loop */
- while (1)
- {
- }
- }
|