IIC详解

本文介绍了IIC总线的基本概念,包括其工作原理、通信过程、典型信号以及与AT24C02EEPROM的交互,详细阐述了数据的写入和读取时序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、IIC简介

IIC是一种串行、半双工总线,主要用于近距离、低速的芯片之间的通信。有两根信号线,一根为SCL(时钟线),一根为SDA(数据线) 。 IIC是一种多主机总线,连接在IIC总线上的器件分为主机和从机,主机有权发起和结束一次通信,而从机只能被呼叫;当总线上有多个主机同时启用总线时,IIC也具备冲突检测和仲裁的功能来防止错误产生;每个连接到IIC总线上的器件都有唯一的地址(7bit),并且每个器件都可以作为主机和从机;IIC总线在通信时总线上发送数据的为发送器,接受数据的为接受器。

二、IIC总线通信过程

1、主机发出起始信号占用总线 2、主机发送一个字节的数据指明从机地址和后续字节的传送方向 3、被寻址的从机发送应答信号回应主机 4、发送器发送一个字节的数据 5、接受器发送应答信号 重复步骤4、5 最后由发送器发送停止信号释放总线。 在步骤2时,发送的一个字节数据,高7位为器件ID,最后一位为数据的发送方向。0为主机发送到从机,1为从机发送到主机。此步骤发送的数据所有器件都可以收到,并和自己ID进行比对。

三、IIC典型信号

1、起始信号SCL为高电平,SDA由高变低表示起始信号。 在这里插入图片描述 代码如下:

void IIC_Start(){
    SDA = 1;//先拉高SDA
    delay_ms(5);
    SCL = 1;//再拉高SCL
    SDA = 0;
    delay(5);
    SCL = 0;//钳住总线,准备发送或接收数据
}

2、结束信号,SCL为高电平时,SDA由低变高表示停止信号。 在这里插入图片描述

void IIC_Stop(){
    SCL = 0;
    SDA = 0;
    delay_us(5);
    SCL = 1;
    delay_us(5);
    SDA = 1;
    delay_us(5);
    
}

3、字节传送 数据的有效性 在传输数据的过程中,当SCL为高电平时,数据线SDA必须保持稳定状态,此时接受器接受一位的数据,当SCL为低电平时,SDA允许跳动,此时发送器可以发送一位的数据。 在这里插入图片描述 IIC通信时每个字节为8为长度,数据传送时,先传送高位,后传送低位,发送器发送完一个字节后,接收器必须发送一位的响应信号。也就是每一帧数据为9位。 如果是发送数据:8位数据位+ 1位ACK 如果是发送地址:7位地址位 + 1位方向 + 1位ACK

//IIC发送一个字节数据
//返回从机有无应答
//1、有应答
//0、无应答
​
void IIC_Send_Byte(uint8_t txd){
    uint8_t t;
    SDA_OUT();
    IIC_SCL = 0;//拉低时钟线开始传输
    for( t = 0; t < 8; t++){
        if((txd & 0x80) == 1)
            IIC_SDA = 1;
        else
            IIC_SDA = 0;
        txd <<= 1;//向左移一位
        delay_us(2);
        IIC_SCL = 1;
        delay_us(2);
        IIC_SCL = 0;
        delay_us(2);        
    }
}
//IIC读取一个字节数据
​
uint8_t IIC_Read_byte(unsigned char ack){
    unsigned char i, receive = 0;
    SDA_IN();
    for(i = 0; i < 8; i++){
        IIC_SCL = 0;
        delay_us(2);
        IIC_SCL = 1;
        receive <<= 1;
        if(READ_SDA) receive++;
        delay_us(1);
    }
    if(ack)
        IIC_Ack();
    else
        IIC_NACK();
    return receive;
}

4、应答信号和非应答信号 在这里插入图片描述

在这里插入图片描述

