跟着原子学I2C

I2C通讯

1、IIC总线介绍

集成电路总线,是一种同步串行半双工通信总线。

总线or协议?!

总线是数据传输通道,协议是数据传输规则。

1、1介绍

a、由时钟线SCL和数据线SDA组成,并且都接上拉电阻,确保总线空闲状态为高电平。

b、总线支持多设备连接,允许多主机存在,每个设备都有一个唯一的地址。

c、连接到总线上的数目受总线的最大电容400pf限制

d、数据传输速率:标准模式100k bit/s 快速模式400k bit/s 高速模式3.4M bit/s。

1、2归纳

三个信号: 起始信号、停止信号、应答信号。

两个注意:数据有效性、数据传输顺序。

一个状态:空闲状态。

起始信号:当SCL为高电平时,SDA从高电平变为低电平。

停止信号:当SCL为高电平时,SDA从低电平变为高电平。

应答信号:上拉电阻影响下SDA默认为高,而从机拉低SDA就是确认收到数据,为ACK,如果没有收到,为NACK。

数据先发送高位,数据以字节(8bit)传输,数据在SCL高电平稳定。

空闲状态:SCL、SDA都是高电平。

1、3跟着正点原子写代码

起始信号

/*SDA、SCL开始都处于高电平,SCL为高电平期间,SDA从高到低跳变*/
void iic_start(void)
{
 IIC_SDA(1);
 IIC_SCL(1);
 IIC_delay();//delay时间看器件
 IIC_SDA(0);
 IIC_delay();
 IIC_SCL(0);//SCL拉低,钳住总线,准备发送/接收数据
 IIC_delay();
}

停止信号

/*SCL为高电平期间,SDA从低电平往高电平跳变*/
void iic_stop(void)
{ 
   IIC_SDA(0);
   IIC_delay();
   IIC_SCL(1);
   IIC_delay();
   IIC_SDA(1);
   IIC_delay();
}

检测应答信号(主机)

//return:  1:fail  0:succeed
uint8_t iic_wait_ack(void) 
{
   IIC_SDA(1);//主机释放SDA线
   IIC_delay();
   IIC_SCL(1);//从机返回ACK
   IIC_delay();
   if(IIC_READ_SDA)//SCL高电平读取SDA状态
   {
      iic_stop();//SDA高电平表示从机NACK
      return 1;
   }
   IIC_SCL(0);
   iic_delay();
   return 0;
}

发送应答信号

void iic_ack(void)
{ 
  IIC_SCL(0);
  IIC_delay();
  IIC_SDA(0);
  IIC_delay();
  IIC_SCL(1);
  IIC_delay();
}

发送非应答信号

void iic_ack(void)
{   
IIC_SCL(0); 
IIC_delay();
IIC_SDA(1);
IIC_delay(); 
IIC_SCL(1); 
IIC_delay();
}
发送1字节数据
void  iic_send_byte(uint8_t  data)
{
  for(uint8_t t=0;t<8;t++)
  {
      IIC_SDA((data&0x80)>>7);
      IIC_delay(); 
      IIC_SCL(1); 
      IIC_delay();
      IIC_SCL(0);
      data<<=1;//左移1位,用于下一次发送   
    }
    IIC_SDA(1);//发送完成,主机释放SDA线
    
}

读取1字节数据

void  iic_read_byte(uint8_t  ack)
{
  uint8_t receive =0;
  for(uint8_t t=0;t<8;t++)
  {
  receive<<1;//高位先输出,先收到的数据位要左移
  IIC_SCL(1);
  IIC_delay();
  if(IIC_READ_SDA)receive++;
  IIC_SCL(0);
  IIC_delay();
  }
  if(!ack)iic_nack();
  else iic_ack();
  return receive;
}

猜你喜欢

转载自blog.csdn.net/weixin_58125062/article/details/130170567
I2C
今日推荐