单片机驱动AT24C02存储芯片

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;
}
时间: 2024-10-31 07:37:58

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

关于单片机代码架构分层

最近看了一个大神吴坚鸿的文章,他的软件架构写得还是不错的,但是代码风格一般,全局变量满天飞,但开发出来的产品稳定,性能也好.不管怎么说,在企业里,老板只追求结果,不追求过程,即使代码写得再不好,能实现功能就不错了.在这里,我借鉴他的""三区一线理论"做下分析". #include <reg51.h> void init(); void initial(); void delay_l(unsigned int ul); void APK(); void m

《我和PIC单片机:基于PIC18》——导读

前 言 无论你是51单片机的铁杆粉丝,还是立志电子研发的有为青年,抑或是发烧友型的宅男技术控,PIC单片机都是值得你花时间和精力去仔细研究的一种微控制器.纵观国内8位单片机市场,PIC在性能指标.开发环境.产品线结构以及性价比方面都不逊色于任何一个竞争对手.而与PIC丰富的产品形成鲜明对比的是,介绍PIC的书籍稍显匮乏,大部分书籍还是以PIC16中档机为例配合汇编语言进行介绍.其实,目前PIC18高档机的价格与中档机相比已经没有明显的差距了,但性能却比后者提高了很多,本书就是以PIC的高档系列P

12864液晶-protues 中液晶驱动问题

问题描述 protues 中液晶驱动问题 在ptotues中如果在用msp430F249单片机驱动液晶的时候: 液晶变黑了,程序哪部分出问题了啊.

《51单片机应用开发从入门到精通》——第 1 章 单片机开发预备知识 1.1 单片机开发流程

第 1 章 单片机开发预备知识 单片机的应用十分广泛,从工业控制到家用电器,许多地方都有单片机的身影.掌握了单片机开发技术,不仅能够根据自己的需要进行电子设计,实现自己的一些想法,而且也为进一步学习嵌入式技术打下一定的基础. 本章将对单片机应用系统的软.硬件设计以及开发和调试等各个方面加以介绍,以便读者能通过对本章的学习较快地完成单片机应用系统的研制工作. 1.1 单片机开发流程 单片机的开发主要分为硬件开发和软件开发,在系统设计上又有最小系统和扩展系统两种.下面将通过系统硬件设计.软件设计进行

tft学习-ili9486中文数据手册,网上都没有中文的

问题描述 ili9486中文数据手册,网上都没有中文的 谁有ili9486中文数据手册,我想学习他,我也不懂能用单片机驱动么,在网上看到屏幕好就买来学习 解决方案 英文的借助google翻译看下.关键点也就是那么一些.比如管脚定义,原理图等等.

实验4 IIC通讯与EEPROM接口

1.       用C语言编程,利用定时器产生一个0~99秒变化的秒表,并且显示在数码管上,每过一秒将这个变化写入实验板上AT24C02,当关闭实验板电源,并再次打开实验板电源时,单片机从AT24C02中将原来写入的数据读出来,接着继续变化在数码管上.   #include<reg51.h> #define uchar unsigned char #define uint unsigned int   //=========全局变量区==============================

关于STM32的延时问题

最近一直在搞一辆智能小车,用STM32单片机驱动,往上面加了很多外设,外型如下: 今天下午打算在LCD显示一个温度,却发现怎么都显示不了,也找不出原因,还好我们公司的郑工帮我看出了问题,让我顺利改过来成功的显示在LCD上,毕竟比我先进公司的工程师还是要有经验一些.o(︶︿︶)o 唉,就是定时计数器少加了一个0,于是延时慢了10倍,导致温度传感器时序没有配置正确,找了一个下午.就这个问题我做下总结,在STM32中,延时的方法有两种,一种是普通延时法,用循环实现,另外一种就是嘀嗒定时器的实现方法,我

I.MX6 AT24Cxx eeprom Linux i2c-gpio

/************************************************************************** * I.MX6 AT24Cxx eeprom Linux i2c-gpio * 声明: * 很多时候当我们使用Linux系统管理硬件的时候,更多的是通过芯片中的控制器, * 但有时候,我们也会遇到芯片中的控制不够用,或者在设计的过程中出现意外,如没 * 有想到控制器存在,本文中的内容就是因为I2C中第四个控制器不存在,但硬件上却 * 认为其存在,

单片机-请问大神2M542驱动怎么使用?

问题描述 请问大神2M542驱动怎么使用? 改驱动的输入口的PLS+,PLS-,DIR+,DIR-,ENA+,ENA-与51单片机怎么连接? 解决方案 http://www.docin.com/p-628212600.html