__RBIT()是位反转(Bit Reversal)函数,它指的是一个数的所有bit位依照中点交换位置,位反转也可以叫二进制逆序。STM32G474的位反转是在字的基础上完成的。
在头文件“cmsis_armclang.h”中有“__RBIT”宏,定义如下:
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __builtin_arm_rbit
#define CRC_POLYNOMIAL_16B 0x8005
//硬件CRC多项式为0x8005
//CRC16=x^16 + x^15 + x^2 + 1,因为bit15=1,bit2=1,bit0=1,所以正向校验的多项式的值为0x8005
//CRC校验分为正向校验和反向校验,而软件CRC使用的是反向校验,其多项式为0xA001,其原因如下:
uint32_t d;
d= __RBIT(CRC_POLYNOMIAL_16B)>>16;
//执行后d=0xA001,所以软件CRC使用的是反向校验。
分析CRC16_DATA8[BUFFER_SIZE] = {0x4D, 0x3C, 0x2B, 0x1A,0xBE, 0x71, 0xC9, 0x8A,0x5E}位反转:
例如0x4D3C2B1A,经过“位反转”后,如下:
bit0=0经过“位反转”后变成了bit31=0,
bit1=1经过“位反转”后变成了bit30=1,
bit2=0经过“位反转”后变成了bit29=0,
bit3=1经过“位反转”后变成了bit28=1,可见A经过“位反转”后变成了5
bit4=1经过“位反转”后变成了bit27=1,
bit5=0经过“位反转”后变成了bit26=0,
bit6=0经过“位反转”后变成了bit25=0,
bit7=0经过“位反转”后变成了bit24=0,可见1经过“位反转”后变成了8
bit8=1经过“位反转”后变成了bit23=1,
bit9=1经过“位反转”后变成了bit22=1,
bit10=0经过“位反转”后变成了bit21=0,
bit11=1经过“位反转”后变成了bit20=1,可见B经过“位反转”后变成了D
bit12=0经过“位反转”后变成了bit19=0,
bit13=1经过“位反转”后变成了bit18=1,
bit14=0经过“位反转”后变成了bit17=0,
bit15=0经过“位反转”后变成了bit16=0,可见2经过“位反转”后变成了4
bit16=0经过“位反转”后变成了bit15=0,
bit17=0经过“位反转”后变成了bit14=0,
bit18=1经过“位反转”后变成了bit13=1,
bit19=1经过“位反转”后变成了bit12=1,可见C经过“位反转”后变成了3
bit20=1经过“位反转”后变成了bit11=1,
bit21=1经过“位反转”后变成了bit10=1,
bit22=0经过“位反转”后变成了bit9=0,
bit23=0经过“位反转”后变成了bit8=0,可见3经过“位反转”后变成了C
bit24=1经过“位反转”后变成了bit7=1,
bit25=0经过“位反转”后变成了bit6=0,
bit26=1经过“位反转”后变成了bit5=1,
bit27=1经过“位反转”后变成了bit4=1,可见D经过“位反转”后变成了B
bit28=0经过“位反转”后变成了bit3=0,
bit29=0经过“位反转”后变成了bit2=0,
bit30=1经过“位反转”后变成了bit1=1,
bit31=0经过“位反转”后变成了bit0=0,可见2经过“位反转”后变成了2
所以0x4D3C2B1A,经过“位反转”后就是0x58D43CB2;
同理,0xBE71C98A,经过“位反转”后就是0x51938E7D;
若剩余一个字节,则按照字节反转,0x5E,经过“位反转”后就是0x7A;
因此,
CRC16_DATA8[BUFFER_SIZE] = {0x4D, 0x3C, 0x2B, 0x1A,0xBE, 0x71, 0xC9, 0x8A,0x5E}位反转后,就是
CRC16_DATA8_CHECK[BUFFER_SIZE] = {0x58, 0xD4, 0x3C, 0xB2,0x51, 0x93, 0x8E, 0x7D,0x7A}
分析0x0000C20A位反转:
A经过“位反转”后变成了5;
0经过“位反转”后变成了0;
2经过“位反转”后变成了4;
C经过“位反转”后变成了3;
0经过“位反转”后变成了0;
0经过“位反转”后变成了0;
0经过“位反转”后变成了0;
0经过“位反转”后变成了0;
因此0x0000C20A经过位反转后,就是0x50430000;相当于执行了__RBIT(0x0000C20A),就是0x50430000;
__RBIT(0x0000C20A) >> 16 的值就是0x5043