AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。

管脚描述
管脚名称
功能
A0 A1 A2
器件地址选择
SDA
串行数据/地址
SCL
串行时钟
WP
写保护
Vcc
+1.8V~ 6.0V 工作电压
Vss

了解了什么是AT24C02之后,我们具体要如何来操作它呢?

操作它之前,我们先来了解一下I2C总线,什么是I2C总线?

I2C总线(I2C
bus,Inter-IC bus)是一个双向的两线连续总线,提供集成电路(ICs)之间的通信线路。I2C总线是一种串行扩展技术,最早由Philips公司推出,广泛应用于电视,录像机和音频设备。I2C总线的意思是“完成集成电路或功能单元之间信息交换的规范或协议”。Philips公司推出的I2C总线采用一条数据线(SDA),加一条时钟线(SCL)来完成数据的传输及外围器件的扩展;对各个节点的寻址是软寻址方式,节省了片选线,标准的寻址字节SLAM为7位,可以寻址127个单元。

I2c总线的模拟方法:

SDA:数据线

SCL:时钟线

1、I2C起始信号:这里是SDA先开始,都为高电平







- SCL是高电平,而SDA是由低电平变为高电平,建立SDA保持的时间要>4.7us



-- 在SCL的时钟信号在高电平期间SDL信号产生一个下降沿。

起始之后的SDL和SCL都为0,同样保持时间也要>4.7us





2、I2C停止信号:这里是SDA先,SDA之前是低电平







SCL高电平期间,SDA线由低电平向高电平的变化表示终止信号

- 当SCL高电平的时候,SDA要产生一个上升沿,SDA产生上跳沿之前是低电平,

建立从低电平到高电平这个期间,时间间隔要大于4us





3、逻辑"1"和逻辑"0"表示:

逻辑"0"。注意在SCL跳变读取期间,要保持SDA的稳定

         这是因为I2C总线读取数据SCL为高电平





 

如何发送一个字节:



1、首先发数据每次都是发一个字节,一个字节有8位的数据,所以我们需要定义一个8位的代表数据的变量,最可靠的就是unsigned char

   发数据的时候是一位一位的发,所以需要有一个循环来发,发送数据发8位要从最高位开始,所以要将数据线偏移到最高的位置也就是

   要右移7位,可以这么理解,看下图:



   刚开始,dat表示:10000000 
,dat表示1

   现在要将dat偏移到最高位,那么dat要干掉所有的0,也就是要右移7位

   10000000 >> 7  =  1;



   接着再循环将dat重新一位一位的往左移,也就是从高位移到地位 1 << 7 = 10000000 for(dat = 0 ; dat < 8 ; dat++);



如何接受一个字节:



1、接受和发送其实是一样的,区别在于发送是写数据,而接受是读数据

接下来我们来看看AT24C02的操作方法.

AT24C02的操作方法:

1 、24C02的硬件连接方法:

    引脚1、2、3、4接地线,7脚WE低电平有效

    6脚是时钟线,5脚是数据线

2、写入过程:

    1、发送器件地址

    2、发送要写入24C02的内存地址

    3、发送要写入的数据

发送器件地址的格式

__________________________________

|                             _  |

| 1 0  1  0   A2  A1  A0  R/W   |

|_________________________________|



高四位1010是24CXX系列的固定器件地址,接下来是

A2、A1、A0是根据器件连接来决定的,我们的原理图

都接地所以是000,R/W为是选择读还是写,1的时候是读

0的时候是写,所以些的地址为0xA0



3、读出过程:

    1、发送写入的器件地址(0xA0)

    2、发送要读的24C02的内存地址

    3、发送读出的器件地址(0xA1)

    4、独取数据



当读取的时候,地址的最后一位R/W位是选择读,也就是该位为1,

所以读取的地址是0xA1

接下来用51单片机来写一个驱动程序:

/*--------------------------------------------------------------------------
I2C.H

这个头文件主要是模拟I2C总线的发送和接收还有AT24C02的使用,
因为51单片机本身不带有I2C的总线的功能。

	  本文件分为以下6个接口:
	  1、I2C总线的起始信号
	  2、I2C总线的结束信号
	  3、I2C总线发送数据
	  4、I2C总线接收数据
	  5、AT24C02写数据
	  6、AT24C02读数据

日期:2015年9月27日

开发者:杨源鑫

备注:
	  用户在使用该程序模块的时候只需调用最后两个函数即可,也就是AT24C02
	  的函数。
--------------------------------------------------------------------------*/

#ifndef __I2C_H
#define __I2C_H
#include <reg51.h>
#include "i2c.h"

sbit SCL=P2^1;	   //时钟线
sbit SDA=P2^0;	   //地址线

/**
 * 函数: void At24c02Write(unsigned char addr,unsigned char dat);
 * 函数功能:AT24C02写数据.
 * 使用方法:用户想要往里写数据的话就调用本函数,传入地址和数据即可
 **/

void At24c02Write(unsigned char addr,unsigned char dat);

/**
 * 函数: unsigned char At24c02Read(unsigned char addr);
 * 函数功能:AT24C02读数据.
 * 使用方法:用户想要读数据的话就调用本函数,传入地址即可
 **/

