寄存器数值转换

寄存器的位值被重新定义后,怎么计算寄存器的值?

1、单片机的有些数据通常需要保存在寄存器中,它们是以0或1的方式存在的。

上图是一个24位的寄存器,MSB最高位是bit23,LSB最低位是bit0。

当bit23:0=0xFFFFFF时,它对应的十进制数值为:

2、有时为了表示某种数据,有的资料会对寄存器的位值进行重新定义。见下图:

上图中,0.0 ≤寄存器的值域< 1.0

当bit23:0=0xFFFFFF时,它对应的十进制数值为:

寄存器数值转换_第1张图片

//返回数值: 0.0<= 浮点数值 < 1.0

//dat=0x800000,则返回2^(-1)

//dat=0x400000,则返回2^(-2)

//dat=0x200000,则返回2^(-3)

//dat=0x100000,则返回2^(-4)

//dat=0x080000,则返回2^(-5)

//dat=0x040000,则返回2^(-6)

//dat=0x020000,则返回2^(-7)

//dat=0x010000,则返回2^(-8)

//dat=0x008000,则返回2^(-9)

//dat=0x004000,则返回2^(-10)

//dat=0x002000,则返回2^(-11)

//dat=0x001000,则返回2^(-12)

//dat=0x000800,则返回2^(-13)

//dat=0x000400,则返回2^(-14)

//dat=0x000200,则返回2^(-15)

//dat=0x000100,则返回2^(-16)

//dat=0x000080,则返回2^(-17)

//dat=0x000040,则返回2^(-18)

//dat=0x000020,则返回2^(-19)

//dat=0x000010,则返回2^(-20)

//dat=0x000008,则返回2^(-21)

//dat=0x000004,则返回2^(-22)

//dat=0x000002,则返回2^(-23)

//dat=0x000001,则返回2^(-24)

//dat=0x000000,则返回0

//函数功能:它和(float)dat/0x1000000是等价的

float value_commutation(u32 dat)

{

    float f,tmpFloatData;

    u8 i;

    u32 dat_temp;

 

    dat_temp=dat;

    dat_temp = (u32)(dat_temp&0x00FFFFFF);//只有最低24位参与计算

 

    f=0.5;//2^(-1)=0.5

    tmpFloatData=0.0;

    for(i = 0;i<24;i++)

    {

       if(dat_temp&0x800000) tmpFloatData=tmpFloatData+f;

       dat_temp =(u32)( dat_temp << 1 );

       f = f/2.0;

    }

    return tmpFloatData;

}

 

3、负数是以补码保存的,下面的寄存器被定义如下:

MSB最高位为符号位

当MSB=1时,该寄存器表示的是一个负数,负数是以补码保存的;负数的补码减1,就得到反码,再将反码除了最高位MSB外,其余各位取反,就得到负数的原码。

当MSB=0时,该寄存器表示的是一个正数;

-1.0 ≤ 寄存器的值 < 1.0

 

1) 当bit23:0=0xFFFFFF时,它对应的十进制数值是一个负数,因此

反码为:0xFFFFFF-1=0xFFFFFE

原码为:(~0xFFFFFE)|0x800000=0x000001|0x800000=0x800001

2) 当bit23:0=0x800000时,它对应的十进制数值是一个负数,因此

反码为:0x800000-1=0x7FFFFF

原码为:(~0x7FFFFF) |0x800000=0x800000|0x800000 =-0x800000=-1

负数补码的最高位为1,其余各位为0,表示该负数最小,因此这里为-1;

 

3) 当bit23:0=0x800001时,它对应的十进制数值是一个负数,因此

反码为:0x800001-1=0x800000

原码为:(~0x800000)|0x800000=0x7FFFFF|0x800000 =-0x7FFFFF

寄存器数值转换_第2张图片

//返回数值: -1.0<= 浮点数值 < 1.0

//dat=0x800000,则返回-2^(0)

//dat=0x400000,则返回2^(-1)

//dat=0x200000,则返回2^(-2)

//dat=0x100000,则返回2^(-3)

//dat=0x080000,则返回2^(-4)

//dat=0x040000,则返回2^(-5)

//dat=0x020000,则返回2^(-6)

//dat=0x010000,则返回2^(-7)

//dat=0x008000,则返回2^(-8)

//dat=0x004000,则返回2^(-9)

//dat=0x002000,则返回2^(-10)

//dat=0x001000,则返回2^(-11)

//dat=0x000800,则返回2^(-12)

//dat=0x000400,则返回2^(-13)

//dat=0x000200,则返回2^(-14)

//dat=0x000100,则返回2^(-15)

//dat=0x000080,则返回2^(-16)

//dat=0x000040,则返回2^(-17)

//dat=0x000020,则返回2^(-18)

//dat=0x000010,则返回2^(-19)

//dat=0x000008,则返回2^(-20)

//dat=0x000004,则返回2^(-21)

//dat=0x000002,则返回2^(-22)

//dat=0x000001,则返回2^(-23)

//dat=0x000000,则返回0

//函数功能:它和(float)dat/0x800000在功能上是等价的

float value_commutation1(u32 dat)

{

    float f,tmpFloatData;

    s8 flag;

    u32 dat_temp;

    u8 i;

 

    dat_temp=dat;

    dat_temp = (u32)(dat_temp&0X00FFFFFF);//只有最低24位参与计算

//计算负数原码开始

    flag = 1;//假定为正数

    f=0.5;

    if(dat&0x800000)//最高位为符号位

    {

       flag = -1;//设置为负数

       dat_temp = dat_temp -1;//负数的补码减一得到反码

       dat_temp = (u32)(~dat_temp); //除最高位外,其余位取反得到原码

       dat_temp = (u32)(dat_temp&0X7FFFFF);

    }

    if(dat==0x800000) tmpFloatData=1.0;

    else tmpFloatData=0.0;

//计算负数原码结束

    for(i = 0;i<23;i++)

    {

       dat_temp =(u32)( dat_temp << 1 );

       if(dat_temp&0x800000) tmpFloatData=tmpFloatData+f;

       f = f/2.0;

    }

 

    tmpFloatData = tmpFloatData*flag;//添加正负号

    return tmpFloatData;

}

 

你可能感兴趣的:(产品研发,补码,stm32,算法)