IIC总线学xx结_淋哥电子_百度空间

      最近公司那边给了个任务,帮调下PCF8563时钟芯片,是一款IIC总线的器件,之前也有写过AT24C02这样的ICC,不过已经忘记的差不多了,现今重拾旧知,总结如下:

    I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。
    I2C总线通过上拉电阻(一般取10K)接正电源。当总线空闲时,两根线均为高电平。连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。


起始和终止信号:

SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号

SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号


数据位的有效性规定
    I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化

数据传送格式每一个字节必须保证是8位长度。数据传送时,先传送{zg}位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。


总线的寻址I2C总线协议有明确的规定:采用7位的寻址字节(寻址字节是起始信号后的{dy}个字节)。

D7~D1位组成从机的地址。D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据。

51单片机IO口模拟ICC典型的子程序:

sbit SDA=P1^0;          // 将p1.0口模拟数据口
sbit SCL=P1^1;         // 将p1.1口模拟时钟口

#define delay_NOP(); {_nop_();_nop_();}; //晶振11.0592M,差不多5us

/****************************************
*函数名称:void iic_start(void)
*输入:无
*输出:无
*功能说明:启动I2C总线子程序
*****************************************/
void iic_start(void)    //时钟保持高,数据线从高到低一次跳变,I2C通信开始
{
EA=0;          
SDA = 1;        
SCL = 1;
delay_NOP();      // 延时5us (大于4.5us即可)
SDA = 0;
delay_NOP();
SCL = 0;
}

/****************************************
*函数名称:void iic_stop(void)
*输入:无
*输出:无
*功能说明:停止I2C总线数据传送子程序
*****************************************/
void iic_stop(void)     //时钟保持高,数据线从低到高一次跳变,I2C通信停止
{
SDA = 0;      
SCL = 0;
delay_NOP();
SCL = 1;
delayNOP();
SDA = 1;
delay_NOP();
EA = 1;
}

/******************************************************************************
*函数名称:void WriteACK(uchar ack)
*输入:uchar ack
*输出:无
*功能说明:内部函数:每个字节传输完成,ack=0,有应答;结束读数据,ack=1,无应答;
*******************************************************************************/
void WriteACK(uchar ack)
{
   SDA=ack;
   delay_NOP();
   SCL=1;
   delay_NOP();
   SCL=0;
}
/********************************************
*函数名称:void WaitACK(void)
*输入:无
*输出:无
*功能说明:等待ACK
**********************************************/
void WaitACK(void)
{
   uchar errtime=20;
   SDA=1;
   delay_NOP(); //读ACK
   SCL=1;
   delay_NOP();
   while(SDA)
   {
    errtime--;
      if(!errtime)
   iic_stop();//等待了一段时间后,没有应答,即停止ICC
   }
   SCL=0;   //拉低时钟
delay_NOP();
}

/******************************************************
*函数名称:void writebyte(uchar wdata)
*输入:uchar wdata
*输出:无
*功能说明:内部函数.写入数据字节,一位一位的写,先写MSB
********************************************************/

void writebyte(uchar wdata)
{
   uchar i;
   for(i=0;i<8;i++)
   {
       if(wdata&0x80) //每次都是wdata{zg}位&0x80,为1时:高电平;为0时,低电平
    {
   SDA=1;
    }
       else
    {
       SDA=0;
    }
       wdata<<=1; //wdata左移一位
       SCL=1;    //数据保持
       delay_NOP();
       SCL=0;     //数据可改变
   }
   WaitACK();     //写完一个8位字节数据后等待应答
}
/********************************************
*函数名称:uchar Readbyte(void)
*输入:无
*输出:return(bytedata)
*功能说明:内部函数.读出一个字节数据
**********************************************/
uchar Readbyte(void)
{
   uchar i,bytedata;
   SDA=1; //先释放总线
   for(i=0;i<8;i++)
   {
      SCL=1; //数据保持稳定,可读取.
      bytedata<<=1; //bytedata左移一位,最地位是0
      bytedata|=SDA; //bytedata或上SDA,即bytedata{zd1}位值为SDA
      SCL=0;   //数据可改变
      delay_NOP();
   }
   return(bytedata);   //返回bytedata
}



郑重声明:资讯 【IIC总线学xx结_淋哥电子_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——