IIC驱动AT24C02(EEPROM)读写操作


IIC通信链接
IIC通信

AT24C02(EEPROM)简介

总容量是256(2K/8)个字节。
接口:IIC
在这里插入图片描述
在这里插入图片描述

地址介绍

1、EEPROM由8位表示为存储地址
2、设备号+读写位
其中最低位是读写位,0表示读,1表示写
高7位表示设备地址(IIC通讯使用)
下面图中的设备地址只是占用了4位,A0-A2默认为0。
因此设备地址为1010(二进制)
3、内存地址
根据EEPROM的型号不同,其中设备地址占的位数有所不同,有的存储的地址单元超过8位。
例如AT24C04有512个地址,需要9位表示。24C08有1024个地址,需要10位表示。
为解决这个问题,A0-A2不仅可以表示原有设备号的地址数据,也可以存储内存地址高于8位的数据。

在这里插入图片描述

读时序

在这里插入图片描述

写时序

在这里插入图片描述

重点理解与掌握

1、掌握IIC通信的原理与IO模拟IIC时序的逻辑代码
2、对EEPROM设备地址A0-A2的理解
3、根据时序图写发送字节函数
4、对发送字节函数进行进一步封装,发送固定长度的数据,字符串等

代码

eeprom.c文件

#include<stdio.h>
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "i2c.h"
#include "eeprom.h"

/*

//eeprom--AT24
//u16 a;
//const u8 TEXT_Buffer[]={"2023年8月30日"};
//#define SIZE sizeof(TEXT_Buffer)

		u8 data[SIZE];
//		u8 value;
		
//		AT24_write_byte(0,0x23);			//发送数字
		AT24CXX_Write(10,(u8*)TEXT_Buffer,SIZE);
		
//		value=AT24_read_byte(0);
		AT24CXX_Read(10,data,SIZE);
		
//		printf("%x\n",value);
		printf("%s\n",data);//显示读到的字符串
		printf("\n");
		delay_ms(100);

*/

void AT24_init()
{
	i2c_init();
}
/*
按照AT24(读)时序图的先后顺序,进行顺序执行
*/
u8 AT24_read_byte(u16 readaddr)
{
	u8 value;
	iic_start();
	
	if(EE_TYPE>AT24C16)
	{
		iic_send_byte(0XA0);						//A是EEPROM在I2C的地址(手册)		
		iic_wait_ack();					
		iic_send_byte(readaddr/256);				//readaddr是EEPROM的内存地址(0~255)
		iic_wait_ack();					
	}
	else{
		iic_send_byte(0XA0|(readaddr/256)<<1);					//发送设备号和高于8位的内存地址
	}
	iic_wait_ack();
	iic_send_byte(readaddr%256);								//发送低于8位的内存地址
	iic_wait_ack();
	iic_start();
	
	iic_send_byte(0xA1);
	iic_wait_ack();
	value = iic_read_byte(0);
	iic_stop();
	return value;
}
/*
按照AT24(写)时序图的先后顺序,进行顺序执行
*/
void AT24_write_byte(u16 writeaddr,u8 DataToWrite)		//
{
	iic_start();
	if(EE_TYPE>AT24C16)
	{
		iic_send_byte(0XA0);		
		iic_wait_ack();					
		iic_send_byte(writeaddr/256);		
		iic_wait_ack();					
	}
	else{
		iic_send_byte(0XA0|(writeaddr/256)<<1);
	}
	iic_wait_ack();
	iic_send_byte(writeaddr%256);	
	iic_wait_ack();
	iic_send_byte(DataToWrite);
	iic_wait_ack();
	iic_stop();
	delay_ms(10);
}

//---------------------------------------------------------------------------

//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
//WriteAddr  :开始写入的地址  
//DataToWrite:数据数组首地址
//Len        :要写入数据的长度2,4
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{  	
	u8 t;
	for(t=0;t<Len;t++)
	{
		AT24_write_byte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
	}												    
}



//在AT24CXX里面的指定地址开始读出长度为Len的数据
//该函数用于读出16bit或者32bit的数据.
//ReadAddr   :开始读出的地址 
//返回值     :数据
//Len        :要读出数据的长度2,4
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{  	
	u8 t;
	u32 temp=0;
	for(t=0;t<Len;t++)
	{
		temp<<=8;
		temp+=AT24_read_byte(ReadAddr+Len-t-1); 	 				   
	}
	return temp;												    
}


//检查AT24CXX是否正常
//这里用了24XX的最后一个地址(255)来存储标志字.
//如果用其他24C系列,这个地址要修改
//返回1:检测失败
//返回0:检测成功
u8 AT24CXX_Check(void)
{
	u8 temp;
	temp=AT24_read_byte(255);//避免每次开机都写AT24CXX			   
	if(temp==0X55)return 0;		   
	else//排除第一次初始化的情况
	{
		AT24_write_byte(255,0X55);
	    temp=AT24_read_byte(255);	  
		if(temp==0X55)return 0;
	}
	return 1;											  
}

//在AT24CXX里面的指定地址开始读出指定个数的数据
//读取ReadAddr地址的数据,放入pBuffer数组
//ReadAddr :开始读出的地址 对24c02为0~255
//pBuffer  :数据数组首地址
//NumToRead:要读出数据的个数
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
	while(NumToRead)
	{
		*pBuffer++=AT24_read_byte(ReadAddr++);	
		NumToRead--;
	}
}  



//在AT24CXX里面的指定地址开始写入指定个数的数据
//将pBuffer数组的内容写入WriteAddr地址
//WriteAddr :开始写入的地址 对24c02为0~255
//pBuffer   :数据数组首地址
//NumToWrite:要写入数据的个数
//*pBuffer  :读出来的数据保存在数组里
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
	while(NumToWrite--)
	{
		AT24_write_byte(WriteAddr,*pBuffer);
		WriteAddr++;
		pBuffer++;
	}
}

eeprom.h文件

#ifndef EEPROM_H
#define EEPROM_H
#include "stm32f10x.h"
#include "sys.h"

#define AT24C1		127
#define AT24C2		255
#define AT24C4		511
#define AT24C8		1023
#define AT24C16		2047
#define AT24C32		4095
#define AT24C64		8189
#define AT24C128		16383
#define AT24C256		32767

#define EE_TYPE 	AT24C2

void AT24_init(void);
u8 AT24_read_byte(u16 readaddr);									//读一个字节(8位)的数据
void AT24_write_byte(u16 writeaddr,u8 DataToWrite);		//写一个字节的数据

void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);			//写入Len长度位的数据
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len);
u8 AT24CXX_Check(void);
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);						
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);

#endif
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好好睡觉好好吃饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值