unsigned char At24c02Read(unsigned char addr);

/**
 * 函数: void I2C_Start_signal(void);
 * 函数功能:I2C总线的起始信号
 **/

void I2C_Start_signal(void);

/**
 * 函数: void I2C_Stop_signal(void);
 * 函数功能:I2C总线的结束信号
 **/

void I2C_Stop_signal(void);

/**
 * 函数: unsigned char I2C_SendByte(unsigned char dat, unsigned char ack);
 * 函数功能:I2C总线的写数据
 **/

unsigned char I2C_SendByte(unsigned char dat, unsigned char ack);

/**
 * 函数: unsigned char I2cReadByte();
 * 函数功能:I2C总线的读数据
 **/
unsigned char I2cReadByte();

/**
 * 函数: void Delay10us();
 * 函数功能:10us延时
 **/

void Delay10us();

#endif   //__I2C_H
#include "i2c.h"

/*******************************************************************************
* 函数名         : Start_signal(void)
* 函数功能		 : I2C总线起始信号
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/

void I2C_Start_signal(void)
{
	 SDA = 1 ;
	 Delay10us();
	 SCL = 1 ;
	 Delay10us();
	 SDA = 0 ;
	 Delay10us();
	 SCL = 0 ;
	 Delay10us();
}

/*******************************************************************************
* 函数名         : Start_signal(void)
* 函数功能		 : I2C总线终止信号
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/

void I2C_Stop_signal(void)
{
	SDA = 0 ;
	Delay10us();
   	SCL = 1 ;
	Delay10us();
	Delay10us();
	SDA=1;
	Delay10us();
}

/*******************************************************************************
* 函数名         : I2C_SendByte(unsigned char dat, unsigned char ack)
* 函数功能		 : I2C总线发送数据
* 输入           : dat,一个字节的数据
* 输出         	 : 发送成功返回1,发送失败返回0
* 备    注       : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0
*******************************************************************************/

