E2PROM芯片24C02的读写程序
24C02读写C程序
//选择性读操作,从 address 地址中读出 1 个字节 uchar Read24c02(uchar address) {
uchar ch; //伪写操作 Start(); Write8Bit(WriteDeviceAddress); //发送从器件地址,且方式为写。 while(TestAck()); Write8Bit(address); while(TestAck());
}
//从 24c02 中读出 8 个 bit uchar Read8Bit() {
unsigned char temp,rbyte=0; for(temp=8;temp!=0;temp--) {
SCL=1; rbyte=rbyte<<1; rbyte=rbyte|((unsigned char)(SDA)); SCL=0; } return(rbyte); }
#define WriteDeviceAddress 0xa0 #define ReadDeviceAddress 0xa1 sbit SCL=P2^7; sbit SDA=P2^6;
//定义器件在 IIC 总线中的地址,且方式为写 //定义器件在 IIC 总线中的地址,且方式为读
sbit P10=P1Stop();
//主机产
生停止信号 return(ch);
}
//本课试验写入一个字节到 24c02 并读出来
void main(void) // 主程序 {
uchar c1,c2; c1=Read24c02(0x02);
//从 24c02 中读出 1 个字节
Write24c02(0x88,0x03); c2=Read24c02(0x03); P3=c2;
24C02读写C程序
外部存储器24c02的读写操作..
/*------51单片机-----------------------名称:外部存储器24c02..芯片:STC89C51..邮箱:MG_TCCX@QQ:2424488418编写:C.ROOKIE日期:2012.9.13 (21:31)内容:定义一个数组,把数组的数据写入24c02存储,然后清楚数组,把24c02的数据读取到数组里,然后显示在数码管上..--------------------------------------*/#include<reg52.h>#include<intrins.h> //这个文件里有空操作指令..#define _Nop() _nop_() //定义空操作指令..unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~Funsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码sbit SCL=P2^0; //模拟IIC总线时钟控制位。
sbit SDA=P2^1; //模拟IIC总线数据传送位。
sbit LATCH1=P2^2; //数码管段选。
sbit LATCH2=P2^3; //数码管位选。
bit ack; //模拟应答标志位。
//声明延时程序。
void DelayUs(unsigned char);void DelayMs(unsigned char);//定义延时程序。
void DelayUs(unsigned char t){while(--t){}}void DelayMs(unsigned char t){while(--t){DelayUs(245);DelayUs(245);}}//启动IIC总线..void Start_IIC(){SDA=1; //SCL=1的情况下,SDA从高电平到低电平就能启动IIC总线.. _Nop();SCL=1; //起始条件建立的时间大概4.7us .._Nop();_Nop();_Nop();_Nop();_Nop();SDA=0; //已经启动IIC总线.._Nop(); //起始条件锁定时间大概4.7us .._Nop();_Nop();_Nop();_Nop();SCL=0; //钳住IIC总线。
IIC总线有关24C02 实验程序
IIC总线有关24C02 实验程序;-----------------------------------------------------------------------;*程序名称:E2PROM.ASM? *;*功能说明:此程序为I2C总线E2PROM的读写实验程序,程序中将AT24C02 *;* 采用集几种模式写入,然后采用几种模式读出,将读出的数据 *;* 和写入的数据进行比较,如果有一个数据不相等则p1.0的LED *;* 指示灯点亮。
*;*创建时间:2003-06-23 *;*修改时间: *;---------------------------------------------------------------------------------------------------------SDA EQU P1.7 ;定义P1.7为I2C总线的数据线SCL EQU P1.6 ;定义P1.6为I2C总线的时钟线SLAW EQU 50H ;定义I2C器件的写地址存放空间SLAR EQU 51H ;定义I2C器件的读地址存放空间ADDRESS EQU 52H ;定义I2C器件的内部地址存放空间WR_DATA EQU 53H ;定义写数据的存放地址NB EQU 54H ;定义读写数据的数目的存放空间ORG 0000HLJMP MAINORG 0100HMAIN:MOV SP,#70H ;设定堆栈指针MOV SLAW,#0A0H ;初始化定义变量MOV SLAR,#0A1HMOV ADDRESS,#00HMOV WR_DATA,#00HMOV NB,#08HMOV R0,#30H ;写入缓冲区30H—38H赋初值MOV A,#00HMOV R5,NBW_DATA: MOV @R0,AINC R0INC ADJNZ R5,W_DATAMOV @R0,WR_DATAMOV R0,#30H ;写入缓冲区指向30HLCALL PAGE_WRITE ;对E2PROM进行页写操作LCALL DELAYMOV ADDRESS,#08H ;写入地址指向08LCALL BYTE_WRITE ;对E2PROM进行字节写操作LCALL DELAYMOV R0,#40H ;读出缓冲区指向40HMOV ADDRESS,#00H ;对E2PROM进行连续读操作LCALL RANDOM_READLCALL DELAYLCALL CURRENT_READ ;对E2PROM进行立即地址读操作INC R0MOV @R0,AMOV R0,#30HMOV R1,#40HMOV R5,#09HSETB P1.0COMP:MOV A,@R0 ;比较30H开始和40H开始的9个单元内容 MOV 08H,@R1CJNE A,08H,LED_OFF ;如有一个不相同,转到LED点亮并结束 INC R0INC R1DJNZ R5, COMPSETB P1.0 ;全部相同,熄灭LED,结束SJMP TEST_ENDLED_OFF:CLR P1.3TEST_END:SJMP $;—————————————————————————————————*;*函数名称:DELAY *;*功能描述:产生2MS的延时 *;*调用函数:无 *;*入口条件:无 *;*占用资源:R6、R7 * ;—————————————————————————————————* DELAY: ;2mS DELAYMOV R6,#0FFHDE1: MOV R7,#0AHDE2: DJNZ R7,DE2DJNZ R6,DE1RET ;—————————————————————————————————*;*函数名称:BYTE_WRITE *;*功能描述:对E2PROM指定地址写入数据 *;*调用函数:STA、WRBYT、CACK、STOP *;*入口条件:SLAW——I2C器件写地址 *;* ADDRESS——I2C的内部地址 *;* WR_DATA——写入的数据 *;*占用资源:ACC、F0、SLAW、ADDRESS、WR_DATA * ;—————————————————————————————————*BYTE_WRITE:LCALL STAMOV A,SLAWLCALL WRBYT ;写器件地址LCALL CACKJB F0,BYTE_WRITEMOV A,ADDRESS ;写入地址LCALL WRBYTLCALL CACKJB F0,BYTE_WRITEMOV A,WR_DATALCALL WRBYT ;写入数据LCALL CACKJB F0,BYTE_WRITELCALL STOPRET ;————————————————————————————————* ;*函数名称:PAGE_WRITE * ;*功能描述:对E2PROM指定的页写入8个字节的数据 * ;*调用函数:STA、WRBYT、CACK、STOP * ;*入口条件:SLAW——I2C器件写地址 * ;* ADDRESS——I2C的内部地址 * ;* R0——写数据的首地址 * ;*占用资源:ACC、R0、R7、F0、SLAW、ADDRESS、NB * ;————————————————————————————————* PAGE_WRITE:LCALL STAMOV A,SLAWLCALL WRBYT ;写器件的写地址LCALL CACKJB F0,PAGE_WRITEMOV A,ADDRESS ;写入地址LCALL WRBYTLCALL CACKJB F0,PAGE_WRITEMOV R7,#08HWR_16BYT: ;向E2PROM写入8个字节的数据MOV A,@R0LCALL WRBYTLCALL CACKJB F0,WR_16BYTINC R0DJNZ R7,WR_16BYTLCALL STOPRET ;————————————————————————————————* ;*函数名称:CURRENT_READ * ;*功能描述:读E2PROM当前地址计数器所指地址数据 *;*调用函数:STA、RDBYT、CACK、MNACK、STOP *;*入口条件:SLAR——I2C器件读地址 *;*占用资源:ACC * ;————————————————————————————————* CURRENT_READ:LCALL STAMOV A,SLARLCALL WRBYT ;写器件的读地址LCALL CACKJB F0,CURRENT_READLCALL RDBYT ;读数据LCALL MNACKLCALL STOPRET ;————————————————————————————————*;*函数名称:RANDOM_READ *;*功能描述:对E2PROM从指定地址读出NB个字节的数据 *;*调用函数:STA、WRBYT、CACK、STOP、MACK、MNACK *;*入口条件:SLAW——I2C器件的写地址 *;* SLAR——I2C器件的读地址 *;* ADDRESS——I2C的内部地址 *;* R0——读出数据存储区的首地址 *;*占用资源:ACC、F0、SLAW、SLAR、ADDRESS、R0 * ;————————————————————————————————*RANDOM_READ:LCALL STAMOV A,SLAWLCALL WRBYT ;写器件的写地址LCALL CACKJB F0,RANDOM_READMOV A,ADDRESSLCALL WRBYT ;读的内部地址LCALL CACKJB F0,RANDOM_READRDNBYT: LCALL STAMOV A,SLAR ;写读地址LCALL WRBYTLCALL CACKJB F0,RDNBYTRDN1: LCALL RDBYT ;读数据MOV @R0,ADJNZ NB,ACK ;判断是否读到最后一个字节,如果是发出非应答 LCALL MNACK ;信号,如果不是发出应答信号,继续读数据LCALL STOPRETACK: LCALL MACKINC R0SJMP RDN1;*******************************************************************;*并行总线P1.7,P1.6模拟IIC总线软件包 P1.7--SDA, P1.6--SCL * ;*入口:分配以下符号的内存地址: * ;* R0--读写出数据缓冲区首址指针 * ;* SLA--从器件地址存放单元(写地址或地址) * ;* NB--发送(读或写)数据字节数存放单元 * ;*出口:发送N个字节调用WRNBYT,接受N个字节调用RDNBYT,发送N * ;* 个字节但不要STOP调用WRNBYTS * ;*占用资源:F0标志位,C,R0,R1(第三组) * ;******************************************************************** STA:SETB SDA ;发启始位SETB SCLNOPNOPNOPNOPCLR SDANOPNOPNOPNOPCLR SCLRETSTOP: ;发停止位CLR SDASETB SCLNOPNOPNOPNOPNOPSETB SDANOPNOPNOPNOPCLR SCLRETMACK: ;发应答位CLR SDASETB SCLNOPNOPNOPNOPCLR SCLSETB SDARETMNACK: ;发非应答位SETB SDASETB SCLNOPNOPNOPNOPCLR SCLCLR SDARETCACK: ;发非应答位SETB SDASETB SCLCLR F0MOV A,P1JNB ACC.7,CEND ;应答位为1,不置位F0 SETB F0CEND: CLR SCLNOPRETWRBYT: ;写单字节MOV R1,#08HWLP: RLC AJC WR1AJMP WR0 ;跳入写0WLP1: DJNZ R1,WLPRETWR1: ;写1SETB SDASETB SCLNOPNOPNOPNOPCLR SCLCLR SDAAJMP WLP1WR0: ;写0CLR SDASETB SCLNOPNOPNOPNOPCLR SCLAJMP WLP1RDBYT: ;读单字节MOV R1,#08HRLP:SETB SDASETB SCLMOV A,P1JNB ACC.7,RD0 ;转读0AJMP RD1 ;转读1RLP1:DJNZ R1,RLP ;8位全接收完毕,转退出 RETRD0:CLR CMOV A,R2RLC AMOV R2,ACLR SCLAJMP RLP1RD1:SETB CMOV A,R2RLC AMOV R2,ACLR SCLAJMP RLP1END。
最好的24C02储存开机次数实验读写程序
24C02储存开机次数实验24C02是2K字节的串行EEPROM, 内部含有256个8位字节,该器件通过总线操作,并有专门的写保护功能。
串行EEPROM简称I2C总线式串行器件。
串行器件不仅占用很少的资源和I/O线,而且体积大大缩小,同时具有工作电源宽、抗干扰能力强、功耗低、数据不易丢失和支持在线编程等特点。
I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
我们通过一个实验来了解24C02的读写操作过程:该实验功能是单片机复位一次,自动从24C02中读取数据,然后加1,最终数码管中的数据就是开机的次数,具有一定的实用意义。
相关原理:程序运行的照片:接线方法:1、接8位数码管的数据线。
将数码管部份的数据口 JP5接到CPU部份的P0口JP51.2、接8位数码管的显示位线。
将数码管部份的显示位口 JP8接到CPU部份的P2口JP52.3、用一根2PIN数据线一端插入CPU部份JP53(P3口)的P3.6,P3.7另外一端插入24C02部份的控制端JP38。
烧写后用手按复位键可以看到数码管每按一下加一。
程序流程图:汇编语言参考程序: SDA24 EQU P3.7 SCLK24 EQU P3.6 ORG 0000HAJMP MAINORG 0080HMAIN:CLR P3.7 ;打开写保护MOV DPTR,#TABMOV A,#00H ;读地址LCALL RD24CJNE A,#10,TTTT: JNC TT1AJMP TT2TT1: MOV A,#00TT2: MOV 30H,AMOVC A,@A+DPTRCLR P2.6 ;开数码管MOV P0,A ;送显示MOV A,30HINC AMOV B,AMOV A,#00HLCALL WT24AJMP $TAB: DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60HRD24: PUSH ACC ;读24C02子程序。
AT24C02串行E2PROM的工作原理与读写
AT24C02串行E2PROM的工作原理与读写串行EEPROM中,较为典型的有ATMEL公司的AT24CXX系列和AT93CXX等系列产品。
简称I2C总线式串行器件。
串行器件不仅占用很少的资源和I/O线,而且体积大大缩小,同时具有工作电源宽、抗干扰能力强、功耗低、数据不易丢失和支持在线编程等特点。
I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL (串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
1.I2C总线的基本结构:采用I2C总线标准的单片机或IC器件,其内部不仅有I2C接口电路,而且将内部各单元电路按功能划分为若干相对独立的模块,通过软件寻址实现片选,减少了器件片选线的连接。
CPU不仅能通过指令将某个功能单元电路挂靠或摘离总线,还可对该单元的工作状况进行检测,从而实现对硬件系统的既简单又灵活的扩展与控制。
I2C总线接口电路结构如图1所示。
从图中可以看出:对于时钟及数据传送,串行数据I/O端SDA一般需要用外部上拉电阻将其电平拉高。
2.双向传输的接口特性:传统的单片机串行接口的发送和接收一般都分别用一条线,如MCS51系列的TXD和RXD,而I2C总线则根据器件的功能通过软件程序使其可工作于发送或接收方式。
当某个器件向总线上发送信息时,它就是发送器(也叫主器件),而当其从总线上接收信息时,又成为接收器(也叫从器件)。
主器件用于启动总线上传送数据并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。
I2C总线的控制完全由挂接在总线上的主器件送出的地址和数据决定。
总线上主和从(即发送和接收)的关系不是一成不变的,而是取决于此时数据传送的方向。
SDA和SCL均为双向I/O线,通过上拉电阻接正电源。
当总线空闲时,两根线都是高电平。
连接总线的器件的输出级必须是集电极或漏极开路,以具有线“与”功能。
24c02读写实验c程序
Init();//初始化
DispBuf[2]=Hidden;
DispBuf[3]=Hidden;
for(;;)
{
Calc(RecBuf[1],RomDat[0]);//分别显示地址和数据
if(Rec)//接收到数据
{Rec=0;//清除标志
if(RecBuf[0]==0)//第一种功能,写入
TR1=1;
}
void Calc(uchar Dat1,uchar Dat2)//第一个参数放在第1、2位,第二个参数放入第5、6位
{DispBuf[0]=Dat1/16;
DispBuf[1]=Dat1%16;
DispBuf[4]=Dat2/16;
DispBuf[5]=Dat2%16;
}
void main()
/**************************************************
24C02.C
功能描述:
PC端发送3个数据n0,n1,n2.
n0=0,写,将n1写入n2地址中
n0=1,读,读出n1地址中的数据,n2不起作用,但必须有
收到一个字节后,将其地址值显示在数码管第1、2位上,数值显示在第5、6位上
sbit we=P2^7;
sbit du=P2^6;
uchar code dispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar code disptab[]={0x3f,0x6,0x5b,0x4f,0x66,
0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
Rec=1;//置位标志
24C02数据读写
delay(); sda=CY; delay(); scl=1; delay(); } scl=0; delay(); sda=1; delay(); } /*******************读一个字节*********************/ uchar read_byte()
{ uchar i,k; scl=0; delay(); sda=1; delay(); for(i=0;i<8;i++) { scl=1; delay(); k=(k<<1)|sda; scl=0; delay();
delay(); scl=1; delay(); } /*************写一个字节*************************/ void write_byte(uchar date) { uchar i,temp; temp=date; for(i=0;i<8;i++) {
temp=temp<<1; scl=0;
void respons() //应答 {
uchar i; scl=1; delay(); while((sda==1)&&(i<250))i++; scl=0; delay(); } /************IIC 初始化****************************/ void init() { sda=1;
IIC 时序 24C02 的操作
一、认识 IIC 总线的工作方式 这是最常用、最典型的 IIC 总线连接方式。
物理结构上,IIC 系统由一条串行数据线 SDA 和一条串行时钟线 SCL 组成。主机按一定的通信协议向从机寻址和进 行信息 传输。在数据传输时,由主机初始化一次数据传输,主机使数据在 SDA 线上传输的同时还通过 SCL 线传输 时钟。信息传输的对象和方向以及信息传输的开始和终 止均由主机决定。 每个器件都有一个唯一的地址,而且可以是单接收的器件(例如:LCD 驱动器)或者可以接收也可以发送的器件(例 如:存储器)。发送器或接收器可以在主模式或从模式下操作,这取决于芯片是否必须启动数据的传输还是仅仅被
E2PROM芯片24C02的读写程序
E2PROM芯片24C02的读写程序一、实验目的:给24C02的内部RAM写入一组数据,数据从24C02内部RAM的01h开始存放。
然后再把这组数据读出来,检验写入和读出是否正确。
在这里我们给24C02中写入0、1、2的段码,然后把它读出来,送到数码管显示。
二、理论知识准备:上面两个实验主要学习的是利用单片机的串口进行通讯,本实验要介绍的是基于I2C总线的串行通讯方法,下面我们先介绍一下I2C总线的相关理论知识。
(一)、I2C总线概念I2C总线是一种双向二线制总线,它的结构简单,可靠性和抗干扰性能好。
目前很多公司都推出了基于I2C总线的外围器件,例如我们学习板上的24C02芯片,就是一个带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,方便进行数据的长期保存。
(二)、I2C总线结构I2C总线结构很简单,只有两条线,包括一条数据线(SDA)和一条串行时钟线(SCL)。
具有I2C接口的器件可以通过这两根线接到总线上,进行相互之间的信息传递。
连接到总线的器件具有不同的地址,CPU根据不同的地址进行识别,从而实现对硬件系统简单灵活的控制。
一个典型的I2C总线应用系统的组成结构如下图所示(假设图中的微控制器、LCD驱动、E2PROM、ADC各器件都是具有I2C总线接口的器件):我们知道单片机串行通讯的发送和接收一般都各用一条线TXD和RXD,而I2C总线的数据线既可以发送也可以接受,工作方式可以通过软件设置。
所以,I2C总线结构的硬件结构非常简洁。
当某器件向总线上发送信息时,它就是发送器,而当其从总线上接收信息时,又成为接收器。
(三)、I2C总线上的数据传送下面我们看看I2C总线是如何进行数据传送的。
我们知道,在一根数据线上传送数据时必须一位一位的进行,所以我们首先研究位传送。
1、位传输I2C总线每传送一位数据必须有一个时钟脉冲。
被传送的数据在时钟SCL的高电平期间保持稳定,只有在SCL低电平期间才能够改变,示意图如下图所示,在标准模式下,高低电平宽度必须不小于4.7us。
24C02串行E2PROM的读写资料
24C02串行E2PROM的读写资料I2C 总线是一种用于IC 器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD 驱动器还是键盘接口。
1.I2C 总线的基本结构采用I2C 总线标准的单片机或IC 器件,其内部不仅有I2C 接口电路,而且将内部各单元电路按功能划分为若干相对独立的模块,通过软件寻址实现片选,减少了器件片选线的连接。
CPU 不仅能通过指令将某个功能单元电路挂靠或摘离总线,还可对该单元的工作状况进行检测,从而实现对硬件系统的既简单又灵活的扩展与控制。
I2C 总线接口电路结构如读写子程序如下:;写串行E2PROM 子程序EEPW; R3=10100000(命令1010+器件3 位地址+读/写。
器件地址一个芯片,是000); (R4)=片内字节地址; (R1)=欲写数据存放地址指针; (R7)=连续写字节数nEEPW: MOV P1,#0FFHCLR P1.0;发开始信号MOV A,R3;送器件地址ACALL SUBS MOV A,R4;送片内字节地址ACALL SUBSAGAIN: MOV A,@R1ACALL SUBS;调发送单字节子程序INCR1DJNZ R7,AGAIN;连续写n 个字节CLR P1.0;SDA 置0, 准备送停止信号ACALL DELAY ;延时以满足传输速率要求SETBP1.1;发停止信号ACALL DELAY SETB P1.0RETSUBS: MOV R0,#08H ;发送单字节子程序LOOP: CLR P1.1RLC A MOV P1.0,C NOP SETB P1.1ACALL DELAY DJNZ R0,LOOP ;循环8 次送8 个bit CLR P1.1ACALL DELAY SETB P1.1REP: MOV C,P1.0JC REP;判应答到否,未到则等待CLR。
AT24C02 E2PROM介绍及驱动程序
SDAE=1;
}
/************************************************************************/
void NoAck() {
SDAE=1;
SCL=1;
SCL=0;
}
/***********************************************************************/
#include<reg52.h>
#include<intrins.h> sda=P3^2; //IO口 //不同自己定义
sbit scl=P3^1;
/////////24C02读写驱动程序////////////////////
Write8Bit(ReadDviceAddress|ddd);
TestAck();
while(bytes!=1) {
*RamAddress=Read8Bit();
Ack();
RamAddress++;
bytes--;
}
*RamAddress=Read8Bit();
NoAck();
Write8Bit(*Wdata);
TestAck();
Wdata++;
}
Stop();
DelayMs(10);
}
/***************************************************************************/
unsigned char Read8Bit() {
24C02读写实验
(1)分段运行程序,对 24C02 进行字节的读/写操作后,观察存储器 RAM 30H-37H 单 元的数据,比较写入与读出的数据是否一致;
(2)连续运行程序,观察数码管的显示的数据,是否是写入的数据。
实验四 E2PROM 读写实验
一、 实验内容与要求:
1.向 24C02 的 00H-07H 存储单元写入 8 个字节的数据,再读出数据存入单片机 RAM 的 30H-37H,比较是否一致。
2.将读出的数据在数码管上显示出来。
二、 实验设计
1.24C02 与单片机的接口电路如图 4.1 所示。
图 4.1 24C02 与单片机的接口电路
返回
返回
(a) 写操作流程图
(b) 读操作流程图
图4.2 24C02数据传输流程图
开始 系统初始化 确定要写入的数据 写入 24C02
N 数据写完?
Y 读 24C02
存入 RAM
显示数据
结束
图 4.3 主程序流程图
四、实验报告要求:
1.实验名称 2.实验内容 3.实验设计
画出实验电路原理图,程序流程图,源程序; 4.实验操作:程序调试过程和运行结果; 5.实验总结。
发启始信号
发启始信号
器件地址写
器件地址写
写入读单元地址
写入存储单元地址
发起始信号
写入数据
器件地址读
发停止信号
读出数据
延时 10ms 等待写
发停止信号
单片机的 P1.0 口接 24C02 的 SDA,作为串行数据的输入输出端口;P1.1 口为 24C02 提供 串行时钟信号。
EEPROM24C02,程序将对存储器进行读和写
/*EEPROM24C02,程序将对存储器进行读和写,因此涉及到键盘程序,比较复杂,耐心学,例子读取24C02内部数据,在数码管上显示,可通过按键来进行不同地址数据的读取和保存*/#include <reg51.h>#include <intrins.h>#define W24C02 0xA0 //存储器的写地址#define R24C02 0xA1 //存储器的读地址#define MSB 0x80 //8位二进制最高位置1#define LSB 0x01 //8位二进制最低位置1/********************/sbit SDA=P3^6; //A T24C02串行数据5脚sbit SCL=P3^7; //A T24C02串行时钟6脚sbit SPK=P3^4; //蜂鸣器,按键用时蜂鸣void I2C_write(unsigned char tmp); //向I2C总线写数据unsigned char I2C_read(); //向I2C总线读数据void I2C_ACK(bit tmp); //ACK应答void I2C_start(void); //I2C传送数据的开始void I2C_stop(void); //I2C传送数据的结束void _24c02menu(void); //当我们按下按键进入处理I2C数据时用的函数void _24c02wdate(unsigned char tmp); //当我们对24C02存储器进行写数据用到的函数void display(unsigned char *lp,unsigned char lc);//显示,在键盘程序里用过void displaystr(unsigned char *lp,unsigned char lc);//字符的显示函数,同上void delay();//延时子函数void ReadKey(void); //扫描键盘获取键值unsigned char l_key=0xFF; //定义变量,存放键值unsigned char l_keyold=0; //做为按键松开否的凭证code unsigned char l_24C02[5]={0x5b,0x66,0x39,0x3f,0x5b};//定义数组常量在数码管上显示24C02unsigned char l_address=0; //读24C02的地址变量unsigned char l_tmpdate[6]={0,0,0x10,0,0,0}; //数组变量code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//共阴数码管0-9 a-f - 表code unsigned char key_tab[17]={0xed,0x7e,0x7d,0x7b,0xbe,0xbd,0xbb,0xde,0xdd,0xdb,0x77,0xb7,0xee,0xd7,0xeb,0xe7,0XFF};//========================此数组为键盘编码,// 1 2 3 a// 4 5 6 b// 7 8 9 e// * 0 # fvoid main(void) //入口函数{TMOD=0x01; //设置定时器0为模式1方式,TH0=0XD1; //设置初值,为12毫秒TL0=0X20;EA=1; //开启总中断ET0=1; //开启定时器中断0EX0=1; //开启外部中断0IT0=1; // 设置成下降沿触发方式P0=0xf0; //while(1){displaystr(l_24C02,5); //用这个函数显示5个字符if(l_key==0x0e){l_key=0xff; //按下#键调用_24c02menu(); //此函数}}}//以下一部份在键盘程序里有说明,此处不在讲述void key_scan() interrupt 0 //外部中断0 0的优先级最高{EX0=0;TH0=0XD1;TL0=0X20;TR0=1;}void timer0_isr(void) interrupt 1 //定时器0的中断函数{TR0=0;ReadKey();}void ReadKey(void){unsigned char i,j,key;j=0xfe;key=0xff;for (i=0;i<4;i++){P0=j;if ((P0&0xf0)!=0xf0){key=P0;break;}j=_crol_(j,1);}if (key==0xff){l_keyold=0xff;P0=0xf0;SPK=1;EX0=1;return;}else{TH0=0X2E;TL0=0X20;TR0=1;SPK=0;}if(l_keyold!=key){l_keyold=key;for(i=0;i<17;i++){if (key==key_tab[i]){l_key=i;break;}}}}void display(unsigned char *lp,unsigned char lc)//显示{unsigned char i;P2=0;P1=P1&0xF8;for(i=0;i<lc;i++){P2=table[lp[i]];P2=0;if(i==7)break;P1++;}}void displaystr(unsigned char *lp,unsigned char lc)//显示{unsigned char i;P2=0;P1=P1&0xF8;for(i=0;i<lc;i++){P2=lp[i];delay();P2=0;if(i==7)break;P1++;}}void delay(void) //{unsigned char i=10;while(i)i--;}void _24c02menu(void) //处理I2C数据时用的函数{unsigned char tmp,tmp2;P2=0; //数码管显示清0l_key=0xfe; //进入存储器处理程序先读取0地址的数据while (1){if(l_key==0x0c){ //如果按下*号键退出循环,即退出回到主函数l_key=0xff;break;}switch(l_key){ //扫描键盘做相应处理case 0x0a: //按下0X0A键,我们可将它理解为上翻键l_key=0xff;if(l_address>0){l_address--; //将地址减1l_key=0xfe; //读取数据break;case 0x0b: //按下0X0A键,我们可将它理解为下翻键l_key=0xff;if(l_address<255){l_address++; //将地址加1l_key=0xfe; ////读取数据}break;case 0x0e: //如果按下#号键,调用写存储器函数l_key=0xff;_24c02wdate(tmp);l_key=0xfe;break;case 0xfe: //此按值是在键盘是没有的,我们有内部给他增加做为读数据处理l_key=0xff;I2C_start(); //I2C读数据的开始,到下面的结束是读一地址的整个过程,I2C_write(W24C02); //向I2C总线发出读取24C02的地址I2C_ACK(0); //下面就得你们自己结合I2C串口协议进行,先看看24C02数据手册是怎么讲I2C协议的I2C_write(l_address);//先写入地址,I2C_ACK(1);I2C_stop();I2C_start(); //再开始读取数据I2C_write(R24C02);I2C_ACK(0);tmp=I2C_read();I2C_ACK(1);I2C_stop(); //读取一个地址的数据结束l_tmpdate[0]=l_address/16; //数码管前两位显示地址(以16进制显示)l_tmpdate[1]=l_address%16; //将地址变量分开用两位数据l_tmpdate[3]=tmp/100; //后面用10进制数显示数据,中间用"-"隔开,数组l_tmpdate[2]tmp2=tmp%100; //8位二进制最大十进制为255,所以我们也将它分开三位显示l_tmpdate[4]=tmp2/10;l_tmpdate[5]=tmp2%10;break;}display(l_tmpdate,6);}}void _24c02wdate(unsigned char tmp)//对24C02的写数据处理函数{unsigned char tmp2=0;while(1){if (l_key==0x0c){ //如果按下*号键退出循环,即退出回到上一极函数l_key=0xff;break;}if(l_key==0x0e){ //如果按下#号键,将更改的数据写入24C02存储器l_key=0xff;I2C_start(); //下面是写一地址数据的过程I2C_write(W24C02); //先向总线发出写24C02的地址I2C_ACK(0);I2C_write(l_address); //写入地址I2C_ACK(0);I2C_write(tmp); //然后写入数据I2C_ACK(1);I2C_stop();break;}switch(l_key){ //下面是对数据的处理case 0x01: //如果按下1键,数据百位加1l_key=0xff;if(tmp<155)tmp+=100;break;case 0x02: //如果按下2键,数据十位加1l_key=0xff;if(tmp<245)tmp+=10;break;case 0x03: //如果按下3键,数据个位加1l_key=0xff;if(tmp<255)tmp++;break;case 0x04: //如果按下4键,数据百位减1l_key=0xff;if(tmp>=100)tmp-=100;break;case 0x05: //如果按下5键,数据十位减1l_key=0xff;if(tmp>=10)tmp-=10;break;case 0x06: //如果按下6键,数据个位减1l_key=0xff;if(tmp>0)tmp--;break;}l_tmpdate[3]=tmp/100; //地址不变我们不用修改,更改数据显示即可tmp2=tmp%100;l_tmpdate[4]=tmp2/10;l_tmpdate[5]=tmp2%10;display(l_tmpdate,6);}}void I2C_write(unsigned char tmp)//I2C写入一个8位二进制数,高位在前低位在后{unsigned char i;for(i=0;i<8;i++){SCL=0;_nop_();_nop_();_nop_();SDA=(bit)(tmp&0x80);tmp<<=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();}SCL=0;}unsigned char I2C_read(void)////I2C读取一个8位二进制数,也是高位在前低位在后{unsigned char i,tmp;tmp=0;for(i=0;i<8;i++){SCL=0;_nop_();_nop_();_nop_(); //加入空指令增加稳定性,这关系到频率问题SDA=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();tmp<<=1;if(SDA==1)tmp++;}SCL=0;return tmp;}void I2C_ACK(bit tmp) //根据tmp的1、0来决定应答信号{SDA=tmp;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;}void I2C_start(void) //看看I2C开始的波形,再对应SDA、SCL的输出{SDA=1;_nop_();SCL=1;_nop_();SDA=0;_nop_();SCL=0;_nop_();}/*********/void I2C_stop(void) //I2C结束{SDA=0;_nop_();SCL=1;_nop_();SDA=1;_nop_();SCL=0;_nop_();}。
24c02读写--相关资料
24c02读写—相关资料AT24C02是美国Atmel公司的低功耗CMOS型E2PROM,内含256×8位存储空间,具有工作电压宽(2.5~5.5 V)、擦写次数多(大于10 000次)、写入速度快(小于10 ms)、抗干扰能力强、数据不易丢失、体积小等特点。
而且他是采用了I2C总线式进行数据读写的串行器件,占用很少的资源和I/O线,并且支持在线编程,进行数据实时的存取十分方便。
1 AT24C02的引脚功能AT24C02引脚如图1所示。
他的的1、2、3脚是3根地址线,用于确定芯片的硬件地址。
第8脚和第4脚分别为正、负电源。
第5脚SDA为串行数据输入/输出,数据通过这根双向I2C总线串行传送。
第6脚SCL为串行时钟,SDA和SCL为漏极开路端,在实际的应用当中都需要和正电源间各接一个5.1 kΩ的电阻上拉。
第7脚为WP写保护端,接地时允许芯片执行一般的读写操作;接正电源时只允许对器件进行读操作。
2 AT24C02的内部结构图2为AT24C02的内部结构图。
启动、停止逻辑单元 接收数据引脚SDA上的电平信号,判断是否进行启动和停止操作串行控制逻辑单元 根据SCL,SDA电平信号以及“启动、停止逻辑”部件发出的各种信号进行区分,并排列出有关的“寻址”、“读数据”和“写数据”等逻辑,将他们传送到相应的操作单元。
例如:当操作命令为“寻址”时候,他将通知地址计数器加1,并启动“地址比较”器进行工作。
在“读数据”时,他控制“Dout/确认逻辑”单元;在“写数据”时候,他控制“高压泵/定时”电路,以便向E2PROM电路提供编程所需要的高电压。
地址/计数器单元 产生访问E2PROM所需要的存储单元的地址,并将其分别送到X译码器进行字选,送到Y译码器进行位选。
高压泵/定时单元 由于E2PROM数据写入时候需要向电路施加编程高电压,为了解决单一电源电压的供电问题,芯片生产厂家采用了电压的片内提升电路。
电压的提升范围一般可以达12~21.5 V。
电气化自动技术 实验8-- 24C02读写-实验指导书
实验八 24C02读写实验一、实验概述使用I2C对24C02进行读写,记录开机的次数。
二、实验目的1、掌握单片机IO模拟I2C总线的方法。
2、了解EEPROM保存数据的特性。
三、实验预习要求1、AT24C02是一个2K位串行CMOS E2PROM,内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。
AT24C02有一个16字节页写缓冲器。
该器件通过IIC总线接口进行操作,有一个专门的写保护功能。
2、器件寻址:前八位是地址地址信号,从最高位(MSB)开始,其中前四位是固定值1010,后三位有管脚A0、A1、A2的基地情况确定。
最后一位是读写控制信号,0表示写,1表示读。
若与SDA线发送过来的地址比较一致,则器件输出应答0,否则将返回等待状态。
器件内部地址寻址是在器件寻址之后,对256个字节进行寻址,直接传送8位地址信号(00-FF)对应于器件内部的地址。
四、实验原理在实际的应用中,保存在单片机 RAM 中的数据,掉电后就丢失了,保存在单片机的FLASH 中的数据,又不能随意改变,也就是不能用它来记录变化的数值。
但是在某些场合,我们又确实需要记录下某些数据,而它们还时常需要改变或更新,掉电之后数据还不能丢失,比如我们的家用电表度数,电视机里边的频道记忆,一般都是使用EEPROM 来保存数据,特点就是掉电后不丢失。
本实验使用的这个器件是 24C02,是一个容量大小是 2Kbits,也就是 256 个字节的 EEPROM。
一般情况下,EEPROM 拥有30 万到 100 万次的寿命,也就是它可以反复写入 30-100 万次,而读取次数是无限的。
24C02 是一个基于 I2C 通信协议的器件,因此,使用24C02还需要了解I2C通信协议。
I2C 多用于板内通信,比如单片机和EEPROM 之间的通信。
在硬件上,I2C 总线是由时钟总线 SCL 和数据总线 SDA 两条线构成,连接到总线上的所有器件的 SCL 都连到一起,所有 SDA 都连到一起。
E2PROM读写设计实验
实验报告(四)题目:AT24C02应用程序设计姓名:赵帅专业:控制09级学号:2009430111009实验四 AT24C02应用程序设计一、实验目的1.掌握24C02与单片机接口电路的设计;2.掌握24C02(E2PROM)的读/写操作的编程方法。
二、实验设备LJD-SY-5100实验板、计算机,Keil软件。
三、实验内容与要求1.把数据表的数据写入24C02的00H-07H存储单元,再读出数据存入单片机RAM的30H-37H,TAB:DB 2H,0H,0H,9H,1H,0H,0H,1H2.将读出的数据在数码管上显示出来。
四、实验原理1.24C02与单片机的接口电路如图4.1所示。
图4.1 24C02与单片机的接口电路单片机的P1.0口接24C02的SDA端口,作为串行数据的输入输出端口;P1.1口接24C02的SCL端口,为24C02提供串行时钟信号。
2. AT24C02是I2C总线接口的E2PROM,根据I2C总线数据传送格式,对24C02读写数据的操作如图4.2所示。
3.根据实验要求,主程序设计流程图见图4.3。
五、实验方法与步骤(1)先运行对24C02进行字节的读/写操作程序,观察存储器RAM 30H-37H单元的数据;(2)再运行显示程序,观察数码管的显示。
在实验板上连续运行程序,检验程序能否达到实验要求。
六、程序设计1、流程图:图4.3 主程序流程图2、源程序:;定义24C02管脚SDA BIT P1.0SCL BIT P1.1R_DATA EQU 30H ;数据存储缓冲区ORG 0000HMOV P1,#60HMOV SP,#60HLCALL WR_EEROMlcall delay10msLCALL RD_EEROMLJMP DISP;------------------------------------------ ;写数据;----------------------------------------- WR_EEROM: MOV R6,#08 ;数据计数器 LCALL STARTMOV A,#0A0H ;器件地址写LCALL WBYTEW_LOOP: MOV A,#00H ;存储单元地址写 LCALL WBYTEMOV DPTR,#TAB ;W_LOOP1: MOV A,#00HMOVC A,@A+DPTR ;数据写LCALL WBYTEINC DPTRDJNZ R6,W_LOOP1 ;写8个数据LCALL STOP ;RETTAB:DB 2H,0H,0H,9H,1H,2H,1H,1H;---------------------------;写字节数据;--------------------------WBYTE: NOPMOV R3,#08HWBY0: CLR SCLRLC AMOV SDA,CSETB SCLNOPNOPNOPDJNZ R3,WBY0CLR SCLNOPSETB SCLNOPJB SDA,$;等待芯片内部写完成CLR SCLNOPRET;------------------------------------;启动信号;************************************START: CLR SCLNOPSETB SDANOPNOPSETB SCLNOPnopCLR SDANOPCLR SCLRET;---------------------------------------;停止信号;****************************************** STOP: CLR SCLNOPCLR SDANOPSETB SCLNOPNOPSETB SDANOPCLR SCLRET;********************************************** ;读数据;*********************************************** RD_EEROM: MOV R6,#08 ;数据计数器MOV R0, #R_DATA ;数据存入RAM地址 LCALL STARTMOV A,#0A0H ;器件地址写LCALL WBYTEMOV A,#00H ;存储单元地址LCALL WBYTENOPNOPNOPLCALL STARTNOPMOV A,#0A1H ;器件地址读LCALL WBYTER_LOOP: NOPNOPNOPNOP;MOV R0,#30HR_LOOP1: LCALL READ ;读字节数据MOV @R0,A ;存数据INC R0DJNZ R6,R_LOOP1LCALL STOPRET;----------------------------------- ;读字节数据;-----------------------------------READ: NOPMOV R3,#08HH1:CLR SCLNOPSETB SCLNOPMOV C,SDARLC AnopnopCLR SCLDJNZ R3,H1CLR SDANOPSETB SCLNOPNOPNOPNOPCLR SCLSETB SDARET;------------------------------DELAY10ms:MOV R5,#20DELAY1: MOV R2,#255DJNZ R2,$DJNZ R5,DELAY1RET;----------------------------------------------;显示子程序;---------------------------------;定义CH451管脚LOAD BIT P1.2DIN BIT P1.0DCLK BIT P1.1DOUT BIT P3.3DISP:CLR DINSETB DCLKSETB DINSETB LOADSETB DOUTNOPMOV B,#04H ;设置CH451MOV A,#03H ;关看门狗开显示键盘LCALL WRITENOPMOV B,#05H ;设置显示模式为译码方式 MOV A,#80HLCALL WRITENOP; CLR IT1 ;置外部信号为低电平触发 ; CLR IE1 ;清中断标志; SETB PX1; SETB EX1 ;允许键盘中断; SETB EA ;开总中断MOV R0,#R_DATA +7DISP1:MOV B,#03HMOV A,#00HLCALL WRITE ;加载左移命令MOV B,#08H ;加载字数据0MOV A,@R0LCALL WRITEDEC R0CJNE R0,#2FH,DISP1SJMP $;-------------------------------------WRITE:PUSH ACCCLR EX1CLR LOADMOV R7,#08HWRITE_1:RRC ACLR DCLKMOV DIN,CSETB DCLKDJNZ R7,WRITE_1MOV A,BMOV R7,#04HWRITE_2:RRC ACLR DCLKMOV DIN,CSETB DCLKDJNZ R7,WRITE_2SETB LOADSETB EX1POP ACCRETEND七、操作与调试程序记录1、程序调试过程:先设计24C02字节的读/写操作程序,并观察存储器RAM 30H-37H单元的数据;再设计显示程序,观察数码管的显示。
24C02读写程序
24C02读写程序HT49 MCU系列单片机读写HT24系列的EEPROM应用范例HT49 MCU系列单片机读写HT24系列的EEPROM应用范例文件编码:HA0017s简介:HT24系列的EEPROM是通过I2C协议控制其读写的。
HT49系列单片机的接口部分是简单I/O 口,可以用来很方便地采用I2C协议控制周边器件。
HT24系列的EEPROM总共8个管脚,三个为芯片地址脚A0、A1、A2,在单片机对它进行操作时,从SDA输入A0、A1、A2数据和芯片外部A0、A1、A2所接地址需一一对应。
一个为芯片写保护脚WP,WP脚接低电平时,芯片可进行读写操作;WP脚接高时,芯片只可进行读,不可进行写。
另外两个管脚为电源脚VCC,VSS。
用单片机对HT24系列的EEPROM进行控制时,HT24系列的EEPROM的外部管脚VCC、VSS、WP、A0、A1、A2根据需要,对应接上,SDA、SCL接到单片机控制脚上。
引脚名称I/O 功能描述A0~A2 I地址输入VSS I电源负极输入SDA I/O串行数据输入/输出SCL I串行数据传送时钟信号输入WP I写保护VCC I电源正极输入HT24系列的EEPROM根据型号不同,EEPROM的容量大小不同,当EEPROM的空间大于1页(256bytes)时,即大于2048bits,则HT49 MCU需要控制A0、A1、A2来确定写HT24系列的EEPROM 的第几页,HT24系列的EEPROM空间大小如下表所示:型号引脚A0、A1及A2使用方法容量大小HT24LC02 A0、A1、A2引脚作为器件地址输入,从SDA输入A0、A1、A2数据和芯片引脚A0、A1、A2所接状态需一一对应2K(256×8)HT24LC04 A1、A2引脚作为器件地址输入,从SDA输入A1、A2数据和芯片引脚A1、A2所接状态需一一对应,A0引脚浮空4K(512×8,2pages)HT24LC08 A2引脚器件地址输入,从SDA输入A2数据和芯片引脚A2所接状态需一一对应,其余引脚浮空8K(1024×8,4pages)HT24LC16 A0、A1、A2全部浮空,不必接16K(2048×8,8pages)HT49 MCU系列单片机读写HT24系列的EEPROM应用范例程式说明:本文是以HT49R30A-1控制HT24LC04为例的。
ATMEL24c02使用详解(汇编及C程序都有)
ATMEL 24c02使用详解(汇编及C程序都有)1000字ATMEL 24c02是一种串行EEPROM存储器,具有2KB的存储容量,可通过I2C总线进行读写操作。
使用ATMEL 24c02时,需先设置I2C总线的通信速率和设备地址。
然后,可以使用汇编语言或C语言编写程序进行读写数据操作。
汇编语言程序示例:1. 设置I2C总线通信速率及设备地址```LDAA #$0 ;设置I2C总线通信速率为100kHzSTAA SCLDIVLDAA #$A0 ;设置EEPROM的设备地址为0xA0STAA SLA```2. 写入数据到EEPROM```BYTE_WRITE PROCLDAA #$00 ;设置数据的存储地址为0x00STAA DADDRLDAA #$A5 ;设置需要写入的数据为0xA5STAA DATAJSR I2C_WRITE ;调用I2C总线写入函数RTSBYTE_WRITE ENDP```3. 从EEPROM读取数据```BYTE_READ PROCLDAA #$00 ;设置数据的读取地址为0x00STAA DADDRJSR I2C_START ;发送起始信号LDAA #$A1 ;设置EEPROM的设备地址为0xA1,读操作时需要在地址末位添加1JSR I2C_SEND ;发送EEPROM设备地址LDAA #$00 ;设置要读取的数据长度为1JSR I2C_READ ;调用I2C总线读取函数LDA DATA ;将读取到的数据保存到DATA寄存器中RTSBYTE_READ ENDP```C语言程序示例:1. 在main函数中,调用I2C_Init()函数,设置I2C总线速率和设备地址。
```void main(){I2C_Init(); //设置I2C总线速率和设备地址}```2. 写入数据到EEPROM```void Write_Byte(unsigned char addr, unsigned char dat) {I2C_Start(); //发送起始信号I2C_SendByte(0xa0); //写入EEPROM的设备地址I2C_SendByte(addr); //设置存储地址I2C_SendByte(dat); //写入数据I2C_Stop(); //发送停止信号}```3. 从EEPROM读取数据```unsigned char Read_Byte(unsigned char addr){unsigned char res;I2C_Start(); //发送起始信号I2C_SendByte(0xa0); //写入EEPROM的设备地址I2C_SendByte(addr); //设置读取地址I2C_Start(); //发送起始信号I2C_SendByte(0xa1); //设置EEPROM的设备地址为读取模式 res = I2C_ReadByte(); //读取数据I2C_Stop(); //发送停止信号return res; //返回读取的数据}```即可进行EEPROM的读写操作。
E2PROM芯片24C02的读写程序
E2PROM芯片24C02的读写程序一、实验目的:给24C02的内部RAM写入一组数据,数据从24C02内部RAM 的01h开始存放。
然后再把这组数据读出来,检验写入和读出是否正确。
在这里我们给24C02中写入0、1、2的段码,然后把它读出来,送到数码管显示。
二、理论知识准备:上面两个实验主要学习的是利用单片机的串口进行通讯,本实验要介绍的是基于I2C总线的串行通讯方法,下面我们先介绍一下I2C总线的相关理论知识。
(一)、I2C总线概念I2C总线是一种双向二线制总线,它的结构简单,可靠性和抗干扰性能好。
目前很多公司都推出了基于I2C总线的外围器件,例如我们学习板上的24C02芯片,就是一个带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,方便进行数据的长期保存。
(二)、I2C总线结构I2C总线结构很简单,只有两条线,包括一条数据线(SDA)和一条串行时钟线(SCL)。
具有I2C接口的器件可以通过这两根线接到总线上,进行相互之间的信息传递。
连接到总线的器件具有不同的地址,CPU根据不同的地址进行识别,从而实现对硬件系统简单灵活的控制。
一个典型的I2C总线应用系统的组成结构如下图所示(假设图中的微控制器、LCD驱动、E2PROM、ADC各器件都是具有I2C总线接口的器件):我们知道单片机串行通讯的发送和接收一般都各用一条线TXD和RXD,而I2C总线的数据线既可以发送也可以接受,工作方式可以通过软件设置。
所以,I2C总线结构的硬件结构非常简洁。
当某器件向总线上发送信息时,它就是发送器,而当其从总线上接收信息时,又成为接收器。
(三)、I2C总线上的数据传送下面我们看看I2C总线是如何进行数据传送的。
我们知道,在一根数据线上传送数据时必须一位一位的进行,所以我们首先研究位传送。
1、位传输I2C总线每传送一位数据必须有一个时钟脉冲。
被传送的数据在时钟SCL的高电平期间保持稳定,只有在SCL低电平期间才能够改变,示意图如下图所示,在标准模式下,高低电平宽度必须不小于4.7us。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
E2PR0M 芯片24C02的读写程序一、实验目的:给24C02的内部RAM写入一组数据,数据从24C02内部RAM的01h开始存放。
然后再把这组数据读出来,检验写入和读出是否正确。
在这里我们给24C02中写入0、1、2的段码,然后把它读出来,送到数码管显示。
二、理论知识准备:上面两个实验主要学习的是利用单片机的串口进行通讯,本实验要介绍的是基于I2C总线的串行通讯方法,下面我们先介绍一下I2C总线的相关理论知识。
(—)、I2C总线概念I2C总线是一种双向二线制总线,它的结构简单,可靠性和抗干扰性能好。
目前很多公司都推出了基于I2C总线的外围器件,例如我们学习板上的24C02芯片,就是一个带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,方便进行数据的长期保存。
(二)、I2C总线结构I2C总线结构很简单,只有两条线,包括一条数据线(SDA)和一条串行时钟线(SCL )。
具有I2C 接口的器件可以通过这两根线接到总线上,进行相互之间的信息传递。
连接到总线的器件具有不同的地址,CPU根据不同的地址进行识别,从而实现对硬件系统简单灵活的控制。
一个典型的I2C总线应用系统的组成结构如下图所示(假设图中的微控制器、LCD驱动、E2PROM、ADC各器件都是具有I2C总线接口的器件):SDASCL|| || || ||微控制器LCD驱动ADC E2PR0M 我们知道单片机串行通讯的发送和接收一般都各用一条线TXD和RXD,而I2C总线的数据线既可以发送也可以接受,工作方式可以通过软件设置。
所以,I2C总线结构的硬件结构非常简洁。
当某器件向总线上发送信息时,它就是发送器,而当其从总线上接收信息时,又成为接收器。
(三)、I2C总线上的数据传送下面我们看看I2C总线是如何进行数据传送的。
我们知道,在一根数据线上传送数据时必须一位一位的进行,所以我们首先研究位传送。
1、位传输I2C总线每传送一位数据必须有一个时钟脉冲。
被传送的数据在时钟SCL的高电平期间保持稳定,只有在SCL低电平期间才能够改变,示意图如下图所示,在标准模式下,高低电平宽度必须不小于 4.7us。
数据有效 改变那么是不是所有I2C 总线中的信号都必须符合上述的有效性呢?只有两个例外, 就是开始和停止信号。
开始信号:当SCL 为高电平时,SDA 发生从高到低的跳变,就定义为开始信号。
停止信号:当SCL 为高电平时,SDA 发生从低到高的跳变,就定义为结束信号。
开始和结束信号的时序图如下图所示:停止信号2、 数据传输的字节格式SDA 传送数据是以字节为单位进行的。
每个字节必须是8位,但是传输的字节数量不受限制,首先传送的是数据的最高位。
每次传送一个字节完毕, 必须接收到从机发出的一个应答 位,才能开始下一个字节的传输。
如果没有接受到应答位, 主机则产生一个停止条件结束本 次的传送。
那么从机应该发出什么信号算是产生了应答呢?这个过程是这样的。
当主器件传送一个字节后,在第 9个SCL 时钟内置高SDA 线,而从器件的响应信号将 SDA 拉低,从 而给出一个应答位。
好啦,了解了 I2C 传输数据的格式,现在来研究双方传送的协议问题。
3、 I2C 数据传输协议 I2C 总线的数据传输协议如下: (1 )、主器件发出开始信号(2) 、主器件发出第一个字节, 用来选通相应的从器件。
其中前7位为地址码,第8位为方 向位(R/W )。
方向位为“0”示发送,方向位为 “ 1”示接受。
(3) 、从机产生应答信号,进入下一个传送周期, 如果从器件没有给出应答信号, 此时主器 件产生一个结束信号使得传送结束,传送数据无效。
(4) 、接下来主、从器件正式进行数据的传送,这时在I2C 总线上每次传送的数据字节数不 限,但每一个字节必须为 8位(传送的时候先送高位,再送低位)。
当一个字节传送完毕时, 再发送一个应答位(第9位),如上一条所述,这样每次传送一个字节都需要 9个时钟脉冲。
数据的传送过程如下图所示:开始信号SL>ASCL从机拉低SDA 产生应答信号/二「二:x(四八24C02芯片相关介绍AT24C02是带有I2C 总线接口的E2PROM 存储器,具有掉电记忆的功能,并且可以象普通 RAM 一样用程序改写。
它的容量是256个字节(00h 〜0ffh ),有A2、A1、A0三位地址,可见I2C 总线上可以连接 8片AT24C02 ,它的寻址字节是 1010 A2A1A0 R/W 。
板上面24C02 的电路连接如图所示:我们对引脚的功能作一个简单的解释:VCC , GND :电源、地引脚 A2A1A0 :地址引脚 SCLK 、SDA :通信引脚 WP :写保护引脚从上面的电路连接知:A2A1A0=000,可见如果要对 24C02进行写操作,寻址字节是1010 000 0;如果对24C02进行读操作,寻址字节是1010 000 1。
用单片机的P1.6脚作为串行时钟线, 用P1.7脚作串行数据线。
(五)、程序分析写过程:(1 )、主机首先发出开始信号(2) 、发出写24C02的寻址字节1010 000 0,即0A0H (3) 、发数据写入24C02的地址,本例中为 01H(4) 、往24C02中写入数据,这里是 3个字节,分别为 48h ,0ebh , 52h 。
(5 )、写完毕发出停止信号 读过程: (1)、主机发出 start 信号(2)、发写 24C02 的寻址字节 1010 000 0 (大家可能要问:我们是读数据,为什么要发写信号SDASCL开始信号\/W7\_yi\_/卜时钟为M 〜丁\/A /?\数据 应答儘停止信号AGVCC Al WP A2 SCLK GXDSDA2K.7.e /5c 43_2「 £F ■r ■一T -「4 s D- p p p p p pCAT2-WCCZc c I 「4 d 4 s, A---. p p p p □- p pP3.4.TCP3 S TI pm «.WRP3-7.5D呢?这是因为你首先要送出一个信号,说明从24C02 中的哪个地址读取数据。
)(3)、发要读取的数据在24C02 中的地址,即01h(4)、主机发start 信号(5)、发读24C02 的寻址字节1010 000 1(5)、从24 C02 中读取数据(6)、读取完毕发出停止信号在这个程序中,我们把开始信号,结束信号、写一个字节数据、读一个字节数据都编制成为通用的子程序,便于在程序中随时调用。
发送和接受应答位的过程放到子程序中,这样可以使得程序结构简化。
具体的程序如下所示,希望大家认真理解。
三、实验程序Org 0000hI2cdata equ 30h;发送数据缓冲区的首址2402data equ 01h;接受缓冲区首址numdata equ 03h;传送的字节数,传送3 个字节Sda bit p1.7Scl bit p1.6Ajmp mainMain: Lcall init ;初始化给30h,31h,32h 中存入0,1,2的段码Mainwr: Lcall start ;启动Mov r7,#0a0hLcall send ;发送写24C02 的寻址字节Mov r7,#2402dataLcall send ;发送数据存入24C02 的地址Mov r5,#Numdata ;欲发送的字节数Mov r0,#i2cdata ;发送缓冲区的首址wrloop: Mov a,@r0Mov r7,aInc r0Lcall sendDjnz r5, wrloop ;把3 个字节的数据发送出去lcall stop ;停止lcall d1smov r5,#Numdata ;要读取的字节数重新赋值Mainre: lcall start ;启动Mov r7,#0a0hLcall send ;发送写24C02 的寻址字节Mov r7,#2402dataLcall send ;发接受缓冲区首址Lcall start ;再次启动Mov r7,#0a1hLcall send ;发送读24C02 的寻址字节Reloop: Lcall read ;调用读取一个字节数据的子程序mov p0,r7 ;把读进来的数送到p0 口显示lcall d1slcall d1sDjnz r5,reloopLcall stop;3 字节读取完毕发出停止信号Ajmp $init: mov p2,#0ffh ;初始化,30h、31h、32h 中存入0、1、2的段码mov 30h,#48h mov 31h,#0ebhmov 32h,#52hretstart: setb sda ;启动信号子程序,大家可以参考开始信号的时序图setb scl lcall d5u clr sda lcall d5uclr sclretstop: clr sda ;停止信号子程序setb scllcall d5usetb sda lcall d5u clr sda clr scl ret;send 是发送一个字节子程序send: mov r6,#08hmov a,r7 ;要发送的数在r7 中sendlop1 : rlc a ;左环移,把A 的最高位移入cy mov sda,c;把cy 的值通过sda 发送出去setb scl;在scl 上产生一个时钟lcall d5u clr scl djnz r6, sendlop1 ;重复8 次,发送一个字节;cack 是检查应答信号的子程序cack: setb sda ;主机首先拉高sdasetb scl ;发出一个时钟lcall d5usendlop2:mov c,sda ; 读入sda的状态,如果是0表示接受到了应答jc sendlop2 clr scl ;接受到应答位,结束时钟retread: mov r6,#08h;读取一个字节子程序readlop1: setb sda ;置sda 为输入方式setb scl ;发出一个时钟lcall d5umov c,sda ; 读入sda状态rlc a ;把该位的状态移入A 中clr scl ;结束时钟djnz r6,readlop1 ;重复8 次,读入一个字节mov r7,a;读进来的数放在r7 中;sack 是发送应答位子程序sack: clr sda; 拉低sda线setb scl ;发出时钟信号lcall d5uclr sclsetb sdaretd5u: nop ;延时5us 子程序nopnopnopnopretd1s: del1: del2:mov r1,#100 ; 延时1s子程序mov r4,#20mov r3,#0ffhdel3:djnz r3,del3 djnz r4,del2 djnzr1,del1 ret end大家把这个程序下载到测试板上面,发现数码管依次显示数字0、1、2。