我们使用I2C来操控一个EEPROM(AT24C02)实现数据的读写。
AT24C02的datasheet可直接在网上下载下来,此刻我们只关注一些重要的芯片信息了:
管脚如下:
SDA和SCL为I2C总线,vcc和vss分别为电源和地,wc为写保护,mode为模式选择,E0~E2为设置该设备地址的,它是主设备识别的唯一标识。AT24C02可认为是一个从设备,主设备为我的STM32。
怎么设置AT24C02的地址:
一个8bit的数据:
bit4~bit7:默认为0101
bit1~bit3:是需要我们自己设置的,它对应于E0~E2管脚,假如你的硬件上都接的是地,那么即为000。
bit0:控制读写的。1位读操作,0位写操作。
假如E0~E2在硬件上都接的是地线,那么:操作该AT24C02我们要读的话为:1010 0001即0xA1,要是要写的话为1010 0000 即0xA0。就是这个道理了。
下面再来看看读写一个byte的时序:
先来一个启示信号,然后是写入设备地址,即0xA0,然后给一个应答信号,然后写入我们要写的地址,这个地址大小为256byte,等待应答,然后写入数据,这个数据存放在你前面设置的那个地址里面,然后等待应答,最后发停止信号。
我们看比较简单的一中:即从某个地址去读数据
先发起始信号,然后发送地址,即:0xA1。确定我们要操作的是哪个AT24C02,等待应答信号,接下来我们要确定操作的是AT24C02里面的那个地址空间,然后等待应答,然后在发送一个起始信号,然后发送设备地址,等待应答,然后才是读出数据,等待应答,发送结束信号。
简单的来说:
对于写,由于I2C总线是可以1主多从的,我们就需要确定我们给哪个从机设备写,我们确定了设备,那么我们就需要在确定把我的数据到底写到设备的那个地址空间里面去,即0~255byte,只要当两个都确定了,我们才能才是写数据了。
对于读,同样的道理,先找到你要读的设备到底是哪一个,找到了设备,还不行啊,你需要找到你原来把数据从到那个地方了,那你就要找到数据的存放位置,只是读的时候我们发送了两次起始信号,两次设备地址,然后我们就读数据了。
下面我们再来看看主要源码:
对照和协议和源码我们来看一下:
函数的参数为:你要写入数据的存放地址和你要写入的数据
首先发送一个I2C协议的起始信号,然后确定设备发送写信号,这个写是与设备的内存容量有关系的,我们这里跑的是else里面的内容,即:
IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据
这个写入的为0xA0了。然后等待应答,然后写入内存地址,即我们要把我们的数据放在芯片的内存的哪里?
IIC_Send_Byte(WriteAddr%256); //发送低地址
,等待应答,然后发送数据,然后等待应答,发送停止信号结束。
函数的参数为:读数据的地址,
函数的返回值为:读到的数据
对比协议,代码是完全按照协议走的,肯定是没有问题的。就不多说了。
基于这两个基本函数,在附加一个扩展函数:
该函数用于写入16bit或者32bit的数据.
WriteAddr :开始写入的地址
DataToWrite:数据数组首地址
Len :要写入数据的长度2,4
该函数用于读出16bit或者32bit的数据.
ReadAddr :开始读出的地址
返回值 :数据
Len :要读出数据的长度2,4
这里用了24XX的最后一个地址(255)来存储标志字.
如果用其他24C系列,这个地址要修改
返回1:检测失败
返回0:检测成功
ReadAddr :开始读出的地址 对24c02为0~255
pBuffer :数据数组首地址
NumToRead:要读出数据的个数
WriteAddr :开始写入的地址 对24c02为0~255
pBuffer :数据数组首地址
NumToWrite:要写入数据的个数
主函数就不说了,直接初始化,然后调函数做操作就好了。