//产生应答信号
void IIC_ACK(){
    IIC_SCL = 0;//先拉低SCL,使SDA数据可以改变
    IIC_SDA = 0;
    delay_us(2);
    IIC_SCL = 1;
    delay_us(5);
    IIC_SCL = 0;
    
}
//不产生应答信号
void IIC_NACK(){
    IIC_SCL = 0;
    IIC_SDA = 1;
    delay_us(2);
    IIC_SCL = 1;
    delay_us(5);
    IIC_SCL = 0;
}
//等待应答信号
//1:接收应答信号失败
//0:接收应答信号成功
uint8_t IIC_Wait_ACK(){
    uint8_t ucErrorTime = 0;
    IIC_SDA = 1;delay_us(1);
    IIC_SCL = 1;delay_us(1);
    while(READ_SDA){
        ucErrorTime++;
        if(ucErrorTime > 250){
            IIC_Stop();
            return 1;
        }
    }
    IIC_SCL = 0;//占住总线
    return 0;
}

四、典型IIC时序

1、主机向从机发送数据 在这里插入图片描述 START:起始信号 DEVICE ADDRESSS:7位设备地址 R/W:读写信号 ACK:应答信号 WORD ADDRESS:从机中的寄存器地址 ACK:响应信号 DATA:数据 STOP:停止信号 2、主机向从机读取数据 在这里插入图片描述

五、下面以AT24C02为例

AT24C02是一个2Kbit的串行EEPROM,内部含有256个8位的字节。 在这里插入图片描述 A0,A1,A2:地址引脚 WP:写保护引脚,接高电平只读,接低电平可读可写 SCL,SDA:IIC信号线 对于不同容量的AT24C02,具有不同的地址,由下图可得 在这里插入图片描述 本例程中AT2C402高四位地址为1010,A0-A2由管脚电平决定,我们将其接地,那么A0-A2为000,最低位表示读写,所以 读AT24C02的时候,地址为10100001B(0xa0) 写AT24C02的时候,地址为10100000B(0xa1) 向AT24C02中写数据 在这里插入图片描述 操作时序为:

1、主机发出起始信号 2、主机发送器件地址,在本例中为0xa0 3、等待应答信号 4、发送数据的存储地址。AT24C02共有256个可寻址空间,地址从0x00-0xff,想把数据存储在哪里,此时就是写的哪个地址 5、等待应答信号 6、发送要写入的数据,每写入一个字节,等待一个应答信号,如果没有应答,说明写入失败。 7、发送停止信号,结束通信

注意:在写数据的时候,每成功写入一个字节,EEPROM的地址就会+1.当到0xff后,在写入一个字节,地址就会变成0x00。 写数据的时候,EEPROM是先写到缓冲区,然后在搬运到掉电非易失区。所以需要一定的时间,AT24C02一般不超过5ms,所以在写入多个字节时,需要延时5ms。

从AT24C02中读取数据 1、读取当前地址的数据

AT24WC01/02/04/08/16 的地址计数器内容为最后操作字节的地址加 1。也就是说 如果上次读/写的操作地址为 N,则立即读的地址从地址 N+1 开始。如果 N=E(这里对 24WC01 E=127;对 24WC02 E=255;对 24WC04 E=511;对 24WC08 E=1023;对 24WC16 E=2047)则计数器将翻转到 0 且继续输出数据。AT24WC01/02/04/08/16 接收到从器件地址信号后(R/W 位置 1),它首先发送一个应答信号,然后发送一个 8 位字节数据。主器件不需发送一个应答信号,但要产生一个停止信号。

在这里插入图片描述按照时序就可以完成 2、读随机地址的数据 在这里插入图片描述

1、主机首先发出一个起始信号 2、主机发送写操作地址,本例中为0xa0(这里写操作是为了将要读的数据的地址先写进去,告诉EEPROM要读哪个地址的数据),等待一个ACK信号 3、发送内存的地址,说明要读哪个地址的信息 4、重新开始发送起始信号 5、主机发送读操作地址,本例为0xa1 6、EEPROM会自动向主机发送数据, 7、主机回复一个NACK信号,发送结束信号,结束通信。

3、连续读数据 在这里插入图片描述 当主机接收到一个字节的数据后,还想继续接受数据,就可以发送一个ACK信号,从机就会继续发送数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值