IIC是什么?
IIC是一种通信是一种由 PHILIPS 公司开发的两线式串行总线。IIC是用来传输数据的,也是一种通信协议。
IIC的特点:
IIC总线简单而有效,占用的PCB(印制电路板)空间很小,芯片引脚数量少,设计成本低。IIC总线支持多主控(Multi-Mastering)模式,任何能够进行发送和接收的设备都可以成为主设备。主控能够控制数据的传输和时钟频率,在任意时刻只能有一个主控。高速 IIC 总线一般可达 400kbps 以上。
IIC的通信时序:
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
数据传输 :SDA的数据在SCL高电平期间被写入从机。SDA的数据变化发生在SCL低电平期间。
注:IIC通信的数据采集发生在SCL时钟信号高电平的时候。
应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。
硬件IIC与软件IIC:
硬件IIC:
硬件IIC也就是说它的通信时序由硬件完成,不需要软件干预。也就是说什么起始信号、结束信号、应答信号我们不用管,它们都是由硬件完成的。
硬件IIC的优缺点:
优点:通信速度快、效率高。
缺点:只能是拥有IIC功能的IO口可以用,移植起来很麻烦。
软件IIC:
软件IIC是指用软件去控制单片机IO口的电平的高低转换以及高低电平的时间去模拟出一个IIC通信的时序。也就说IIC的起始信号、结束信号、应答/非应答信号都是用软件编程写出来的。
软件IIC的优点:可移植性高;是个单片机都能用,任何普通的IO口都可以进行软件IIC通信(像51单片机这一类,就必须用软件IIC了)。
缺点:通信效率慢了点,但是几us完全可以忽略不计。
前面我们就有说IIC的起始信号是必需的,结束信号和应答信号,都可以不要,在这里就看看IIC起始信号的代码。
这里是AT24Cxx芯片IIC通信的时序要求:
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
在这里 IIC_SDA和IIC_SCL用宏定义定义了单片机的引脚,比如:#define IIC_SCL PBout(8) //SCL
这样的代码移植起来非常方便,假如你想把stm32的例程移植到51单片机的时候,只需要把引脚定义改一改,另外再写一个精确的延时函数即可,非常简单方便。所以我极力推荐大家使用软件IIC通信。
下面通过STM32于AT24C02之间的通信,了解一下软件IIC通信。
引脚功能:
A0-A2:地址输入**(注意:仅在AT24C01/02中适用)**
SDA:串行数据
SCL:串行时钟输入
WP:写保护
题外:NC代表引脚可悬空(NC代表无用引脚,在设计时不用连接)在使用大于2K的AT24C系列芯片时, A0-A2会有几个引脚为无用,具体可看芯片手册。
硬件电路设计:
为什么这样设计,引脚为什么这样连?这就要问问芯片手册了。
翻译如下:(加入了个人理解,可能会有错误)
引脚描述:
串行时钟(SCL): SCL输入用于将正边缘时钟数据输入每个EEPROM设备,将负边缘时钟数据输出每个设备。
串行数据(SDA): SDA引脚是双向串行数据传输。这种引脚是开漏驱动的,可以与任意数量的其他开漏或开集电极装置相连。
设备/页面地址(A2, A1, A0): A2, A1和A0引脚是AT24CO1A和AT24C02硬连接的设备地址输入。多达八台1K/2K设备可以在一个总线系统上被寻址(设备寻址在设备寻址部分下被详细讨论)。(A2, A1, A0,3个位代表8个地址,其实就是2^3=8,所以可以AT24C01/2可以接8个设备)
AT24C04使用硬线寻址的A2和A1输入,在一个单一总线系统上可以寻址共四个4K设备,A0引脚是一个无连接。
AT24C08A只使用A2输入为硬线寻址和两个8K设备可以在一个单一总线系统上被寻址,A0和A1引脚没有连接。
AT24C16A不使用设备地址引脚,它限制了单个总线上的设备的数量为一个A0、A1和A2引脚没有连接。
写保护(WP): AT24C01A/02/04/08A/16A有一个写保护pin,提供硬件数据保护。当连接到地(GND)时,写保护pin允许正常的读/写操作。当写保护引脚连接到Vcc时,写保护功能启用。
芯片器件地址:
设备地址的第8位是读/写操作选择位(R/W位)。
如果这个位高,则启动读操作;
如果这个位低,则启动写操作。
按照我们原理图的接法,我们可以知道:
1、WP接低电平,允许读/写操作
2、A2, A1和A0引脚都是接地,芯片高四位统一为1010(十六进制为A)所以器件地址就是:1010 000X
读地址操作:0XA1
写地址操作:0XA0
写操作方法:1、字节写 2、页写
字节写:
字节写操作首先发送设备地址字和写确认(也就是0XA0));在收到这个地址,EEPROM将响应一个“0”。
然后发送8位数据储存地址(在容量大于2K的芯片是word adress,也就是字地址,一个字为两个字节,所以一次是写两个字节地址,分别为要写入地址的高8位和低八位共16位地址);在收到两个8位数据字地址之后,EEPROM将再输出一个“0”响应。最后发送数据,发送结束后产生一个0的应答。
寻址设备,如微控制器,在收到这些操作后必须以停止条件终止写序列。此时EEPROM进入到非易失性存储器的内部定时写周期twp。在这个写周期中,所有输入都被禁用,直到写完成,EEPROM才会响应(参见第10页的图8)。
//在AT24CXX指定地址写入一个数据
//WriteAddr :写入数据的目的地址
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
IIC_Start(); //产生IIC起始信号
//发送外设地址0XA0(末位为0表示写数据) +储存地址高8位
IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(WriteAddr%256); //发送储存地址低8位
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite); //发送字节
IIC_Wait_Ack();
IIC_Stop(); //产生停止信号
delay_ms(10);
}
程序里面把器件地址(对应word adress)分开为两次发(因为IIC每次是写入8位),第一次是(WriteAddr/256)<<1)把地址左移一位。
**注意:**其实在使用AT24C02时,不需要那么麻烦。只需以下操作:
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
IIC_Start(); //产生IIC起始信号
IIC_Send_Byte(0XA0); //发送外设地址0XA0
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(WriteAddr); //发送储存地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite); //发送字节
IIC_Wait_Ack();
IIC_Stop(); //产生停止信号
delay_ms(10);
}
所以多出来的那几个语句只是为了兼容后面容量大的芯片。
页写:(没有例程)
页写:1K/2K EEPROM能够进行8字节的页写,而4K、8K和16K设备能够进行16字节的页写。页写的初始化与字节写的初始化是一样的,但是微控制器不会在第一个数据字被写入后发送一个停止条件。相反,在EEPROM确认接收到第一个数据字后,微控制器可以发送最多服务器(1K/2K)或15个(4K、8K、16K)更多的数据字。EEPROM在收到每个数据字后将以一个“O”响应。微控制器必须使用停止条件终止页写序列(参见第10页上的图9)。数据字地址较低的三位(1K/2K)或四位(4K, 8K, 16K)位在收到每个数据字后内部递增。较高的数据字地址位不递增,保持内存页行位置。当内部生成的单词address到达页面边界时,下面的字节被放置在同一页面的开头。如果超过8个(1K/2K)或16个(4K, 8K, 16K)数据字被传输到EEPROM,数据字地址将“滚动”,之前的数据将被覆盖
读的时序:有3种:1、当前地址读 2、随机读3、顺序读
下面贴出随机读的时序:
//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址
//返回值 :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
u8 temp=0; //用于保存读取到的数据的变量
IIC_Start(); //产生一个起始信号
IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,末位为0代表写数据
IIC_Wait_Ack(); //产生一个应答信号
IIC_Send_Byte(ReadAddr%256); //发送低地址
IIC_Wait_Ack();
IIC_Start(); //再次产生一个起始信号
IIC_Send_Byte(0XA1); //发送器件地址,末位为1代表读数据进入接收模式
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
return temp;
}
关于ReadAddr%256和ReadAddr/256也是为了兼容容量大的AT24C系列芯片,具体在前面写操作时有写,这里就不再赘述了。
上一篇:STM32第九章-IIC通讯应用
下一篇:STM32的I2C通讯配置(硬件实现)——学习笔记(6-2)
推荐阅读最新更新时间:2024-10-20 14:19
设计资源 培训 开发板 精华推荐
- LM27402S-20A大电流降压模块
- LT8609SEV 12V 降压稳压器的典型应用电路
- L7815A 的典型应用通过降压电阻降低功耗
- RT7258 8A、24V、600kHz 降压转换器的典型应用,具有用于 SOP-8(裸露焊盘)封装的同步栅极驱动器
- 基于GD32F350针对于智能跑鞋的蓝牙基站
- L7806C 分体式稳压器的典型应用 (± 15 V - 1 A)
- 使用具有 PowerPath 和 2A 输入限制的 LTC4162EUFD-L40 9V 至 35V、2 节、3.2A 充电器的典型应用
- LTC2908CDDB-A1、12V、5V、3.3V、2.5V、1.8V、1.5V六电源监视器的典型应用电路
- EVAL-ADM1170EBZ,评估板允许轻松评估 ADM1170
- SIPI-ERM8-ZIPCBL: Zipwire线缆组件