单片机学习小组
登录
直播中
张鑫
7年用户
1032经验值
私信
关注
如何利用一个函数将24位的数据类型转换成32位的呢
开启该帖子的消息推送
函数
计算机中的负数是怎么存储的?
如何利用一个函数将24位的数据类型转换成32位的呢?
回帖
(1)
王静
2022-2-25 15:12:57
一般情况下,ADC与单片机的通讯方式都是串行的,可能是IIC、SPI等。假设现在有一个24位的ADC,那么在正常工作时,单片机将依次接收到24bit的数据。ADC的数据是24位的,但是没有24位的数据类型。在单片机中,int类型的数据一般是32位的。所以需要一个函数来完成两者的转换。
首先我们要搞清楚计算机中数字的二进制存储形式。对于一个24位数,其计算关系可用下面的公式表达:
对于一个32位数,其计算关系可用下面的公式表达:
显而易见,对于一个正数来说,要拓宽它的位数,只需要在其多出来的位上补0即可。因为只是多项式中多加了几个0而已,并不会改变数据的大小。
而如果我们转换的数据是一个负数,问题就不那么简单了。
首先我们要搞清楚负数是怎么存储的。计算机中的负数是以补码形式存储的,即补码=原码取反+1。就是对正数先取反码,然后再加1。前面我们已经搞清楚了对一个正数该怎么拓宽,即补0。如果对拓宽后的这个正数再进行取反然后加1,那么我们是不是得到了一个位数改变的负数呢?答案肯定是对的。
假设我们现在有一个负数,我们可以先倒推回去,将其变成正数,然后用我们确定正确的方式对这个正数进行转换,然后把正数再变成负数。此时得到的负数位数已经是改变了的。可能有点绕,但确实是可行的。我们会发现,其实最终的效果是在多出来的位上补了1。这是因为我们对正数补0之后取了反,那就相当于直接补1了。
下面开始编写我们的代码。这里定义一个数组adc[3],用来存储ADC的数据。将接收到的三字节数据由低到高依次放置到数组中。即adc[0]放置低字节,adc[1]放置中间的字节,adc[2]放置高字节。
int adc24to32(unsigned char *padc);
此函数的输入参数为数组的地址。函数内部完成数据的转换,返回值为转换之后的32位数据。
在函数内定义一个int型的数据value,然后再定义一个指向value的指针。然后将数组中的数据搬到value所在的地址中。
*p = *padc;
*(p+1) = *(padc+1);
*(p+2) = *(padc+2);
此处我们默认按照正数处理,然后判断其符号。判断是不是负数只需要判断*(padc+2)的最高位是不是1即可,将其与0x80相与,如果结果为1则表示其为负数,反之则不是。即:
if(*(padc+2) & 0x80)
{
*(p+3) = 0xff;
return value;
}
else
{
return value;
}
假设我们现在有如下数据,下面对其一一进行检验。
原始数据(二进制)
理论值(十进制)
0X7FFFFF
8388607
0X400000
4194304
0X000001
1
0X000000
0
0XFFFFFF
-1
0XC00000
-4194304
0X800000
-8388607
这里定义三个数组来存储我们的原始数据,LL为数据的低字节,MM是数据的中间字节,HH为数据的高字节。在测试的时候,给adc[ ]赋值,然后调用刚才编写的函数。最后将结果打印出来,跟预期的结果进行对比,就可以知道我们的函数有没有错误。
unsigned char LL[7] = {0xff,0x00,0x01,0x00,0xff,0x00,0x00};
unsigned char MM[7] = {0xff,0x00,0x00,0x00,0xff,0x00,0x00};
unsigned char HH[7] = {0x7f,0x40,0x00,0x00,0xff,0xc0,0x80};
然后我们定义一个for循环,依次取出其中的数据进行检验
int main( )
{
int i;
for(i = 0; i < 7; i++)
{
adc[0] = LL
;
adc[1] = MM
;
adc[2] = HH
;
value = adc24to32(adc);
printf("nThis 24bit value %02x%02x%02x change to int32 is %dn",adc[2],adc[1],adc[0],value);
}
return 0;
}
程序运行的结果如下:
跟表格里的结果进行对比,可知程序没有错误。
一般情况下,ADC与单片机的通讯方式都是串行的,可能是IIC、SPI等。假设现在有一个24位的ADC,那么在正常工作时,单片机将依次接收到24bit的数据。ADC的数据是24位的,但是没有24位的数据类型。在单片机中,int类型的数据一般是32位的。所以需要一个函数来完成两者的转换。
首先我们要搞清楚计算机中数字的二进制存储形式。对于一个24位数,其计算关系可用下面的公式表达:
对于一个32位数,其计算关系可用下面的公式表达:
显而易见,对于一个正数来说,要拓宽它的位数,只需要在其多出来的位上补0即可。因为只是多项式中多加了几个0而已,并不会改变数据的大小。
而如果我们转换的数据是一个负数,问题就不那么简单了。
首先我们要搞清楚负数是怎么存储的。计算机中的负数是以补码形式存储的,即补码=原码取反+1。就是对正数先取反码,然后再加1。前面我们已经搞清楚了对一个正数该怎么拓宽,即补0。如果对拓宽后的这个正数再进行取反然后加1,那么我们是不是得到了一个位数改变的负数呢?答案肯定是对的。
假设我们现在有一个负数,我们可以先倒推回去,将其变成正数,然后用我们确定正确的方式对这个正数进行转换,然后把正数再变成负数。此时得到的负数位数已经是改变了的。可能有点绕,但确实是可行的。我们会发现,其实最终的效果是在多出来的位上补了1。这是因为我们对正数补0之后取了反,那就相当于直接补1了。
下面开始编写我们的代码。这里定义一个数组adc[3],用来存储ADC的数据。将接收到的三字节数据由低到高依次放置到数组中。即adc[0]放置低字节,adc[1]放置中间的字节,adc[2]放置高字节。
int adc24to32(unsigned char *padc);
此函数的输入参数为数组的地址。函数内部完成数据的转换,返回值为转换之后的32位数据。
在函数内定义一个int型的数据value,然后再定义一个指向value的指针。然后将数组中的数据搬到value所在的地址中。
*p = *padc;
*(p+1) = *(padc+1);
*(p+2) = *(padc+2);
此处我们默认按照正数处理,然后判断其符号。判断是不是负数只需要判断*(padc+2)的最高位是不是1即可,将其与0x80相与,如果结果为1则表示其为负数,反之则不是。即:
if(*(padc+2) & 0x80)
{
*(p+3) = 0xff;
return value;
}
else
{
return value;
}
假设我们现在有如下数据,下面对其一一进行检验。
原始数据(二进制)
理论值(十进制)
0X7FFFFF
8388607
0X400000
4194304
0X000001
1
0X000000
0
0XFFFFFF
-1
0XC00000
-4194304
0X800000
-8388607
这里定义三个数组来存储我们的原始数据,LL为数据的低字节,MM是数据的中间字节,HH为数据的高字节。在测试的时候,给adc[ ]赋值,然后调用刚才编写的函数。最后将结果打印出来,跟预期的结果进行对比,就可以知道我们的函数有没有错误。
unsigned char LL[7] = {0xff,0x00,0x01,0x00,0xff,0x00,0x00};
unsigned char MM[7] = {0xff,0x00,0x00,0x00,0xff,0x00,0x00};
unsigned char HH[7] = {0x7f,0x40,0x00,0x00,0xff,0xc0,0x80};
然后我们定义一个for循环,依次取出其中的数据进行检验
int main( )
{
int i;
for(i = 0; i < 7; i++)
{
adc[0] = LL
;
adc[1] = MM
;
adc[2] = HH
;
value = adc24to32(adc);
printf("nThis 24bit value %02x%02x%02x change to int32 is %dn",adc[2],adc[1],adc[0],value);
}
return 0;
}
程序运行的结果如下:
跟表格里的结果进行对比,可知程序没有错误。
举报
更多回帖
rotate(-90deg);
回复
相关问答
函数
请问使用强制
数据类型
转换
函数
的时候,
数据类型
type端该如何设置,才能使
数据
成功
转换
类型
?
2018-06-25
4205
如何把字符
转换成数据类型
方便我们使用?
2021-12-09
741
怎么把int
类型
的
数据
转换成
字符串?
2023-11-01
549
怎么
转换
连接
数据类型
?
2016-11-29
3933
labview音频
数据
的
类型
与生成噪音的
数据类型
不
一
致。
2014-04-01
2826
如果
将
float
转换成
char
类型
为什么会提示报错
2021-12-01
1141
关于
数据类型
转换
的问题
2016-04-27
3491
32
位
浮点怎么
转换成
16
位
定点?
2020-05-05
2224
怎样把AD
转换
得到的补码
转换成
一
个
有符号的整数
呢
2022-02-25
1856
如何
将
labview串口接收到的多路16进制
数据
转换成
相应的10进制数,并可以选择输出
2016-04-07
3607
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
英国威廉希尔公司网站
william hill官网 版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分