STM32-IIC通信(基于AT24C02的软件IIC通信)

IIC是什么?

IIC是一种通信是一种由 PHILIPS 公司开发的两线式串行总线。IIC是用来传输数据的,也是一种通信协议。

IIC的特点:
IIC总线简单而有效,占用的PCB(印制电路板)空间很小,芯片引脚数量少,设计成本低。IIC总线支持多主控(Multi-Mastering)模式,任何能够进行发送和接收的设备都可以成为主设备。主控能够控制数据的传输和时钟频率,在任意时刻只能有一个主控。高速 IIC 总线一般可达 400kbps 以上。

IIC的通信时序:
STM32-IIC通信(基于AT24C02的软件IIC通信)_第1张图片

I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。

  • 开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
  • 结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
  • 数据传输 :SDA的数据在SCL高电平期间被写入从机。SDA的数据变化发生在SCL低电平期间。
    注:IIC通信的数据采集发生在SCL时钟信号高电平的时候。
  • 应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。CPU
    向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU
    接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。

这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。
STM32-IIC通信(基于AT24C02的软件IIC通信)_第2张图片

硬件IIC与软件IIC:

硬件IIC:
硬件IIC也就是说它的通信时序由硬件完成,不需要软件干预。也就是说什么起始信号、结束信号、应答信号我们不用管,它们都是由硬件完成的。
硬件IIC的优缺点:
优点:通信速度快、效率高。
缺点:只能是拥有IIC功能的IO口可以用,移植起来很麻烦。

软件IIC:
软件IIC是指用软件去控制单片机IO口的电平的高低转换以及高低电平的时间去模拟出一个IIC通信的时序。也就说IIC的起始信号、结束信号、应答/非应答信号都是用软件编程写出来的。
软件IIC的优点:可移植性高;是个单片机都能用,任何普通的IO口都可以进行软件IIC通信(像51单片机这一类,就必须用软件IIC了)。
缺点:通信效率慢了点,但是几us完全可以忽略不计。

前面我们就有说IIC的起始信号是必需的,结束信号和应答信号,都可以不要,在这里就看看IIC起始信号的代码。
这里是AT24Cxx芯片IIC通信的时序要求:
STM32-IIC通信(基于AT24C02的软件IIC通信)_第3张图片

//产生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通信。

STM32-IIC通信(基于AT24C02的软件IIC通信)_第4张图片

引脚功能:

  • A0-A2:地址输入**(注意:仅在AT24C01/02中适用)**
  • SDA:串行数据
  • SCL:串行时钟输入
  • WP:写保护

题外:NC代表引脚可悬空(NC代表无用引脚,在设计时不用连接)在使用大于2K的AT24C系列芯片时, A0-A2会有几个引脚为无用,具体可看芯片手册。

硬件电路设计:
STM32-IIC通信(基于AT24C02的软件IIC通信)_第5张图片

为什么这样设计,引脚为什么这样连?这就要问问芯片手册了。
STM32-IIC通信(基于AT24C02的软件IIC通信)_第6张图片
翻译如下:(加入了个人理解,可能会有错误)
引脚描述:
串行时钟(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位)。

  • 如果这个位高,则启动读操作;
  • 如果这个位低,则启动写操作。

STM32-IIC通信(基于AT24C02的软件IIC通信)_第7张图片

按照我们原理图的接法,我们可以知道:

  • 1、WP接低电平,允许读/写操作

2、A2, A1和A0引脚都是接地,芯片高四位统一为1010(十六进制为A)所以器件地址就是:1010 000X

  • 读地址操作:0XA1
  • 写地址操作:0XA0

写操作方法:1、字节写 2、页写

STM32-IIC通信(基于AT24C02的软件IIC通信)_第8张图片

字节写:
字节写操作首先发送设备地址字和写确认(也就是0XA0));在收到这个地址,EEPROM将响应一个“0”。
然后发送8位数据储存地址(在容量大于2K的芯片是word adress,也就是字地址,一个字为两个字节,所以一次是写两个字节地址,分别为要写入地址的高8位和低八位共16位地址);在收到两个8位数据字地址之后,EEPROM将再输出一个“0”响应。最后发送数据,发送结束后产生一个0的应答。
寻址设备,如微控制器,在收到这些操作后必须以停止条件终止写序列。此时EEPROM进入到非易失性存储器的内部定时写周期twp。在这个写周期中,所有输入都被禁用,直到写完成,EEPROM才会响应(参见第10页的图8)。

STM32-IIC通信(基于AT24C02的软件IIC通信)_第9张图片

//在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);	 
}

所以多出来的那几个语句只是为了兼容后面容量大的芯片。

STM32-IIC通信(基于AT24C02的软件IIC通信)_第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,数据字地址将“滚动”,之前的数据将被覆盖
STM32-IIC通信(基于AT24C02的软件IIC通信)_第11张图片

读的时序:有3种:1、当前地址读 2、随机读3、顺序读

下面贴出随机读的时序:
STM32-IIC通信(基于AT24C02的软件IIC通信)_第12张图片

//在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,stm32,IIC,嵌入式,单片机)