小玩一下沁恒CH32V317的CRC32外设
在嵌入式系统中,数据在传输或存储时,难免会遇到噪声干扰或硬件老化导致的比特翻转。比如,串口通信中,电磁干扰可能让 0 变成 1;又或者Flash 长时间使用和写入时,某些存储单元出错。CRC32就是一种高效的错误检测方法,用来发现这些意外的数据变化。
CRC32的核心是多项式除法,具体的理论我这里不再赘述。总之利用这个算法可以校验数据是否完整,是否出错。CRC32算法有几个参数我们必须关注:1. 初始值;2. 校验多项式;3. 结果是否异或;4. 结果是否取反;
说了不少的理论知识,在实际应用中,我们多数情况还是利用MCU内部的硬件CRC32来计算,以简化软件设计实现,节省CPU和RAM资源,提升整个系统的性能。沁恒CH32V317内部集成了CRC32外设,软件实现特别简单——仅需要操作CRC_CTLR和CRC_DATAR两个寄存器,即在校验开始前通过写入CRC_CTLR寄存器reset一下CRC32外设,让其初始值设置为0xFFFF_FFFF,之后不断的把待校验数据写入到CRC_DATAR寄存器。待写入最后一个数据后,回读一下CRC_DATAR寄存器即可得到CRC32的校验值。简单不?让我们看看代码如何实现吧!
/*********************************************************************
* @fn CRC_ResetDR
*
* [url=/u/brief]@brief[/url] Resets the CRC Data register (DR).
*
* [url=/u/return]@return[/url] none
*/
void CRC_ResetDR(void)
{
CRC->CTLR = CRC_CTLR_RESET;
}
/*********************************************************************
* @fn CRC_CalcBlockCRC
*
* @brief Computes the 32-bit CRC of a given buffer of data word(32-bit).
*
* @param pBuffer - pointer to the buffer containing the data to be computed.
* BufferLength - length of the buffer to be computed.
*
* @return 32-bit CRC.
*/
uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)
{
uint32_t index = 0;
for(index = 0; index < BufferLength; index++)
{
CRC->DATAR = pBuffer[index];
}
return (CRC->DATAR);
}
/*********************************************************************
* @fn CRC_GetCRC
*
* @brief Returns the current CRC value.
*
* @return 32-bit CRC.
*/
uint32_t CRC_GetCRC(void)
{
return (CRC->DATAR);
}
我们使用上面这三个官方提供的CRC32的API函数来完成我们的测试评估任务。简单不!?