C51 IIC 和SPI总线,IIC+AT24C02+C51代码实现

一、DS18B201

  • 封装
    这里写图片描述
  • SPI时序图,每次传送产生8个时钟。传送速度可达1.05Mbit/s.高位在前MSB,低位在后LSB。
    这里写图片描述

  • II2总线
    这里写图片描述

    • SCL 为时钟,所有器件时钟连接到上面
    • SDA为数据线,所有器件的数据线连到上面。
    • SDA和SCL都是双向。
    • 上拉电阻,将总线空闲时上拉为高电平,一单器件有输出低电平,总线立刻变为低电平。
    • 电容容量决定连接的器件的数目,每个器件都有唯一地址。

  • IIC数据传输

    • 当SCL为高电平时,SDA的状态不可变化;SCL为低电平时,SDA的状态可以变化。

    这里写图片描述

    • 起始和终止信号

      • 由器件发出
      • SCL为高,SDA由高变低,产生起始信号
      • SCL为高,SDA由低变高,产生终止信号
      • 只有在起始信号发生后,命令才生效

    这里写图片描述

    • 主器件-》从器件,数据传送的应答,主器件对从器件进行寻找–>发送1字节数据(8位,最高位为MSB)–>接收器件发出应答信号A(在第 9 个时钟产生,发送发的SDA必须为高电平,以便接收低电平信号A)。当从器件忙碌时,要把SDA置为高,主器件产生一个终止信号。

    • 非应答信号为从器件给主器件发送,释放总线。
      这里写图片描述

    • 寻址字节

    • 高四位DA3-DA0为机器地址,出产决定

    • A2-A0为引脚地址
    • R/W为读写,R/=1.表示主器件接收从器件数据(读),0表示主器件发送数据(写)。

    • 多字节读写

    • 写(0),先发送起始信号,发送寻址字节。多次发送1字节数据和应答信号A。最后发送终止信号。
      这里写图片描述

    • 读(1)和写差别,R/W为1,无需应答信号
      这里写图片描述

    • 主器件写读操作,读取一字节数据,先写入地址,后读取数据。
      这里写图片描述

  • IIC总线EEPROM读写代码实现

    • AT24C02总时序图
      这里写图片描述
    • 代码模块
      • 起始信号:I2cStart() 。时序图请参考上面的图片。
      • 终止信号:I2cStop()。
      • 单片机向IIC发送数据:unsigned char I2cSendByte(unsigned char dat)。
      • 单片机向IIC读取数据:unsigned char I2cReadByte().
      • 向AT2402写入数据:void At24c02Write(unsigned char addr,unsigned char dat)。
      • 向AT2402读取数据:unsigned char At24c02Read(unsigned char addr)。
    • 起始信号,时序图在上面,SCL=1,SDA产生下降沿。

      void I2cStart()
      {
          SDA=1;
          Delay10us();
          SCL=1;
          Delay10us();//建立时间大于0.6us(5v)
          SDA=0;
          Delay10us();//保持时间大于0.6Us(5v)
          SCL=0;     //恢复0        
          Delay10us();        
      }
    • 终止信号。SCL = 1.SDA产生上升沿。

      void I2cStop()
      {
          SDA=0;
          Delay10us();
          SCL=1;
          Delay10us();//建立保持时间>0.6us(5V)
          SDA=1;
          Delay10us();        
      }
    • IIC发送数据。从高位写入,SCL先电平高保持一段时间再降低,发送9个这样周期。实现数据传输。第九个周期SDA=1.单片机等待从机应答,拉低SDA,SDA=0。如果没有应答数据传输失败

      unsigned char I2cSendByte(unsigned char dat)
      {
          unsigned char a=0,b=0;//        
          for(a=0;a<8;a++)//传输8位数据,SCL保证为0,在初始化得时候已经设置SCL为0
          {
              SDA=dat>>7;  //高位先,先移动七位,再把第7位移动到最高位
              dat=dat<<1;
              Delay10us();
              SCL=1;
              Delay10us();//建立时间大于4.7us,产生一个脉冲周期
              SCL=0;
              Delay10us();//
          }
          SDA=1; //拉高SDA,等待应答
          Delay10us();
          SCL=1; //数据不可改变
          while(SDA)//
          {
              b++;
              if(b>200)    //大于2000us,应答失败
              {
                  SCL=0;
                  Delay10us();
                  return 0;
              }
          }
          SCL=0;  //SCL恢复
          Delay10us();
          return 1;       
      }
    • IIC读取数据,产生8个脉冲周期

      unsigned char I2cReadByte()
      {
          unsigned char a=0,dat=0;
          SDA=1;          //建立时间大于>4.7us.
          Delay10us();
          for(a=0;a<8;a++)//最高位读取
          {
              SCL=1; //产生脉冲周期,SCL初始化和写入都为0。
              Delay10us();
              dat<<=1;
              dat|=SDA;
              Delay10us();
              SCL=0;
              Delay10us();
          }
          return dat;     
      }
      
    • 向AT24C02写入数据。起始信号->写入器件地址->写入数据地址->写入数据->终止信号

      void At24c02Write(unsigned char addr,unsigned char dat)
      {
          I2cStart();       //起始信号
          I2cSendByte(0xa0);//写入器件地址= 10100000。R/W为0
          I2cSendByte(addr);//写入数据地址
          I2cSendByte(dat);//写入数据
          I2cStop();       //终止信号
      }
    • 向AT24C02读取数据。读取方式:随机读。起始信号->发送机器地址->发送数据地址->起始信号->发送器件地址(R/\overline{W}=1)->读取数据->终止信号。

      unsigned char At24c02Read(unsigned char addr)
      {
          unsigned char num;
          I2cStart();  //起始信号
          I2cSendByte(0xa0); //发送机器地址:10100000
          I2cSendByte(addr); //发送数据地址
          I2cStart();
          I2cSendByte(0xa1); //发送机器地址:10100001
          num=I2cReadByte(); //读取数据
          I2cStop();   //终止信号
          return num; 
      }

猜你喜欢

转载自blog.csdn.net/jmu201521121021/article/details/78925113
IIC
C51