STM32/STM8技术论坛
直播中

张龙

7年用户 199经验值
私信 关注
[问答]

请问合并两个8位数据的方式是否正确?

在调四轴飞控的时候看到了这行代码:
uint8_t buf[6];
accData[0] = (int16_t)((buf[0] << 8) | buf[1]);//合并8位数据为16位

其中accData[0]是16位的,buf[0]、buf[1]是8位的。

如果先让8位的buf[0]先左移8位,会不会导致buf[0]的数据丢失?8位数组左移8位之后,数组原来的数据跑哪里去了?

我感觉合并数据应该这么合并:
1.将buf[0]的值赋给accData[0]的低8位;
2.accData[0]<<8;
3.将buf[0]的值赋给accData[0]的低8位;

在网上看了别人的C语言合并8位数据为16位数据的代码,大概就是上面那么写的。

所以说那种写法到底有没有错?左移之后的数据会不会丢失?

求大神解答

回帖(31)

甘璐妲

2019-1-30 03:42:30
    orig[0]=1;
    orig[1]=2;
    orig[2]=3;
    orig[3]=4;
    outInt16=(uint16_t)(orig[0]<<8)|orig[1];
    outInt32=(uint32_t)(orig[0]<<24)|(uint32_t)(orig[1]<<16)|(uint32_t)(orig[2]<<8)|orig[3];
    outInt16_1=(orig[0]<<8)|orig[1];
    outInt32_1=(orig[0]<<24)|(orig[1]<<16)|(orig[2]<<8)|orig[3];



举报

张龙

2019-1-30 03:55:52
求大神解答
举报

赵鑫

2019-1-30 04:03:38
本帖最后由 Tcreat 于 2017-5-23 19:44 编辑

你那样合并应该是有问题的  直接buf[0]就被清掉了     accData[0] = (uint16_t)buf[0] << 8 | buf[1]     这样应该就没有太大问题   先强制类型转换buf[0]到16位的 在移位  后面的可以不用强制转换   系统会自动向16位的靠  
举报

张龙

2019-1-30 04:11:34
引用: 60user135 发表于 2019-1-30 11:22
本帖最后由 Tcreat 于 2017-5-23 19:44 编辑

你那样合并应该是有问题的  直接buf[0]就被清掉了     accData[0] = (uint16_t)buf[0] << 8 | buf[1]     这样应该就没有太大问题   先强制类型转换buf[0]到16位的 在移位  后面的可以不用强制转换   系统会自动向16位的靠   ...

我也觉得有问题。。。
举报

张龙

2019-1-30 04:24:23
引用: youpukeji668 发表于 2019-1-30 11:01
    orig[0]=1;
    orig[1]=2;
    orig[2]=3;

本帖最后由 NNXia 于 2017-5-23 22:30 编辑


首先多谢老哥的调试图

outInt16=(uint16_t)(orig[0]<<8)|orig[1];
outInt16_1=(orig[0]<<8)|orig[1];
这两个运行结果一样,

为什么会这样呢????
难道左移8位之后数据没有丢失????

可是如果数组元素的存储地址是从低到高的话,那左移8位岂不是将orig[0]的数据移动到了orig[1]里给覆盖了?
举报

张龙

2019-1-30 04:38:35
引用: 60user135 发表于 2019-1-30 11:22
本帖最后由 Tcreat 于 2017-5-23 19:44 编辑

你那样合并应该是有问题的  直接buf[0]就被清掉了     accData[0] = (uint16_t)buf[0] << 8 | buf[1]     这样应该就没有太大问题   先强制类型转换buf[0]到16位的 在移位  后面的可以不用强制转换   系统会自动向16位的靠   ...

看到4楼那位大哥的调试图了吗?请问为什么会出现那种情况?
举报

徐昕

2019-1-30 04:51:35
我也试了试....
举报

徐昕

2019-1-30 05:05:01
unsigned int
举报

甘璐妲

2019-1-30 05:19:01
引用: chm1 发表于 2019-1-30 11:43
本帖最后由 NNXia 于 2017-5-23 22:30 编辑

stm32的寄存器是32位的
举报

刘杰

2019-1-30 05:28:03
这种还是以事实为准,写代码跑一遍是最简单的获取答案的途径
举报

李杰

2019-1-30 05:47:41
这样写有什么问题?BUFF[0]左移8位后等于16位,右边8位会自动补0,这时再与buff[1]相或,得到一个完整的16位数。请注意,这里的前提是有(int16_t)强制数据类型转换,意思就是已经提前告诉编译器这个数据是要作为16位数据处理的,所以保留的数据也是16位数。
举报

任娟娟

2019-1-30 05:53:11
并没有问题,自己分析一下楼上的汇编就懂了
举报

孙婷婷

2019-1-30 06:08:31
8位数据左移8位后溢出部分丢失,需要进行先强制定义再进行移位。
举报

李海洪

2019-1-30 06:13:38
看汇编代码吧,移位的数据并没有保存在原来的数组,保存在RO R1寄存器上,所以并没有任何问题。
举报

廖宇婷

2019-1-30 06:29:38
看看,帮顶
举报

张龙

2019-1-30 06:39:06
引用: youpukeji668 发表于 2019-1-30 12:37
stm32的寄存器是32位的

也就是说,8位数据左移只要不超过24位,数据就不会丢失?还在那个寄存器里?
举报

张龙

2019-1-30 06:47:18
引用: youpukeji668 发表于 2019-1-30 12:37
stm32的寄存器是32位的

8为数据左移之后时候否丢失是跟运行这行代码的机器有关的吧?
比如在51单片机中,8位数据左移8位之后就丢了?
举报

甘璐妲

2019-1-30 06:54:02
引用: chm1 发表于 2019-1-30 14:06
8为数据左移之后时候否丢失是跟运行这行代码的机器有关的吧?
比如在51单片机中,8位数据左移8位之后就丢了?

51是8位单片机
举报

张龙

2019-1-30 07:12:17
引用: youpukeji668 发表于 2019-1-30 14:12
51是8位单片机

明白了,在32上运行这个代码是没问题的,但这行代码对数据来说是不安全的,移植到其他单片机上有可能不能用。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分