协议—IIC

I2C总线支持任何IC生产过程NMOS CMOS双极性,两线――串行数据 SDA 和串行时钟SCL线在连接到总线的器件间传递信息,每个器件都有一个唯一的地址识别,无论是微控制器、LCD 驱动器、存储器或键盘接口,而且都可以作为一个发送器或接收器。

 

总线空闲状态 :

SDA :高电平

SCL :高电平

硬件电路:

两线要各外接一个约3~10K欧的上拉电阻

 

宏定义必要参数:

#define SDA P1_0              //I2C 数据传送位

#define SCL P1_1              //I2C 时钟传送位

#define  GuestAddr  0x1D //从机地址

 

延时函数:

1、

void iic_delay(){//延时约7us

       for(i=16;i<16;i--);//延时时间us=(3+5*16)/12 值不可大于255

}

2、

#define iic_delay() Delay_1u(8)

void Delay_1u(uint microSecs)

{

  while(microSecs--)

  {

    /* 32 NOPs == 1 usecs*/

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop");

  }

}

起始和终止信号(灰色区域):

 

 

void iic_start()               //函数功能:I2C通信开始

{

    SDA = 1;

    iic_delay();

    SCL = 1;

    iic_delay();

    SDA = 0;

    iic_delay();

}

 

void iic_stop()                //函数功能:I2C通信停止

{

    SDA = 0;

    iic_delay();

    SCL = 1;

    iic_delay();

    SDA = 1;

    iic_delay();

}

应答信号时序:

 

 

void iic_ack()                 //函数功能:I2C通信查应答位

{

SCL = 1;

SCL = 0;

}

写字节代码:

 

void iic_write_byte(uchar wdata)//函数功能:向I2C从机写入一个字节

{

     uchar i,temp,temp1;

 

     temp1 = wdata;

    

     for (i = 0; i < 8; i++)

     {

        SCL = 0;

        iic_delay();

        temp = temp1;

        temp = temp&0x80;

        SDA = (temp == 0x80? 1: 0);

        iic_delay();

        SCL = 1;

        iic_delay();

        SCL = 0;

        iic_delay();

        temp1 <<= 1;

     }

 

}

读字节代码:

uchar iic_read_byte(void)    //函数功能:从I2C从机中读出一个字节

{

     uchar x;

     uchar data;

     for (x = 0; x < 8; x++) {

        data <<= 1;

        SDA = 1;

        iic_delay();

        SCL = 0;

        iic_delay();

        SCL = 1;

        iic_delay();

        P1DIR &= ~0x01

        if(SDA == 1)  data |= 0x01;

        P1DIR |= 0x01

     }

     return data;

}

综合应用:

void iic_write(uchar byte_add,uchar wdata)//函数功能:按地址写入一字节数据

{

     uchar t;

  t = GuestAddr <<1;

/* 第一个字节的头 7 位组成了从机地址,最低位它决定了报文的方向:第一个字节的最低位是 0 表示主机会写信息到被选中的从机 ,1 表示主机会向从机读信息*/

  iic_start();   //起始信号

  iic_write_byte(t);

  iic_ack();

  iic_write_byte(byte_add);//内部寄存器地址

  iic_ack();

  iic_write_byte(wdata);//内部寄存器数据

  iic_ack();

  iic_stop();

}

uchar iic_read(uchar byte_add)            //函数功能:按地址读出一字节数据

{

     uchar t;

     uchar x;

     t = (GuestAddr << 1);

     iic_start();

     iic_write_byte(t);

     iic_ack();

     iic_write_byte(byte_add);

     iic_ack();

     t = (GuestAddr << 1) | 0x01;

/* 第一个字节的头 7 位组成了从机地址,最低位它决定了报文的方向:第一个字节的最低位是 0 表示主机会写信息到被选中的从机 ,1 表示主机会向从机读信息*/

 

     iic_start();

     iic_write_byte(t);

     iic_ack();

     x = iic_read_byte();

     iic_ack();

     iic_stop();

    

     return x;

}

 

************************************************************************************************

延时函数参考:https://m.hqew.com/tech/fangan_1647539

来源于课堂整理

转载于:https://www.cnblogs.com/dongxiaodong/p/9801684.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值