unsigned char I2C_SendByte(unsigned char dat, unsigned char ack)
{

	unsigned char a = 0,b = 0;//最大255,一个机器周期为1us,最大延时255us。
Replay:
    b = 0 ;
	for(a=0; a<8; a++)//要发送8位,从最高位开始
	{
		SDA = dat >> 7;	 //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
		dat = dat << 1;
		Delay10us();
		SCL = 1;
		Delay10us();//建立时间>4.7us
		SCL = 0;
		Delay10us();//时间大于4us
	}

	SDA = 1;
	Delay10us();
	SCL = 1;
	while(SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
	{
		b++;
		if(b > 200)	 //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
		{
			SCL = 0;
			Delay10us();
		//	return 0;
			goto Replay ;   //如果超过200us没有应答则发送失败,或者为非应答,这时候系统启动重发机制
							//使用goto语句返回到上面接着发
		}
	}

	SCL = 0;
	Delay10us();
 	return 1;
}

/*******************************************************************************
* 函数名         : I2cReadByte()
* 函数功能		 : I2C总线接收数据
* 输入           : 无
* 输出         	 : dat,数据
*******************************************************************************/

unsigned char I2cReadByte()
{
	unsigned char a=0,dat=0;
	SDA=1;
	Delay10us();
	for(a=0;a<8;a++)//接收8个字节
	{
		SCL=1;
		Delay10us();
		dat<<=1;
		dat|=SDA;
		Delay10us();
		SCL=0;
		Delay10us();
	}
	return dat;
}

/*******************************************************************************
* 函数名         : Delay10us()
* 函数功能		 : 延时
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/

void Delay10us()
{
   unsigned char a,b;
	for(b=1;b>0;b--)
		for(a=2;a>0;a--);
}

/*******************************************************************************
* 函 数 名         : void At24c02Write(unsigned char addr,unsigned char dat)
* 函数功能		   : 往24c02的一个地址写入一个数据
* 输    入         : 地址和数据
* 输    出         : 无
*******************************************************************************/

void At24c02Write(unsigned char addr,unsigned char dat)
{
   	I2C_Start_signal();
	I2C_SendByte(0xa0, 1);//发送写器件地址
	I2C_SendByte(addr, 1);//发送要写入内存地址
	I2C_SendByte(dat, 0);	//发送数据
	I2C_Stop_signal();

}

/*******************************************************************************
* 函 数 名         : unsigned char At24c02Read(unsigned char addr)
* 函数功能		   : 读取24c02的一个地址的一个数据
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

unsigned char At24c02Read(unsigned char addr)
{
	unsigned char num;
	I2C_Start_signal();
	I2C_SendByte(0xa0, 1); //发送写器件地址	   1010   0000
	I2C_SendByte(addr, 1); //发送要读取的地址
	I2C_Start_signal();
	I2C_SendByte(0xa1, 1); //发送读器件地址
	num=I2cReadByte(); //读取数据
	I2C_Stop_signal();
	return num;
}

单片机驱动AT24C02存储芯片的更多相关文章

  1. LCD1602液晶显示模块的单片机驱动深入详解之软件篇(AVR)

    LCD1602液晶显示模块的驱动虽然比七段数码管之类的显示要复杂一些,但实际上也并不是很难,最主要的还是初始化,为什么这么说呢?我们在调试一块新液晶屏的时候,都会先初始化看看有没有光标在闪,没有光标前 ...

  2. LCD1602液晶显示模块的单片机驱动深入详解之硬件篇

    (本文以HD44780主控芯片的LCD1602为蓝本进行描述,其中的截图也来自HD44780数据手册,用户可自行搜索其datasheet,有部分整理网上的,但绝对要比你看到的要深入得多) 一.接口 L ...

  3. TMS320VC5509驱动AT24C02

    1. 刚开始的波形不太对,比如如下代码 i2c_status = I2C_write( at24c02_write_buf, //pointer to data array , //length of ...

  4. [51单片机] EEPROM AT24c02 [存储\读取一个字节]

    /*----------------------------------------------- 名称:IIC协议 EEPROM24c02 存数读取数据 内容:此程序用于检测EEPROM性能,测试方 ...

  5. 单片机IO口驱动能力

    以STM32的IO口为例,最大的输出电流和灌入电流在芯片手册上都有说明.单个IO口一般都是十几mA到几十mA,同时总的VDD电流也有限制,大概为150mA.所以单片机驱动外设时,如果不是信号型而是功率 ...

  6. 51单片机 Keil C 延时程序的简单研究

    应用单片机的时候,经常会遇到需要短时间延时的情况.需要的延时时间很短,一般都是几十到几百微妙(us).有时候还需要很高的精度,比如用单片机驱动DS18B20的时候,误差容许的范围在十几us以内,不然很 ...

  7. STM32 驱动1602液晶

    利用STM32f103c8t6单片机驱动1602A液晶进行显示功能 上图即为写入信息后的效果图 本人用的是STM32的核心系统,无任何外设 库函数:3.5版本的库函数 驱动模式:采用4线驱动模式 供电 ...

  8. 基于basys2驱动LCDQC12864B的verilog设计图片显示

    话不多说先上图 前言 在做这个实验的时候在网上找了许多资料,都是关于使用单片机驱动LCD显示,确实用单片机驱动是要简单不少,记得在FPGA学习交流群里问问题的时候,被前辈指教,说给我最好的指教便是别在 ...

  9. 实验1 单片机IO口应用及数码管显示

    1.   单片机驱动蜂鸣器的实验: a)         说明:Lab51单片机实验板的蜂鸣器连接到单片机的P1.5 b)        基本要求:控制蜂鸣器每2秒响0.5秒. #include &l ...

随机推荐

  1. 树莓派初体验,安装Ubuntu 14.04 LTS

    转载自:http://www.polarxiong.com/archives/%E6%A0%91%E8%8E%93%E6%B4%BE%E5%88%9D%E4%BD%93%E9%AA%8C-%E5%AE ...

  2. 假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 而已」

    假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 ...

  3. EJB3+JBoss5+Myeclipse9创建HelloWorld实例

    本实例用到的工具 1. jboss5 (配置不做介绍,谷歌度娘都有) 2. MyEclipse 9 实例创建 1.EJB类创建 打开MyEclipse 9 中右上角如下选项  再新建一个EJB项目 新 ...

  4. TCP连接建立系列 — 客户端接收SYNACK和发送ACK

    主要内容:客户端接收SYNACK.发送ACK,完成连接的建立. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 接收入口 tcp_v4_rcv |--&g ...

  5. linux真正使用shell脚本做定时任务 关键的Nohup

    网上有很多的文章教大家使用定时任务,所以别的废话我就不多说了 我这里直接有SH来做定时,只是有一点大家不知道,一定要用Nohup,否则用户退出终端以后,SH任务会被自动终止掉 假设有一 tash.sh ...

  6. Objc中处理数组越界的一种办法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Objc的数组如果在访问时索引非法,则会抛出NSRangeEx ...

  7. C++对象模型的那些事儿之一:对象模型(上)

    前言 很早以前就听人推荐了<深入理解C++对象模型>这本书,从年初买来到现在也只是偶尔翻了翻,总觉得晦涩难懂,放在实验室上吃灰吃了好久.近期由于找工作对C++的知识做了一个全面系统的学习, ...

  8. Dynamics CRM 修改数据导出到EXCEL的最大条数

    系统默认的最大导出数为一万,这个数可以通过执行以下SQL看到,那要增加导出的最大数量改变MaxRecordsForExportToExcel的值即可. <span style="fon ...

  9. 01_Linux系统系统语言查询,设置Xshell工具,中文显示,测试Xshell中文字符显示,Linux中文显示乱码设置

              Xshell是一个强大的安全终端模拟软件,它支持SSH1,SSH2,以及Microsoft Windows平台的TELNETNetSarang Xshell 4 Build 0 ...

  10. Ubuntu 15.10下Qt5的安装实战

    写照篇博客的目的就是因为最近要使用Qt,但是由于本人的系统是Ubuntu的,而网上大部分的讲解全是基于Windows的,所以就花费一些时间总结了一下我的安装过程,当然也是也为了能帮助到更多的博友. 第 ...