找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 21494|回复: 22
收起左侧

dat = (dat>>1) | (dat1<<7);是什么意思,什么功能?

  [复制链接]
ID:161933 发表于 2017-1-15 22:13 | 显示全部楼层 |阅读模式
在下面程序中,
uchar Ds1302Read(uchar addr)
{
        uchar n,dat,dat1;
        RST = 0;
        _nop_();

        SCLK = 0;//先将SCLK置低电平。
        _nop_();
        RST = 1;//然后将RST(CE)置高电平。
        _nop_();

        for(n=0; n<8; n++)//开始传送八位地址命令
        {
                DSIO = addr & 0x01;//数据从低位开始传送
                addr >>= 1;
                SCLK = 1;//数据在上升沿时,DS1302读取数据
                _nop_();
                SCLK = 0;//DS1302下降沿时,放置数据
                _nop_();
        }
        _nop_();
        for(n=0; n<8; n++)//读取8位数据
        {
                dat1 = DSIO;//从最低位开始接收
                dat = (dat>>1) | (dat1<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;//DS1302下降沿时,放置数据
                _nop_();
        }

        RST = 0;
        _nop_();        //以下为DS1302复位的稳定时间,必须的。
        SCLK = 1;
        _nop_();
        DSIO = 0;
        _nop_();
        DSIO = 1;
        _nop_();
        return dat;        
}

问题1:        dat = (dat>>1) | (dat1<<7);是什么意思,什么功能?


问题2:dat1 = DSIO;//从最低位开始接收,数据明明是给了dat1,但是最后return 的数据 却是  dat ??为什么???

回复

使用道具 举报

ID:161939 发表于 2017-1-15 23:33 来自手机 | 显示全部楼层
本帖最后由 zyldlzh 于 2017-1-15 23:34 编辑

只能告诉你,dat=(dat>>1)|(dat1<<7)
dat=(dat按位右移1位)相或同假为假一真即真|(dat1按位左移7位)
貌似是!!!还会补零
回复

使用道具 举报

ID:149988 发表于 2017-1-16 06:28 | 显示全部楼层

RE: dat = (dat>>1) | (dat1<<7);是什么意思

zyldlzh 发表于 2017-1-15 23:33
只能告诉你,dat=(dat>>1)|(dat1

假如dat=00001010B,dat1=00000001B,其中B是二进制的意思,dat>>1意思是右移一位,dat=00001010B右移一位=00000101B。dat1<<7意思是左移七位,dat1=00000001B左移七位=10000000B。(dat>>1) | (dat1<<7)意思是括号中的两个数进行“或”运算。在不能理解的情况下可以把它简单理解为相加,(dat>>1) | (dat1<<7)=(00000101B) | (10000000B)=(00000101B) + (10000000B)= 10000101B=133。可以用十进制运算来验证一下,00000101B=5,10000000B=128,00000101B+10000000B=5+128=133,运算结果是相等的。

评分

参与人数 1黑币 +30 收起 理由
迫使湖南 + 30 很给力!

查看全部评分

回复

使用道具 举报

ID:161869 发表于 2017-1-16 08:45 | 显示全部楼层
我把这个句子拆分下,dat右移1位,左侧空位补0;dat1左移7位,右侧空位补0,将两个结果按位或运算,赋值给dat
回复

使用道具 举报

ID:161869 发表于 2017-1-16 08:49 | 显示全部楼层
你的程序最后一句话写的是return dat;如果想返回dat1,就写return dat1;
回复

使用道具 举报

ID:161641 发表于 2017-1-16 08:53 | 显示全部楼层
       for(n=0; n<8; n++)//读取8位数据
        {
                dat1 = DSIO;//从最低位开始接收
                dat = (dat>>1) | (dat1<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;//DS1302下降沿时,放置数据
                _nop_();
        }
温度是单总线的,一个温度值需要读8次,显然dat1只有最低位有效,通过(dat1<<7)将有效位移至最高位,然后在(dat)的最高位。通过8次移位,正好将8次读到的值赋值到dat。
回复

使用道具 举报

ID:161203 发表于 2017-1-16 09:03 | 显示全部楼层

dat>>1,右移一位,高1位补零,变成0XXXXXXX。
dat1<<7左移七位,低7位补零,变成X0000000,
(dat>>1)|(dat1<<7),逐位或,即相当于取前者后7位,取后者前1位,构成8位。
dat=(dat>>1)|(dat1<<7),新构成的8位给dat‘
最终结果就是:取dat前7位作其后7位,而取dat1后1位代替dat的高1位。

从上可知,dat结果与dat1是有关的。
回复

使用道具 举报

ID:161979 发表于 2017-1-16 10:42 | 显示全部楼层
dat = (dat>>1) | (dat1<<7)  就是dat右移一位, dat1左移7位,当两个条件任何一个为真时,结果为1.
回复

使用道具 举报

ID:161203 发表于 2017-1-16 15:22 | 显示全部楼层
我上午的回复显示需要审核,怎么就不见了呢?
回复

使用道具 举报

ID:303875 发表于 2018-7-21 15:40 | 显示全部楼层
因为DS1302是从低位开始读取的,首先把最低位读取出来,dat = (dat>>1) | (dat1<<7);dat1向左移动7位,放在最高位。而dat是要读取的数据嘛,不断向右移动,8次就读完。不断的或运算就能把最终的dat读出,可以认为dat1就是一个中间变量把。
回复

使用道具 举报

ID:439020 发表于 2018-12-4 10:19 | 显示全部楼层
dat = dat | (dat1<<n);                //这条语句不成功!!!  为啥?????
               
//dat = (dat>>1) | (dat1<<7);   //这条语句没问题
回复

使用道具 举报

ID:439112 发表于 2018-12-4 12:24 | 显示全部楼层
dat = (dat>>1) | (dat1<<7); 把dat1最后一位放在最高位,原dat高7位接着放,构成一个新的dat
回复

使用道具 举报

ID:21069 发表于 2018-12-10 03:37 来自手机 | 显示全部楼层
看这个代码时,你要看看它的电路与你以前有什么不同?以前是8个口传数据,现在一个口!!!以前传的是一个字节,现在是一个位!!!其实这就是将8个位合并成一个字节或是一个字节拆分成8个位的常用手段,只能是位才便于一个端口传输。至于合并与拆分具体上面朋友有讲的很清楚的!
回复

使用道具 举报

ID:472242 发表于 2019-2-6 23:42 | 显示全部楼层
jinsheng7533967 发表于 2018-12-10 03:37
看这个代码时,你要看看它的电路与你以前有什么不同?以前是8个口传数据,现在一个口!!!以前传的是一个 ...

讲的很透彻,学习了

评分

参与人数 1黑币 +35 收起 理由
shuisheng + 35

查看全部评分

回复

使用道具 举报

ID:479528 发表于 2019-2-22 23:55 | 显示全部楼层
  for(n=0; n<8; n++)//读取8位数据
        {
                dat1 = DSIO;//从最低位开始接收
                dat = (dat>>1) | (dat1<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;//DS1302下降沿时,放置数据
                _nop_();
        }

dat = (dat>>1) | (dat1<<7);这个语句是将dat右移一位高位补零,将dat1左移7位低位补零,然后两者按位或运算。实现功能是将DSIO数据依此读取到dat。

比如说要将一个8位数hgfedcba(每一位都是未知的)读到dat,DSIO在8个循环从低位到高位依此发送a b c d e f g h,由于之前的循环中最后一步SCLK=0已经出现下降沿,指定寄存器中的第一位数据a已发送到DSIO,第一个循环
dat1 = DSIO;                      运行结果dat1=0000000a;

dat = (dat>>1) | (dat1<<7);        运行结果dat=aXXXXXXX;
运行过程:      
先dat>>1; dat由未知8位数XXXXXXXX变为dat=0XXXXXXX;即将最高为清空;
dat1<<7; dat1=0000000a变成dat1=a0000000;将DSIO上读取的值移动最高位,清空低位。然后进行或运输dat=0XXXXXXX+ a0000000,dat=aXXXXXXX即将DSIO值读取到dat最高位。

SCLK = 1;
_nop_();                           运行结果 拉高SCLK准备下一个下降沿
SCLK = 0;                          运行结果 产生下降沿,放置下一个b数据到DSIO
_nop_();

依此类推
第二个循环 dat变为dat=baXXXXXX;
第三个循环 dat变为dat=cbaXXXXX;
第四个循环 dat变为dat=dcbaXXXX;
第五个循环 dat变为dat=edcbaXXX;
第六个循环 dat变为dat=fedcbaXX;
第七个循环 dat变为dat=gfedcbaX;
第八个循环 dat变为dat=hgfedcba;
循环完成后,完成将指定寄存器addr中的数据读取到dat。
回复

使用道具 举报

ID:326868 发表于 2019-3-16 22:06 | 显示全部楼层
for(n=0; n<8; n++)//读取8位数据
        {
                dat1 = DSIO;//从最低位开始接收
                dat = (dat>>1) | (dat1<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;//DS1302下降沿时,放置数据
                _nop_();
        }
dat1 = DSIO;//从最低位开始接收
dat1每次循环开始都重新赋值,8次赋值为什么不是一样的?
回复

使用道具 举报

ID:491841 发表于 2019-3-17 15:07 | 显示全部楼层
假如dat=00001010B,dat1=00000001B,其中B是二进制的意思,dat>>1意思是右移一位,dat=00001010B右移一位=00000101B。dat1<<7意思是左移七位,dat1=00000001B左移七位=10000000B。(dat>>1) | (dat1<<7)意思是括号中的两个数进行“或”运算。在不能理解的情况下可以把它简单理解为相加,(dat>>1) | (dat1<<7)=(00000101B) | (10000000B)=(00000101B) + (10000000B)= 10000101B=133。可以用十进制运算来验证一下,00000101B=5,10000000B=128,00000101B+10000000B=5+128=133,运算结果是相等的。
回复

使用道具 举报

ID:466164 发表于 2019-3-17 18:55 | 显示全部楼层
这个语句dat = (dat>>1) | (dat1<<7)要从后面看,
1.dat1<<7把dat1最低地位,放最高位。
2.  |  按位或是为了读数据,数据情况不清楚。
3. dat>>1是为了下次循环,腾位置否则数据被覆盖了,刚好把放高位的低位数据移到低位。
4.8次循环后dat1=dat
这个问题我曾经也想了几天!
回复

使用道具 举报

ID:964308 发表于 2021-10-19 16:18 来自手机 | 显示全部楼层
这些数据储存都是0x两位数,代表16进制,同时他也能进行和2进制一样的运算。>><<是移位的意思,dat向右移1位,dat1向左移7位,补零后同假为假。最简单的说法就是把最新接收的那一位(可能是1可能是0)塞进dat里面,从左边塞
回复

使用道具 举报

ID:945922 发表于 2021-10-27 15:17 | 显示全部楼层
不倒翁.WZT 发表于 2017-1-16 06:28
假如dat=00001010B,dat1=00000001B,其中B是二进制的意思,dat>>1意思是右移一位,dat=00001010B右移一 ...

谢了,懂了!
回复

使用道具 举报

ID:974277 发表于 2021-10-28 11:47 | 显示全部楼层
表示位移,<<向左位移(高位丢弃,低位补0),>>向右位移(低位丢弃,高位补0)
回复

使用道具 举报

ID:975682 发表于 2021-10-28 14:27 | 显示全部楼层
dat右移1位,左侧空位补0;dat1左移7位,右侧空位补0,将两个结果按位或运算,赋值给dat
回复

使用道具 举报

ID:750420 发表于 2021-10-28 16:27 | 显示全部楼层
重组了这个数据
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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