打印
[STM32]

STM32软件模拟I2C程序中有问题?

[复制链接]
2897|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huster_tjs|  楼主 | 2015-10-25 14:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我在用软件模拟I2C过程中,写入硬件写地址(address)和数据(data)都是正确的,能够得到waitask响应。在waitask响应后master将SCL电平拉低,SDA电平自动释放(高电平)。这些都正确。

但是当我写入硬件读地址(address+1)的时候,能得到waitask响应,但是响应后我master拉低SCL电平后,SDA电平还是被拉低,即使通过master软件拉高SDA的IO口都不能将之电平拉高。因此可知,写入硬件读地址(address+1)后,能得到正确的的响应,但是slave就是不释放SDA数据端口。这是怎么回事呢,哪里出了问题?

下面是一些代码:
//单字节读取*****************************************
unsigned char I2C_ReadByte(unsigned char REG_Address)
{   
        unsigned char REG_data;            
        if(!I2C_Start())return FALSE;
        I2C_SendByte(SlaveAddress);
    if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
    I2C_SendByte((u8) REG_Address);   //设置低起始地址      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);              //就是这里发送读地址
    I2C_WaitAck();                                  //这个waitack里面出问题,最后的scl拉低,slave不释放SDA电平
   REG_data= I2C_ReceiveByte();
    I2C_NoAck();
    I2C_Stop();
    //return TRUE;
        return REG_data;

}               

//这里就是waitack()
bool I2C_WaitAck(void)          //返回为:=1有ACK,=0无ACK
{
        SCL_L;
        I2C_delay();
        SDA_H;                       
        I2C_delay();
        SCL_H;
        I2C_delay();
        if(SDA_read)
        {
      SCL_L;
          I2C_delay();
      return FALSE;
        }
        SCL_L;                            //这里拉低SCL电平,但是slave不释放sda(一直是低电平)
        I2C_delay();
        return TRUE;
}

unsigned char I2C_ReceiveByte(void)  //数据从高位到低位//
{
    u8 i=8;
    u8 ReceiveByte=0;
    SDA_H;                        //slave一直拉低sda,在这master写入SDA高电平都不能将SDA电平拉高
    I2C_delay();                               
    while(i--)
    {
      ReceiveByte<<=1;      
      SCL_L;
      I2C_delay();
          SCL_H;
      I2C_delay();       
      if(SDA_read)
      {
        ReceiveByte|=0x01;
      }
    }
    SCL_L;
    return ReceiveByte;
}


求帮助,这是哪问题呢

相关帖子

沙发
huster_tjs|  楼主 | 2015-10-25 15:56 | 只看该作者
这么有趣的问题为什么没人回答呢:'(

使用特权

评论回复
板凳
NE5532| | 2015-10-25 16:45 | 只看该作者
你的意思是你写了addr+R/W以后,在紧随其后的应答位上,从机拉低了SDA线,发出了ACK信号是么?如果是这样描述的,那么从器件就是应该发ACK,因为这帧数据是Master给Slave的,该Slave应答,详见I2C协议,如果不是这样描述的,请楼主继续描述问题。

使用特权

评论回复
地板
huster_tjs|  楼主 | 2015-10-25 16:56 | 只看该作者
NE5532 发表于 2015-10-25 16:45
你的意思是你写了addr+R/W以后,在紧随其后的应答位上,从机拉低了SDA线,发出了ACK信号是么?如果是这样描 ...

是响应了ack信号。是在scl从低电平到高电平的时候,从机将sda线拉低了,这里没问题。但是在从机拉低了sda电平后,我将scl再拉低,从机不释放sda线(还是低电平)。而且此时通过主机将设置sda高电平,sda电平还是低电平。

使用特权

评论回复
5
NE5532| | 2015-10-25 17:00 | 只看该作者
这个时候应该是从机送出主机所要求读取数据的第一个bit,你怎么保证从机此时不是刚好要输出0呢??他怎么就必须该“释放”啊?

使用特权

评论回复
6
huster_tjs|  楼主 | 2015-10-25 17:12 | 只看该作者
NE5532 发表于 2015-10-25 16:45
你的意思是你写了addr+R/W以后,在紧随其后的应答位上,从机拉低了SDA线,发出了ACK信号是么?如果是这样描 ...

也就是说,在从写入addr+R后,从机将sda线拉低响应了,但是将scl设置为低电平时,从机不释放sda线(还是低电平)。。。。

而前面写入addr+w后,没出现这种问题。在从机响应拉低了sda后,我将scl设置低电平时,sda将被释放(处于高电平)。。。。

也请您看看我的I2C_ReadByte(), I2C_WaitAck(),I2C_ReceiveByte(),这三个程序,看有没有时序错误的问题。就我目前对照别人的i2c来看,基本没有什么不同,没找出问题点。在此先谢过

使用特权

评论回复
7
huster_tjs|  楼主 | 2015-10-25 17:23 | 只看该作者
本帖最后由 huster_tjs 于 2015-10-25 17:27 编辑
NE5532 发表于 2015-10-25 17:00
这个时候应该是从机送出主机所要求读取数据的第一个bit,你怎么保证从机此时不是刚好要输出0呢??他怎么就 ...

我读取的是mpu6050的数据,不应该8个位都是0,所以我担心这里出现了错误。

那我们来讨论一下时序问题(请教),照这么来说的话,当发送完addr+r后,slave响应将sda电平拉低。此时master将scl电平拉低时,slave就准备好输出数据的第一位了(将sda电平拉低或为高电平)

但是我觉得应该是 ,当发送完addr+r后,slave响应将sda电平拉低。然后将scl拉低,slave释放sda,然后当scl再次拉高时,slave检测到master电平的变化。slave准备第一位数据,然后master可以读取sda,也就是说,slave只有在检测到scl电平由低到高变化时才准备一个数据。
不知道您怎么看?

使用特权

评论回复
8
NE5532| | 2015-10-25 20:21 | 只看该作者
你对I2C协议理解错了,sda只能在scl低电平期间送出数据,在scl高电平期间被采样,两个特例是启动位和停止位。你怀疑读得有问题,就多读几个数据,用不会都是0嘛。

使用特权

评论回复
9
欧阳2013| | 2015-10-26 10:10 | 只看该作者
iic需要共地:)

使用特权

评论回复
10
阿南| | 2015-10-26 10:31 | 只看该作者
NE5532同志好样的

使用特权

评论回复
评论
NE5532 2015-10-26 19:11 回复TA
过奖,过奖 
11
huster_tjs|  楼主 | 2015-10-26 11:15 | 只看该作者
NE5532 发表于 2015-10-25 20:21
你对I2C协议理解错了,sda只能在scl低电平期间送出数据,在scl高电平期间被采样,两个特例是启动位和停止位 ...

好的,谢谢你,我再换块芯片试试。

使用特权

评论回复
12
huster_tjs|  楼主 | 2015-10-26 11:31 | 只看该作者

好的,我认真再检查一下

使用特权

评论回复
13
wxl319| | 2016-11-2 19:22 | 只看该作者
huster_tjs 发表于 2015-10-26 11:15
好的,谢谢你,我再换块芯片试试。

换了芯片也是这样的,我也是同样的问题,求问,你是怎么解决的啊?求指教啊!这个问题困了好久了!

使用特权

评论回复
14
wxl319| | 2016-11-2 19:24 | 只看该作者
不知楼主有没有发现,换了IO口就没问题了,但是问题在哪呢?我还没找到!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

31

帖子

0

粉丝