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() {
- 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。