基本的东西我就不说了看链接文章
Linear11数据格式 这种数据格式具有11位尾数和5位指数(请参见图2)。尾数和指数都是二进制补码整数,这表示它们可以是正数或者负数。
Linear11数据格式
使用公式(1)将实际值转换为Linear11格式:
XREAL WORLD=Y∙2N N可以为正或负, 2N定义了Y尾数LSB的大小。使用Linear11格式可以表示的最小数字是±2-16 x 1 = ±15.3e-6,最大数字为±33.5e6。 由于Signed(有符号)11位整数为-1,024至+1,023,尾数的大小应介于512和1,023之间。由此可以得出一种将实际值编码为PMBus Linear11格式值的方法。即N从-16开始递增,并保持尾数大小在所需范围之内。
文章的补充说明主要是关于负值计算
正值其实挺好理解的,就是负数值有点绕,上面文章写的不太清楚实际负数的值应该是在-512和-1023间正在512和1023间。博主的意思应该是11位中的低10位在512和1,023之间,不过那样写我一下没有看明白。
我搞个例子实现一下:
比如-45的计算步骤为:
-45 先乘16(2的4次方)变为-720在-512和-1023间。然后11位的-720对应的补码 0X800-720=0x530 。那么对应高5位为 0x20-4(4次方)=0x1c。将他们拼在一起就是0XE530。
//typedef __attribute__((packed))struct
typedef struct
{
int16_t base : 11;
int16_t mantissa : 5;
} linear11_t ;
typedef union
{
linear11_t linear;
uint16_t raw;
} linear11_val_t;
inline double linear11_to_double(linear11_val_t t)
{
uint16_t X;
int16_t N;
#if 1
double data,data2;
X=t.linear.base;
N=t.linear.mantissa;
data=X;
data2= pow(2,N);
data=data*data2;
return data;
#else
return t.linear.base * (double)(1 << t.linear.mantissa);
#endif
}
inline double linear11_to_double11(linear11_val_t t)
{
int16_t X;
int16_t N;
#if 1
double data,data2;
X=t.linear.base;
N=t.linear.mantissa;
if(N&(1<<5))
data=X;
else
data=-X;
data2= pow(2,N);
data=data*data2;
return data;
#else
return t.linear.base * (double)(1 << t.linear.mantissa);
#endif
}
double L11_to_double(uint8_t *data)
{
linear11_val_t fixed_temp;
uint16_t r;
double temp ;
r=data[1];
r=r<<8;
r|=data[0];
fixed_temp.raw=r;
temp = linear11_to_double(fixed_temp);
return temp;
}
double L11_to_double11(uint8_t *data)
{
linear11_val_t fixed_temp;
uint16_t r;
double temp ;
r=data[1];
r=r<<8;
r|=data[0];
fixed_temp.raw=r;
temp = linear11_to_double11(fixed_temp);
return temp;
}
inline double linear16_to_double(linear11_val_t t)
{
uint16_t X;
int16_t N;
#if 1
double data,data2;
X=t.linear.base;
N=t.linear.mantissa;
data=X;
data2= pow(2,N);
data=data*data2;
return data;
#else
return t.linear.base * (double)(1 << t.linear.mantissa);
#endif
}
double L16_to_double(uint8_t *data)
{
uint16_t r;
double temp ;
r=data[1];
r=r<<8;
r|=data[0];
temp=(int16_t)r;
temp *=pow(2,-12) ;
return temp;
}