OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4809|回复: 6

关于移位操作的一个小问题

[复制链接]

12

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
246
金钱
246
注册时间
2015-1-28
在线时间
50 小时
发表于 2015-3-16 12:35:11 | 显示全部楼层 |阅读模式
5金钱
BUF[0]储存了某寄存器的高八位,BUF[1]储存了某寄存器的低八位。通过如下代码将高低八位合并

[mw_shl_code=c,true]BYTE BUF[8]; x = BUF[0] << 8 | BUF[1]; [/mw_shl_code]

请问其具体是如何操作的?

最佳答案

查看完整内容[请看2#楼]

回复【4楼】opennedver: --------------------------------- dat <<= 1; 移出高位,这样操作是因为dat 被定义成了8bit了,而且是自己给自己8bit里肯定放不下9位数据的。 如果BUF[0]<<=8;BUF[0]就是 0000 0000了,不会是10110001 00000000。之所以是10110001 00000000是因为接收的数据是x,这里的x是被定义成16位的了,而且是在stm32里操作的(51单片机里可能有不一样的结果)。其 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

30

主题

705

帖子

1

精华

新手上路

积分
21
金钱
21
注册时间
2013-3-14
在线时间
52 小时
发表于 2015-3-16 12:35:12 | 显示全部楼层
回复【4楼】opennedver:
---------------------------------
dat <<= 1; 移出高位,这样操作是因为dat 被定义成了8bit了,而且是自己给自己8bit里肯定放不下9位数据的。
如果BUF[0]<<=8;BUF[0]就是 0000 0000了,不会是10110001 00000000。之所以是10110001 00000000是因为接收的数据是x,这里的x是被定义成16位的了,而且是在stm32里操作的(51单片机里可能有不一样的结果)。其实这样操作会容易出错的,编译器不一样可能结果不一样。x=(u16)BUF[0]<<8;---这样做才是安全的,需要加强制转换。
原子哥是不是又要出黑科技了呀。^_^...
回复

使用道具 举报

30

主题

705

帖子

1

精华

新手上路

积分
21
金钱
21
注册时间
2013-3-14
在线时间
52 小时
发表于 2015-3-16 16:10:28 | 显示全部楼层
都是这样用的呀。
这个是拆开:
testRegister[0]=my_NUM&0x0000ffff;
testRegister[1]=my_NUM>>16;
这个是合并:
my_NUM=testRegister[0]+testRegister[1]<<16;
我这个是操作u32的拆开成两个u16的。
原子哥是不是又要出黑科技了呀。^_^...
回复

使用道具 举报

18

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
377
金钱
377
注册时间
2013-3-1
在线时间
50 小时
发表于 2015-3-16 17:04:01 | 显示全部楼层
具体就是 高八位左移8位然后或上低八位 组成一个16位的
回复

使用道具 举报

12

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
246
金钱
246
注册时间
2015-1-28
在线时间
50 小时
 楼主| 发表于 2015-3-16 17:08:16 | 显示全部楼层
回复【2楼】fanghuiopenedv:
---------------------------------
谢谢楼上
我产生题中疑问主要是之前看过这句:
dat <<= 1;
此句是用来移出dat首位的
如:dat中数据为10110001,移位后为01100010 另一例:BUF[0]<<8中数据为10110001,移位后却为10110001 00000000
由上,为什么此句中dat首尾被清除,而BUF[0]<<8中的数据却移入到下一字节? 

相关代码如下:

/**************************************
从IIC总线接收一个字节数据
**************************************/
BYTE HMC5883_RecvByte()
{
    BYTE i;
    BYTE dat = 0;

    SDA = 1;                    //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;             //!!!!!!!注意这行!!!!!!!
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        dat |= SDA;             //读数据               
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    return dat;
}
回复

使用道具 举报

12

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
246
金钱
246
注册时间
2015-1-28
在线时间
50 小时
 楼主| 发表于 2015-3-16 17:08:52 | 显示全部楼层
回复【3楼】huarana:
---------------------------------
谢谢回答,详细问题在二楼
回复

使用道具 举报

12

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
246
金钱
246
注册时间
2015-1-28
在线时间
50 小时
 楼主| 发表于 2015-3-16 18:12:29 | 显示全部楼层
回复【6楼】fanghuiopenedv:
---------------------------------
谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-25 05:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表