寄存器的位值被重新定义后,怎么计算寄存器的值?
1、单片机的有些数据通常需要保存在寄存器中,它们是以0或1的方式存在的。
上图是一个24位的寄存器,MSB最高位是bit23,LSB最低位是bit0。
当bit23:0=0xFFFFFF时,它对应的十进制数值为:
2、有时为了表示某种数据,有的资料会对寄存器的位值进行重新定义。见下图:
上图中,0.0 ≤寄存器的值域< 1.0
当bit23:0=0xFFFFFF时,它对应的十进制数值为:
//返回数值: 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
//返回数值: -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;
}