宏“__RBIT”详解

__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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值