你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

这种【合并两个8位数据】的方式是否正确?

[复制链接]
NNXia 提问时间:2017-5-23 18:32 /
在调四轴飞控的时候看到了这行代码:
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位数据的代码,大概就是上面那么写的。

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

求大神解答
收藏 评论30 发布时间:2017-5-23 18:32

举报

30个回答
斜阳 回答时间:2017-5-23 22:08:10
    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];

o0-1优化结果.png
o0-2优化结果.png
结果.png


NNXia 回答时间:2017-5-23 22:24:15
本帖最后由 NNXia 于 2017-5-23 22:30 编辑
斜阳__ 发表于 2017-5-23 22:08
orig[0]=1;
    orig[1]=2;
    orig[2]=3;


首先多谢老哥的调试图

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

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

可是如果数组元素的存储地址是从低到高的话,那左移8位岂不是将orig[0]的数据移动到了orig[1]里给覆盖了?
NNXia 回答时间:2017-5-23 18:51:33
求大神解答
Tcreat 回答时间:2017-5-23 19:42:24
本帖最后由 Tcreat 于 2017-5-23 19:44 编辑

你那样合并应该是有问题的  直接buf[0]就被清掉了     accData[0] = (uint16_t)buf[0] << 8 | buf[1]     这样应该就没有太大问题   先强制类型转换buf[0]到16位的 在移位  后面的可以不用强制转换   系统会自动向16位的靠  
NNXia 回答时间:2017-5-23 22:18:11
Tcreat 发表于 2017-5-23 19:42
你那样合并应该是有问题的  直接buf[0]就被清掉了     accData[0] = (uint16_t)buf[0]

我也觉得有问题。。。
NNXia 回答时间:2017-5-23 22:33:39
Tcreat 发表于 2017-5-23 19:42
你那样合并应该是有问题的  直接buf[0]就被清掉了     accData[0] = (uint16_t)buf[0]

看到4楼那位大哥的调试图了吗?请问为什么会出现那种情况?
Mandelbrot_Set 回答时间:2017-5-23 23:26:14
我也试了试....
捕获.PNG
Mandelbrot_Set 回答时间:2017-5-23 23:29:09
unsigned int
捕获2.PNG
斜阳 回答时间:2017-5-24 08:12:11
NNXia 发表于 2017-5-23 22:24
首先多谢老哥的调试图

outInt16=(uint16_t)(orig[0]

stm32的寄存器是32位的
潇潇雨歇pku 回答时间:2017-5-24 09:06:24
这种还是以事实为准,写代码跑一遍是最简单的获取答案的途径
hjl2832 回答时间:2017-5-24 09:08:04
这样写有什么问题?BUFF[0]左移8位后等于16位,右边8位会自动补0,这时再与buff[1]相或,得到一个完整的16位数。请注意,这里的前提是有(int16_t)强制数据类型转换,意思就是已经提前告诉编译器这个数据是要作为16位数据处理的,所以保留的数据也是16位数。
风子 回答时间:2017-5-24 09:10:34
并没有问题,自己分析一下楼上的汇编就懂了
废鱼 回答时间:2017-5-24 09:13:15
8位数据左移8位后溢出部分丢失,需要进行先强制定义再进行移位。
疯de_恒 回答时间:2017-5-24 10:41:02
看汇编代码吧,移位的数据并没有保存在原来的数组,保存在RO R1寄存器上,所以并没有任何问题。
123下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版