51单片机IIC总线

IIC的通讯协议中这里时钟线SCL为什么要置零。

img

 函数:ReadACK()
 参数:无
 返面值:1非应答,                                           0应答
 描述:I2C总线读从机应答信号
 bit ReadACK O
    SCL=0://拉低时钟总线,允许从机控制SDA
    SCL=1://拉高,读SDA
     delay5us O:
     if(SDA)//NOACK
         SCL=0
         return(1);//返回1
    else//ACK
     人
         SCL=0
         return(0);//返回0

在I2C通信协议中,时钟线SCL的置零是为了将总线控制权交给从机,以使从机在该周期内可以修改SDA线的电平。

具体来说,当主机希望读取从机的应答信号时,主机先将时钟线SCL拉低,然后将自己置为接收模式,接着从机将通过SDA线上发送应答信号。在主机将SCL拉低期间,从机可以控制SDA线的电平,通过将SDA线拉低或拉高来发送响应的应答信号。

上述给出的代码片段中,SCL=0表示将时钟线SCL拉低,以准备读取从机的应答信号。接下来的SCL=1表示将时钟线SCL拉高,从而允许读取从机的应答信号。这样,从机就可以根据SDA线的电平来发送应答信号。

在读取完从机的应答信号后,再将SCL线拉低,以便下一次通信操作。

最后,根据从机发送的应答信号的SDA电平,函数会返回应答(0)或非应答(1)的结果。

  • 请看👉 :身价过亿的灵仙子说你IIC没写完也发?
  • 除此之外, 这篇博客: 51单片机I2C通信时序总结中的 建议在写每一个子函数时,按照一定的节奏(习惯),如:以SCL的正跳变开始,负跳变结束,这样可以在保证程序在子函数之间切换时有一个明确的标志,从二百凹征时钟信号的稳定。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

  • 以下回答由chatgpt基于相关博客总结生成:

    在IIC通讯协议中,时钟线SCL用来同步数据传输。在某些情况下,需要将时钟线SCL置零,这是为了进行特定的操作,例如重复起始条件或停止条件。

    1. 重复起始条件(Repeated Start Condition):在IIC通讯过程中,如果需要在一个完整的传输周期内发送多个数据帧,可以使用重复起始条件。重复起始条件是在发送完一个数据帧后,不释放总线,而是直接发送下一个数据帧。在重复起始条件下,SCL线将被置零,并保持为低电平直到发送下一个起始条件。

    下面是一个重复起始条件的示例代码:

    void IIC_Start(void){
        SDA = 1; // 确保数据线SDA处于高电平状态
        delay(); // 延时一段时间
        SCL = 1; // SCL线拉高
        delay(); // 延时一段时间
        SDA = 0; // 发送起始条件:将SDA线拉低,表示起始条件开始
        delay(); // 延时一段时间
        SCL = 0; // 将SCL线拉低
        delay(); // 延时一段时间
    
        // 发送数据帧...
    }
    
    void IIC_RepeatedStart(void){
        SDA = 1; // 确保数据线SDA处于高电平状态
        delay(); // 延时一段时间
        SCL = 1; // SCL线拉高
        delay(); // 延时一段时间
        SDA = 0; // 发送重复起始条件:将SDA线拉低,表示重复起始条件开始
        delay(); // 延时一段时间
        SCL = 0; // 将SCL线拉低
        delay(); // 延时一段时间
    
        // 发送数据帧...
    }
    
    1. 停止条件(Stop Condition):在完成数据传输后,需要发送停止条件。停止条件是在发送完一个数据帧后,释放总线并将SCL和SDA线都拉高。这样表示一次完整的通讯周期已经结束。在发送停止条件时,SCL线将被置零,并保持为低电平直到发送完停止条件。

    下面是一个停止条件的示例代码:

    void IIC_Stop(void){
        SDA = 0; // 确保数据线SDA处于低电平状态
        delay(); // 延时一段时间
        SCL = 1; // SCL线拉高
        delay(); // 延时一段时间
        SDA = 1; // 发送停止条件:将SDA线拉高,表示停止条件开始
        delay(); // 延时一段时间
        // 停止条件结束后,可以进行下一个IIC通讯周期
    
        // 发送数据帧...
    }
    

    这样,通过置零SCL线,可以实现重复起始条件和停止条件的操作。这些操作的目的是在IIC通讯中正确控制数据的传输过程。