找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5796|回复: 12
收起左侧

各位大佬iic总线SDA=dat>>7; dat=dat<<1是怎么移为啊

[复制链接]
ID:696335 发表于 2020-2-21 22:42 | 显示全部楼层 |阅读模式
unsigned char I2cSendByte(unsigned char dat)
{
unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。  
for(a=0;a<8;a++)//要发送8位,从最高位开始
{
  SDA=dat>>7;  //起始信号之后SCL=0,所以可以直接改变SDA信号
  dat=dat<<1;
  Delay10us();
  SCL=1;
  Delay10us();//建立时间>4.7us
  SCL=0;
  Delay10us();//时间大于4us  
}
SDA=1;
Delay10us();
SCL=1;
while(SDA)//等待应答,也就是等待从设备把SDA拉低
{
  b++;
  if(b>200)  //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
  {
   SCL=0;
   Delay10us();
   return 0;
  }
}
SCL=0;
Delay10us();
  return 1;  
}

回复

使用道具 举报

ID:462827 发表于 2020-2-22 15:51 | 显示全部楼层
SDA是只能有一个位的信息,如果你让SDA=dat的话(dat是字节),那么dat里任何一位是1的话SDA就会是1,dat里全部位都是0,SDA就是0。

那么SDA要逐一地取dat的每一个位怎么办呢,你所贴的代码是从最高位开始取,dat>>7就是dat这么一个字节总共8个位的数据向右移7个位,原来的最高位就移到了最右的位置,左边7个位全被抹成0,SDA=dat>>7实际也就是取得了原先最高位的值了。

然后再接着dat=dat<<1,也就是让dat左移一位且赋值回来,把原来最高位的顶掉没有了,原来它的下一个位就被顶到最高位,再重复前面的步骤,重复8次,SDA就会把dat的8个位都给发送完毕。

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:235200 发表于 2020-2-22 01:12 | 显示全部楼层
假设一个数是0xa3,即
D7   D6   D5   D4   D3  D2  D1  D0
1      0     1      0     0    0    1    1
第1步:先把D7位1送至SDA
第2步:把这个数的D7位去掉,同时D6-D0位替换原来的D7-D1,D0位用0代替
第3步:转到第1步并判断是否转了8次,若是转第4步
第4步:……
回复

使用道具 举报

ID:696335 发表于 2020-2-22 12:06 | 显示全部楼层
csmyldl 发表于 2020-2-22 01:12
假设一个数是0xa3,即
D7   D6   D5   D4   D3  D2  D1  D0
1      0     1      0     0    0    1    1
...

SDA=dat>>7是向右移7位,怎么能直接送到SDA呢?
回复

使用道具 举报

ID:696335 发表于 2020-2-22 12:08 | 显示全部楼层
csmyldl 发表于 2020-2-22 01:12
假设一个数是0xa3,即
D7   D6   D5   D4   D3  D2  D1  D0
1      0     1      0     0    0    1    1
...

dat>>7是向右移7位,怎么能把d7送到SDA?
回复

使用道具 举报

ID:696335 发表于 2020-2-22 12:11 | 显示全部楼层
dat向右移7位,怎么能直接送到SDA?
回复

使用道具 举报

ID:679425 发表于 2020-2-22 13:14 | 显示全部楼层
1楼正解
回复

使用道具 举报

ID:235200 发表于 2020-2-22 14:35 | 显示全部楼层
臭大死王八羔子 发表于 2020-2-22 12:08
dat>>7是向右移7位,怎么能把d7送到SDA?

dat=0xa3;
D7   D6   D5   D4   D3  D2  D1  D0
1      0     1      0     0    0    1    1
SDA=dat>>7;是不是就是SDA=1了呢
即D7位的1信号放到了SDA线上,也就是高电平
回复

使用道具 举报

ID:642838 发表于 2020-2-22 14:49 | 显示全部楼层
臭大死王八羔子 发表于 2020-2-22 12:08
dat>>7是向右移7位,怎么能把d7送到SDA?

右移7位,不就是只剩最高位D7,然后依次左移右移,把剩下的7位依次发送出去
回复

使用道具 举报

ID:291294 发表于 2020-2-22 15:47 | 显示全部楼层
SCL=1;
SCL=0;
回复

使用道具 举报

ID:291294 发表于 2020-2-22 15:49 | 显示全部楼层
SCL=1;
  Delay10us();//建立时间>4.7us
  SCL=0;
回复

使用道具 举报

ID:94642 发表于 2020-6-12 18:00 | 显示全部楼层
一楼正解,谢谢大佬们,我也理解了,我还见过这样的程序,更符合一楼的解释:

unsigned char I2cSendByte(unsigned char dat)
{
        unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。               
        for(a=0;a<8;a++)//要发送8位,从最高位开始
        {
                SDA=dat>>7;         //起始信号之后SCL=0,所以可以直接改变SDA信号
                dat=dat<<1;
                Delay10us();
                SCL=1;
                Delay10us();//建立时间>4.7us
                SCL=0;
                Delay10us();//时间大于4us               
        }
        SDA=1;
        Delay10us();
        SCL=1;
        while(SDA)//等待应答,也就是等待从设备把SDA拉低
        {
                b++;
                if(b>200)         //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
                {
                        SCL=0;
                        Delay10us();
                        return 0;
                }
        }
        SCL=0;
        Delay10us();
        return 1;               
}

回复

使用道具 举报

ID:94642 发表于 2020-6-13 09:28 | 显示全部楼层
大佬们,为什么经过8次循环后,SDA的值变成了0,这相当于在第九个脉冲的时候把SDA直接拉低了,我用LED灯试了下,SDA的值一直是0,这样虽然保证了返回值是1,应答出现,而但是为什么会是这样的,没有明白这个for循环之后的逻辑,循环之后不是把SDA赋值为1吗?为什么会是0的,
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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