AT24C02EEPROM读写程序
I2C总线AT24C02存储器读写程序
write_byte(date);//在芯片第address位置写date.
respons();//写完后调用应答函数
stop();//I2C结束时钟函数
}
uchar read_add(uchar address)
{
uchar date;
{ start();//I2C开始时钟函数
write_byte(0xa0);//at24c02的固定地址A,1010,AO-A3都接地都为0。
respons();//写完后调用应答函数
write_byte(address);//确定从at24c02的第address位置写数据。
aa=k;
ee=aa*2200;
if(D4==0)
{
delay (100);
if(D4==1)
{
aa++;
delay (1);
init();//写直址,最后低位应为0。
write_add(2,aa);//23为at24c02内部储存地址,0xaa为写到23地址的数据。
#include <reg52.h>
#define uint unsigned int //定义unsigned int 为uint
#define uchar unsigned char //定义unsigned char 为uchar
#define uchar unsigned char //定义unsigned char 为uchar
delay (1);
k=read_add(2);//送到P1口显示。//从23地址读数据
24c02读写程序大全
24c02读写程序大全2C总线的应用(24C02子程序)// 对24C02的读、写// extern void DelayMs(unsigned int);// extern void Read24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);// extern void Write24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);/***************************************************************************/#define WriteDeviceAddress 0xa0#define ReadDviceAddress 0xa1#include <reg52.h>#include <stdio.h>#include <absacc.h>/***************************************************************************/sbit SCL=P2^7;sbit SDA=P2^6;bit DOG;/***************************************************************************/void DelayMs(unsigned int number) {unsigned char temp;for(;number!=0;number--,DOG=!DOG) {for(temp=112;temp!=0;temp--) {}}}/***************************************************************************/void Start() {SDA=1;SCL=1;SDA=0;SCL=0;}/***************************************************************************/void Stop() {SCL=0;SDA=0;SDA=1;}/***************************************************************************/void Ack() {SDA=0;SCL=1;SCL=0;SDA=1;}/***************************************************************************/void NoAck() {SDA=1;SCL=1;SCL=0;}/***************************************************************************/bit TestAck() {bit ErrorBit;SDA=1;SCL=1;ErrorBit=SDA;SCL=0;return(ErrorBit);}/***************************************************************************/void Write8Bit(unsigned char input) {unsigned char temp;for(temp=8;temp!=0;temp--) {SDA=(bit)(input&0x80);SCL=1;SCL=0;input=input<<1;}}/***************************************************************************/void Write24c02(unsigned char *Wdata,unsigned char RomAddress,unsign ed char number) {Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();for(;number!=0;number--) {Write8Bit(*Wdata);TestAck();Wdata++;}Stop();DelayMs(10);}/***************************************************************************/ unsigned char 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);}/***************************************************************************/void Read24c02(unsigned char *RamAddress,unsigned char RomAddress, unsigned char bytes) {//unsigned char temp,rbyte;Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start();Write8Bit(ReadDviceAddress);TestAck();while(bytes!=1) {*RamAddress=Read8Bit();RamAddress++;bytes--;}*RamAddress=Read8Bit();NoAck();Stop();}[单片机应用]24c02的读写程序电子工匠发表于2007-1-4 22:33:07;---------------从24C02整组读数据RD_INI: LCALL DELAYRD_AREA: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITE ;24C02信息的读入LCALL DELAYLCALL ACKLCALL DELAYJC RD_AREAMOV R2, #8CLR P1.7 ;起始地址为00 ADDR_0: LCALL DELAYLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, ADDR_0LCALL ACKLCALL DELAYJC RD_AREALCALL DELAYLCALL STARTMOV R0, #SAVE0MOV R3, #8 ;6个字节LCALL DELAYLCALL READLCALL DELAYLCALL ACKJC RD_AREARD_R_0: LCALL DELAYLCALL DELAYLCALL RD_INFOLCALL DELAYINC R0DJNZ R3, RD_R_1lcall ack_2lcall delayLCALL STOPRETrd_r_1: lcall ack_1sjmp rd_r_0;---------------向24C02整组写数据WR_INI: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITELCALL DELAYLCALL ACKLCALL DELAYJC WR_INICLR P1.7MOV R2, #8WR_W_0: LCALL DELAY ;写地址SETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_W_0LCALL DELAYLCALL ACKLCALL DELAYJC WR_INIMOV R0, #SAVE0MOV R3, #8 ;6个字节WR_W_1: LCALL WR_INFOLCALL DELAYLCALL ACKLCALL DELAYJC WR_INIINC R0DJNZ R3, WR_W_1LCALL DELAYLCALL STOPRET;---------------24C02启动START: SETB P1.7SETB P1.6LCALL DELAYCLR P1.7LCALL DELAYCLR P1.6RET;---------------24C02读命令字;片选为"00";---------------------------- READ: MOV A, #10100001B MOV R2, #8RD1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, RD1RET;---------------24C02写命令字;片选为"00";---------------------------- WRITE: MOV A, #10100000B MOV R2, #8WR1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6CLR P1.7LCALL DELAYDJNZ R2, WR1RET;---------------24C02结束命令字STOP: CLR P1.7LCALL DELAYSETB P1.6LCALL DELAYSETB P1.7LCALL DELAYCLR P1.6RET;---------------24C02的应答信息ACK: SETB P1.7SETB P1.6LCALL DELAYmov a, p1MOV C, a.7LCALL DELAYCLR P1.6RETack_1: CLR P1.7 ;应答SETB P1.6lcall delayCLR P1.6lcall delaySETB P1.7lcall delayRETack_2: SETB P1.7 ;非应答SETB P1.6lcall delayCLR P1.6CLR P1.7lcall delayRET;---------------24C02的读;R0:数据的存储地址;-------------------------------- RD_INFO: SETB P1.7LCALL DELAYMOV R2, #8MOV R7, #0MOV A, #0RD_I_0: SETB P1.6LCALL DELAYMOV A, P1MOV C, A.7LCALL DELAYCLR P1.6MOV A, R7RLC AMOV R7, ALCALL DELAYDJNZ R2, RD_I_0MOV @R0, ARET;---------------24C02的写;R0:数据的写数据地址;-----------------------------------WR_INFO: MOV A, @R0MOV R2, #8WR_O_0: RLC AMOV P1.7, CLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_O_0RET24Cxx I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接GND(24C65接VCC,具体看DataSheet)。
AT24C02的读写
; (R4)=片内字节地址
; (R1)=欲写数据存放地址指针
; (R7)=连续写字节数n
EEPW: MOVP1,#0FFH
CLRP1.0;发开始信号
MOVA,R3;送器件地址
ACALLSUBS
MOVA,R4;送片内字节地址
RET
;读串行E2PROM子程序EEPR
;(R1)=欲读数据存放地址指针
;; R3=10100001(命令1010+器件3位地址+读/写。器件地址一个芯片,是000)
;(R4)=片内字节地址
;(R7)=连续读字节数
EEPR: MOVP1,#0FFH
CLRP1.0;发开始信号
MOVA,R3;送器件地址
MOV DPTR,#0600H;定义源数据的位置
LOOP:MOV A,#00H
MOVC A,@A+DPTR
LCALL SDATA
LCALL ACK
JC LOOP
INC DPTR
DJNZ R2,LOOP
LCALL STOP;调用停止子程序
STAR:SETB SDA
SETB SCL
NOP
NOP
NOP
NOP
应答毕sdaret程序中多处调用了delay子程序仅两条nop指令这是为了满足i2c总线上数据传送速率的要求只有当sda数据线上的数据稳定下来之后才能进行读写即scl线发出正脉冲
AT24C02的读写
作者:来源:阅读次数:372
AT24C02是美国ATMEL公司的低功耗CMOS串行EEPROM,它是内含256×8位存储空间,具有工作电压宽(2.5~5.5V)、擦写次数多(大于10000次)、写入速度快(小于10ms)等特点。
C51编写的AT24C02详细的读写程序
C51_AT24C02读写程序:/*void start() //开始信号void stop() //停止信号void Ack() //发确认信号void NoAck() //发无确认信号void init()//初始化信号,拉高SDA和SCL两条总线bit write_byte(uchar date)//写一字节,将date 写入AT24C02 中uchar read_byte()//读一字节,从AT24C02 中读一字节bit busy() //应答查询,stop()后,启动A T24C02内部写周期,启动查询//初始化EEPROM子程序内容为0XFF,nPage(0~31)void Init_Flash(uchar nPage) //8 bytes/1 page init 0xFFvoid write_add(uchar address,uchar date)//向AT24C02 中写数据//从AT24C02中给定的地址nAddr起,将存放在以指针nContent开头的存储空间中的nLen 个字节数据,连续写入AT24C02void write_flash(uchar *nContent,uchar nAddr, uchar nLen)uchar read_add(uchar address)//从AT24C02 中读出数据//从AT24C02中给定的地址nAddr起,读取nLen个字节数据存放在以指针nContent开头的存储空间。
void read_flash(uchar *nContent,uchar nAddr, uchar nLen)*//*单片机P2口接74HC138(三八译码器)P2.3--74HC138:/EI、P2.2--74HC138:A2、P2.1--74HC138:A1、P2.0--74HC138:A0译码器输出Y0,Y1、Y2、Y3、Y4、Y5、Y6、Y7均低电平有效,分别选通1~8个数码管。
单片机程序设计实践教程_第17章_EEPROM器件AT24C02读写
4
图17-1 24C02读写项目的电路原理图 17- 24C02读写项目的电路原理图
5
17.3 系统板上硬件连线
PMY单片机开发板上24C02读写控制项目的连接插线设置如图 17-2所示。
24C02读写项目的连接插线设置 图17-2 开发板上24C02读写项目的连接插线设置 17- 开发板上24C02
3
17.2 项目任务
24C02读写控制项目的电路原理图如图17-1所示。在第17章已 经介绍过,STC89C52RC单片机本身不包含I2C总线通信控制器的 功能,为了与具有I2C总线通信和存储功能的EEPROM器件24C02 芯片进行数据交换,STC89C52RC单片机必须利用自身的两根 I/O线(这里是P14和P15引脚),作为I2C的SDA和SCL信号线,利 用 软 件 模 拟 产 生 I2C 通 信 协 议 规 定 的 传 输 数 据 信 号 , 以 完 成 与 24C02芯片之间的数据交换。 本次项目应完成以下程序设计:通过C51嵌入式软件对24C02指 定的多个连续地址写入指定数值,再读出已写入24C02器件地址的 数值,并在七段LED数码管上进行显示。
14
如何在项目中实现24C02 24C02的读写 17.6.3 如何在项目中实现24C02的读写
程序中的_24C02_WriteByte函数是向指定从地址器件的特定寄 存器地址写入一个字节数据,虽然与数字钟设计项目程序中的 PCF8563_WRINIT函数功能类似,但只是完成了向从器件传送一 个字节数据的功能。而PCF8563_WRINIT函数则完成向从器件指 定地址写入多个指定字节数据,在本项目主程序main中的以下语 句同样可以实现主器件(STC89C52RC)向指定从器件(24C02) 的指定地址连续写入多个字节的功能: /*************以下语句为向24C02写入数据*****************/ _24C02_Fillbyte(20,0xff); //将前20字节用0xff填充 for(i=0;i<16;i++) _24C02_WriteByte(i,DispDat[i]); //将数组DispDat设定的 显示代码写入到24C02 /*************以上语句为向24C02写入数据*****************/
24c02读写程序大全
CLR SCLK24
CALL START24;启动
MOV A,#0A0H
CALL SHIFT8;移位
CALL ACK;响应
POP ACC
>SETB;应答毕,SDA置1
>RET
>程序中多处调用了DELAY子程序(仅两条NOP指令),这是为了满足I2C总线上数据传
送速率的要求,只有当SDA数据线上的数据稳定下来之后才能进行读写(即SCL线发出正
脉冲)。另外,在读最后一数据字节时,置应答信号为“1”,表示读操作即将完成。
>
>下面是本人编写的源程序,已经调试成功,下载就可以使用,程序编写的不是很规范
>ACALL SUBS
>MORE: ACALL SUBR
>MOV@R1,A
>INCR1
>DJNZ R7,MORE
>CLR
>ACALL DELAY
>SETB
>ACALL DELAY
>SETB;送停止信号
>RET
>SUBR: MOVR0,#08H ;接受单字节子程序
>LOOP2: SETB
>ACALL DELAY
TT2:MOV30H,A
MOVCA,@A+DPTR
CLR;开数码管
MOVP0,A;送显示
MOVA,30H
INCA
MOVB,A
MOVA,#00H
LCALLWT24
AJMP$
TAB:DB28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H
RD24: 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读写程序
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程序
按下4×4键盘任意一个键,记下数码管显示的值。
复位单片机后数码管显示刚才显示的值学习IIC接口的EEPROM读写:IIC接口的时序比较复杂,对初学者难度较大,要对照at24c02资料的时序图认真研究才明白*/#include<reg51.h>sbit speaker=P3^7;sbit led_k=P1^4;/////////////////键盘sbit v1=P2^0;sbit v2=P2^1;sbit v3=P2^2;sbit v4=P2^3;sbit h1=P2^4;sbit h2=P2^5;sbit h3=P2^6;sbit h4=P2^7;/////////////////显示sbit shu1=P1^3;/*第1位数码管共阴端*/sbit shu2=P1^2;/*第2位数码管共阴端*/sbit shu3=P1^1;/*第3位数码管共阴端*/sbit shu4=P1^0;/*第4位数码管共阴端*/////////////////24c02sbit sda=P1^6;sbit scl=P1^5;void start();void delay1();unsigned int read(unsigned int word_address);void write(unsigned int word_address,da);void delayms(unsigned int i);unsigned char yima[]={0xeb,0x88,0xb3,0xba,0xd8,0x7a,0x7b,0xa8,0xfb,0xfa};/*译码表,此表数据和硬件相关*/unsigned int b=0;/*要显示的数据*/unsigned int b_count=0;/*扫描次数*/void delayms(unsigned int i);unsigned char keyboar();void t0()interrupt 1 using 1 /*中断程序负责显示b的值*/{unsigned char a1=0,a2=0,a3=0,a4=0;static int k=0;/*数码管扫描显示*/a1=b/1000;/*取b的千位*/a2=b%1000/100;/*取b的百位*/a3=b%100/10;/*取b的十位*/a4=b%10;/*取b的个位*/if(k==0){shu4=1;shu1=0;shu2=0;shu3=0;P0=yima[a1];}else if(k==1){shu4=0;shu1=1;shu2=0;shu3=0;P0=yima[a4];}else if(k==2){shu4=0;shu1=0;shu2=1;shu3=0;P0=yima[a3];}else if(k==3){shu4=0;shu1=0;shu2=0;shu3=1;P0=yima[a2];}k++;if(k>3)k=0;TH0=240;}main(){//write(1,60);unsigned char b_tem;b=read(1); //读取eeprom地址为1的数据并赋值给b,定时中断程序把b显示在数码管speaker=0;/*关闭蜂鸣器电源,否则蜂鸣器会发热*/led_k=0;//关闭ledEA=1;/*开全局中断*/TR0=1;/*定时器0开始计数*/ET0=1;/*定时器0开中断*/TMOD=0X01;/*定时器0工作在方式1:16位计数模式*/while(0){}while(1){b_tem=keyboar();/*把按键的代表的值给b */if(b_tem<17){if(b!=b_tem) //当按下的按键与上次按下的不同时,执行写EERPOM。
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_();}。
AT24C02页读写程序
for(i=0;i<8;i++)
{
if(Order&0x80)
SID_set;
else
SID_clr;
CLK_clr;
CLK_set;
Order<<=1;
}
Order=Data;
Order<<=4;
for(i=0;i<8;i++)
{
if(Order&0x80)
SID_set;
{
uchar Value;
IIC_Start();
AT24C02_Send_Byte(Slave_Addr);
AT24C02_Send_Byte(Addr);
IIC_Start();
AT24C02_Send_Byte(Slave_Addr+1);
Value=AT24C02_Rec_Byte();
IIC_SendAck(1);
{
IIC_Start();
AT24C02_Send_Byte(Slave_Addr);
AT24C02_Send_Byte(Address);
AT24C02_Send_Byte(Dat);
IIC_Stop();
}
/*单字节读AT24C02*/
uchar Single_Read_AT24C02(uchar Slave_Addr,uchar Addr)
/*接收应答信号*/
uchar IIC_RecAck(void)
{
uchar A;
SDA_in;
SCL_set;
Delay(35);
if(PINC & (1<<4))
DSP实践讲解-11 EEPROM 24C02读写实验
Digital Signal Processor 数字信号处理器
光华学院 信息工程系 王 超
GPIO应用之EEPROM
IIC 总线
IIC 总线
IIC 总线术语:
数据的有效性
起始和停止条件
传输数据
传输数据
AT24C02
AT24C02连接原理图
AT24C02
IIC总线AT24C02实验
IIC总线AT24C02实验
IIC总线AT24C02实验
IIC总线AT24C02实验
IIC总线AT24C02实验
IIC总线AT24C02实验
设置数据=1 设置时钟=1,稳定 设置数据为输入模式 设置时钟=0,可变 设置数据为输出模式 返回”真”/”假”
IIC总线AT24C02实验
设置数据输出 数据输出=1 时钟输出=1,稳定 读数据? 时钟输出=1,可变
Data是1变量的地址, *Data是指向这个变量地址下的内容.1.
前n-1次数据读,有应答! 最后1次数据读,主机无应答!
读数据n-1个,有应答, 第n个数据无应答.
IIC总线AT24C02实验
Temp=地址,w_data=写入数据,erro=错误,r_data读数据
END
0,1,2,3,4地址下写入17,18,19,20,21
读0,1,2,3,4地址下内容是否为 17,18,19,20,21,5次全读对则erro=0. unsigned char w_buffer[8]={23,18,18,20,32,25,28,29}; unsigned char r_buffer[8]={0};
24C02(IIC)读写操作
1. AT24C02写操作首先我们来看一下写AT24C02。
一般步骤是:1) 发送起始信号2) 发送写器件地址3) 等待应答4) 发送要写入的24C02 的地址5) 等待应答6) 发送要写入的数据7) 等待应答8) 发送数据结束发送结束信号具体程序如下:/****************************************************************************** ** 函数名: AT24Cxx_WriteOneByte* 函数功能: 24c02写一个字节地址数据* 输入: addr dt* 输出: 无********************************************/void AT24Cxx_WriteOneByte(u16 addr,u8 dt){I2C_Start();if(EE_TYPE>AT24C16){I2C_Send_Byte(0xA0);I2C_Wait_Ack();I2C_Send_Byte(addr>>8); //发送数据地址高位}else{I2C_Send_Byte(0xA0+((addr/256)<<1));//器件地址+数据地址}I2C_Wait_Ack();I2C_Send_Byte(addr%256);//双字节是数据地址低位//单字节是数据地址低位I2C_Wait_Ack();I2C_Send_Byte(dt);I2C_Wait_Ack();I2C_Stop();delay_ms(10);}2. AT24C02读操作那么读取AT24C02 的步骤是:1)发送起始信号2) 发送写器件地址3) 等待应答4) 发送要读取的AT24C02 的地址5) 等待应答6) 再发送其实信号7) 发送读器件地址8) 等待应答9) 接收数据10) 如果没有接收完数据,发送应答11) 接收数据12) 直到接收完数据,发送非应答13) 发送结束信号/****************************************************************************** ** 函数名: AT24Cxx_ReadOneByte* 函数功能: 24c02读一个字节地址数据* 输入: addr* 输出: 返回值temp*****************************************************************************/ u8 AT24Cxx_ReadOneByte(u16 addr){u8 temp=0;I2C_Start();if(EE_TYPE>AT24C16){I2C_Send_Byte(0xA0);I2C_Wait_Ack();I2C_Send_Byte(addr>>8); //发送数据地址高位}else{I2C_Send_Byte(0xA0+((addr/256)<<1));//器件地址+数据地址}I2C_Wait_Ack();I2C_Send_Byte(addr%256);//双字节是数据地址低位//单字节是数据地址低位I2C_Wait_Ack();I2C_Start();I2C_Send_Byte(0xA1);I2C_Wait_Ack();temp=I2C_Read_Byte(0); // 0 代表NAC I2C_NAck();I2C_Stop();return temp;}。
(单片机设计)AT24C02的读写程序
AT24C02的读写程序24C02 read / write process 关键字:AT24C02的读写程序AT24C02的读写程序#include#include#include "INTRINS.H"#define uchar unsigned char#define _NOP_() _nop_()/***************************************************************************/#define WriteDeviceAddress 0xa0 /*24c02的写地址*/#define ReadDviceAddress 0xa1 /*24c02的读地址*//***************************************************************************/sbit SCL=P1^6;sbit SDA=P1^7;sbit P1_5=P1^5;sbit P1_4=P1^4;sbit P1_3=P1^3;sbit P1_2=P1^2;unsigned char code table[]={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};unsigned char table1[8];/*********************延时程序*******************************************/void DelayMs(unsigned int number) {unsigned char temp;for(;number!=0;number--){for(temp=112;temp!=0;temp--);}}/******************************************************************************************************24c02开始程序***************************************************************************************************************/void Start(){SDA=1;SCL=1;SDA=0;SCL=0;}/******************************************************************************************************24c02停止程序************************************ ***************************************************************************/ void Stop(){SCL=0;SDA=0;SCL=1;SDA=1;}/***************************************************************************/ void Ack(){SDA=0;SCL=1;SCL=0;SDA=1;}/***************************************************************************/ void NoAck(){SDA=1;SCL=1;SCL=0;}/*************************************************************************** *返回错误标志,ErrorBit=SDA,为1错误,0正确********************************* ***************************************************************************/ bit TestAck(){bit ErrorBit;SDA=1;SCL=1;ErrorBit=SDA;SCL=0;return(ErrorBit);}/*************************************************************************** ***************************24c02写一个字节程序****************************** ***************************************************************************/ void Write8Bit(unsigned char input){unsigned char temp;for(temp=8;temp!=0;temp--){SDA=(bit)(input&0x80);/*从高位依次取input的各位*/SCL=1;SCL=0;input=input<<1; /*相等与RLC,取了CY位*/}}/******************************************************************************************************24c02写程序*****************************************************************************************************************/void Write24c02(unsigned char *Wdata,unsigned char RomAddress,unsigned char number) { /*Wdata对准要写的数据的首地址 RomAddress单元地址 number几个Byte*/ Start();/*IIC开始*/Write8Bit(WriteDeviceAddress);/*写入器件地址0xa0*/TestAck();/*测试ACK位*/Write8Bit(RomAddress);/*写入器件控制单元地址*/TestAck();/*测试ACK位*/for(;number!=0;number--){Write8Bit(*Wdata);TestAck();Wdata++;}Stop();/*IIC停止*/DelayMs(10);/*延长10MS,保证数据写入*/}/******************************************************************************************************24c02读一个字节程序*********************************************************************************************************/ unsigned char Read8Bit(){unsigned char temp,rbyte=0;for(temp=8;temp!=0;temp--){SCL=1;rbyte=rbyte<<1;rbyte=rbyte|((unsigned char)(SDA));SCL=0;}/* for(temp=8;temp!=0;temp--){SCL=1;rbyte=rbyte<<1;if(SDA==1)rbyte=rbyte|0x01;SCL=0;} */return(rbyte); /*把数据返回*/}/******************************************************************************************************24c02读程序*****************************************************************************************************************/void Read24c02(unsigned char *RamAddress,unsigned char RomAddress,unsigned char bytes) {/*unsigned char temp,rbyte;*/Start(); /*IIC开始*/Write8Bit(WriteDeviceAddress);/*写入器件地址0xa0*/TestAck();/*测试ACK位*/Write8Bit(RomAddress);/*写入器件控制单元地址*/TestAck();/*测试ACK位*/Start();/*IIC再次发送开始*/Write8Bit(ReadDviceAddress);TestAck();/*测试ACK位*/while(bytes!=1){*RamAddress=Read8Bit();/*存一个读到的数据到RamAddress+I*/Ack();/*发送IIC再读*/RamAddress++;/*存取地址加一*/bytes--;}*RamAddress=Read8Bit();NoAck();/*发送IIC停止读*/Stop();/*IIC停止*/}/***************************************************************************/。
单片机对存储器AT24C02页读,写程序
/****************************************************************************** 定义控制存储器操作的程序******************************************************************************/ 这是自己写的程序,已经经过验证,细节要求的地方,参考一下AT24CXX数据手册即可#include <intrins.h>#include "AT89S52_reg.h"#include "Delay.h"sbit SDA = P3^6;sbit SCL = P3^7;/*********************************初始化存储器子程序*********************************/void InitMemory(void){SCL = 1;flash();SDA = 1;flash();}/*********************************I2C总线短延时子程序*********************************/static void flash(){_nop_();_nop_();_nop_();_nop_();_nop_(); /时序图要求开始建立时间tSU.STA大于4.7us,开始保持时间tHD.STA大于4us。
51中每个_nop_ ();延时1个CPU cycle,即1us}/*********************************启动I2C总线子程序*********************************/static void Start(void){SDA = 1;flash();SCL = 1;SDA = 0;flash();SCL = 0;flash();}/*********************************停止I2C总线子程序*********************************/static void Stop(void){SDA = 0;flash();SCL = 1;flash();SDA = 1;flash();}/******************************************** 写一字节子程序********************************************/ static void Mmr_SendByte(unsigned char byte){unsigned char i, temp;temp = byte;for (i=0; i<8; i++){temp <<= 1;SCL = 0;flash();SDA = CY;flash();SCL = 1;flash();}SCL = 0;flash();SDA = 1;flash();i = 0;flash();while ((SDA==1) && (i<255)){i++;}SCL = 0;flash();}/**************************************读一字节子程序**************************************/static unsigned char Mmr_GetByte(void){unsigned char i;unsigned char byte;SCL = 0;flash();SDA = 1;for (i=0; i<8; i++){byte <<= 1;flash();SCL = 1;flash();if (SDA == 1){byte |= 0x01;}SCL = 0;}flash();SDA = 0;SCL = 1;flash();SCL = 0;flash();SDA = 1;flash();return(byte);}/*********************************************************************从存储器指定地址中读取n个字节数据子程序(页读)*********************************************************************/void ReadMemory(unsigned char addr, unsigned char *p, unsigned char n) reentrant//addr 为数据开始地址*p为指向所需写入数据数组的指针n为个数,因不同存储器而不同这个可以参见数据手册{Start();Mmr_SendByte(0xA0); // 写入数据指令Mmr_SendByte(addr); // 写入读取数据的地址Start();Mmr_SendByte(0xA1); // 读取数据指令while(n--){*p = Mmr_GetByte();p++;}Stop();Delayms(2);}/**********************************************************************写存储器指定地址中写入n个字节数据子程序(页写)**********************************************************************/void WriteMemory(unsigned char addr, unsigned char *p, unsigned char n) reentrant{EA = 0;Start();Mmr_SendByte(0xA0);Mmr_SendByte(addr);while(n--){Mmr_SendByte(*p);p++;}Stop();EA = 1;Delayms(10);}。
STM32作为主机I2C,读写24C02EEPROM
STM32作为主机I2C,读写24C02EEPROM1、时钟和数据的传输:开始和停止条件,数据在SCL的高电平期间有效,在SCL的低电平期间改变。
2、开始条件:在SCL高电平期间,SDA产生一个下降沿3、停止条件:在SCL高电平期间,SDA产生一个上升沿4、应答:成功接收到数据(地址和数据),产生一个应答位(在第9个时钟周期,将SDA拉低)下面是源程序:原理上说,下面程序再移植时,只要将数据类型变化,可以应用到任何处理器AT24c02.h#ifndef __24CXX_H#define __24CXX_H#include "i2c.h"/************************************************************** *- 说明:以下参数是AT24Cxx的寻址空间,C0x ,X 表示XK 如C01表示1K- 127表示2^7 1Kbit/8=128Byte 128字节- 255表示2^8 2Kbit/8=256Byte 256字节- 512表示2^9 4Kbit/8=512Byte 512字节-*************************************************************** /#define AT24C01 127#define AT24C02 255#define AT24C04 511#define AT24C08 1023#define AT24C16 2047#define AT24C32 4095#define AT24C64 8191#define AT24C128 16383#define AT24C256 32767/************************************************************** --板子使用的是24c02,所以定义EE_TYPE为AT24C02**************************************************************/ #define EE_TYPE AT24C02/************************************************************** --EEPROM的操作函数--24CXX驱动函数**************************************************************/u8 AT24CXX_ReadOneByte(u16 ReadAddr); //指定地址读取一个字节void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite); //指定地址写入一个字节void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//指定地址开始写入指定长度的数据u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len); //指定地址开始读取指定长度数据void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite); //从指定地址开始写入指定长度的数据void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead); //从指定地址开始读出指定长度的数据u8 AT24CXX_Check(void); //检查器件void AT24CXX_Init(void); //初始化IIC#endif----------------------------------------------------------------------------------------------------------------------------------------- AT24c02.c#include "at24cxx.h"#include "delay.h"/************************************************************** *************- 功能描述:STM32f103 EEPORM初始化函数- 隶属模块:STM32 EEPROM操作- 函数属性:外部,使用户使用- 参数说明:无- 返回说明:无- 函数功能:实现I2C的初始化。
实战24C02读写
实战24C02读写AT24C02是美国ATMEL公司的低功耗CMOS串行EEPROM,它是内含256×8位存储空间,具有工作电压宽(2.5~5.5V)、擦写次数多(大于10000次)、写入速度快(小于10ms)等特点。
24C02与单片机的联接参见原理图 ,读写程序如下,运行此程序,可以看到其中之一数码管循环显示0,1,2,3,4,5,6,7,8,9的效果。
其根本是,先往24C02中写数据,然后,读出数据,在数码管中显示,这样直观明了,详细说明,请看程序中注解。
此程序是针对24c02的,其实,可以扩展来其他i2c的eeprom.这由你们来完成吧。
#include <at89x51.h>#include <intrins.h> //此文件中有_nop_()空操作函数#define uchar unsigned char#define uint unsigned int#define OP_READ 0xa1 // 器件地址以及读取操作#define OP_WRITE 0xa0 // 器件地址以及写入操作uchar code display[10]={0x28,0xEB,0x32,0xA2,0xE1,0xA4,0x24,0xEA,0x20,0xA0};//数码管0,1,2,3,4,5,6,7,8,9的编码sbit SDA = P2^0; //位定义sbit SCL = P2^1; //位定义void LED_display(uchar i);//数码管显示编码获取函数,例如,i=0,则P0=display[0],即显示数字“0”void start();//开始位void stop();//停止位uchar shin();//从AT24C02移入数据到MCUbit shout(uchar write_data);//从MCU移出数据到AT24C02void write_byte( uchar addr, uchar write_data); //在指定地址addr处写入数据write_datavoid fill_byte(uchar fill_size,uchar fill_data);//填充数据fill_data到EEPROM内fill_size字节void delayms(uchar ms); // 延时子程序uchar read_current(); // 在当前地址读取uchar read_random(uchar random_addr);// 在指定地址读取void LED_display(uchar i){P0 = display[i];}main(void){uchar i;uint j;SDA = 1;SCL = 1;fill_byte(11,0xff); // 将前10字节填充0xfffor(i = 0 ; i < 10; i++) //写入显示代码到AT24C02{write_byte(i, i);P2_7 = 0; //打开数码管1的显示for(i =0 ;i <10 ; i++){LED_display(read_random(i));for (j = 0; j<35000;j++);//延时}}void start()//开始位{SDA = 1;SCL = 1;_nop_();_nop_();SDA = 0;_nop_();_nop_();_nop_();_nop_();SCL = 0;}void stop()// 停止位{SDA = 0;_nop_();_nop_();SCL = 1;_nop_();_nop_();_nop_();_nop_();SDA = 1;}uchar shin()// 从AT24C02移入数据到MCU {uchar i,read_data;for(i = 0; i < 8; i++){SCL = 1;read_data <<= 1;read_data |= (uchar)SDA;SCL = 0;return(read_data);}bit shout(uchar write_data)// 从MCU移出数据到AT24C02{uchar i;bit ack_bit;for(i = 0; i < 8; i++) // 循环移入8个位{SDA = (bit)(write_data & 0x80);_nop_();SCL = 1;_nop_();_nop_();SCL = 0;write_data <<= 1;}SDA = 1; // 读取应答_nop_();_nop_();SCL = 1;_nop_();_nop_();_nop_();_nop_();ack_bit = SDA;SCL = 0;return ack_bit; // 返回AT24C02应答位}void write_byte(uchar addr, uchar write_data)// 在指定地址addr处写入数据write_data{start();shout(OP_WRITE);shout(addr);shout(write_data);stop();delayms(10); // 写入周期}void fill_byte(uchar fill_size,uchar fill_data)// 填充数据fill_data到EEPROM内fill_size字节{uchar i;for(i = 0; i < fill_size; i++){write_byte(i, fill_data);}}uchar read_current()// 在当前地址读取{uchar read_data;start();shout(OP_READ);read_data = shin();stop();return read_data;}uchar read_random(uchar random_addr) // 在指定地址读取{start();shout(OP_WRITE);shout(random_addr);return(read_current());}void delayms(uchar ms)// 延时子程序{uchar i;while(ms--){for(i = 0; i < 120; i++);}}。
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的读写操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
;--------------------------------------------------------------------------------------------------------------------- ;本程序是针对AT89S52单片机编制的EEPROM读写程序(2013.8.4测试通过);本程序在4MHZ、12MHZ和24MHZ分别测试通过;AT24C02的A0、A1、A2均接GND,设备地址高7位为(1010)000;WP接GND,充许对EEPROM正常读写;本程序仅作学习交流之用。
;--------------------------------------------------------------------------------------------------------------------- SCl equ P2.0 ;SCL接A T89S52的P2.0端口,作为EEPROM的串行输入时钟SDA equ P2.1 ;SDA接AT89S52的P2.1端口,作为主机与EEPROM之间信息串行传输总线WRITEDATA equ 08H;拟写入EEPROM的数据在主机中的存贮单元地址READDATA equ 09H ;从EEPROM读取的数据存放到主机存贮单元地址EPROMADDRESS equ 0AH;拟随机读写EEPROM的存贮单元地址;------------------------------------------------ORG 00HLJMP MAIN;------------------------------------------------ORG 50HMAIN: MOV SP,#20H;防止堆栈影响已用内存数据;以下为写EEPROM过程mov EPROMADDRESS,#09H;该地址可以随意输入(00H~FFH),但读和写的地址须相同MOV WRITEDA TA,#01010010B;该数字可以随意输入,并将读和写的数据进行比较;如读数正确则按将读出数据在P1口输出,可在P1口各位分别接LED灯直观显示出来。
LCALL WRITEEEPROMR;以下为读EEPROM过程mov EPROMADDRESS,#09H;该地址可以随意输入(00H~FFH),但读和写的地址须相同LCALL READEEPROMR;以下为EEPROM读写操作验证MOV A,WRITEdataMOV B,AMOV A,READDATACJNE A,B,MAIN1MOV P1,READDATA;写入数和读出数相等时,读出的数据在P1口输出并按位分别控制LED灯直观显示sJMP $MAIN1: MOV P1,#00H;写入数和读出数相等时,LED灯全亮;以下可接其它主程序,此处暂为死循环SJMP $;--------------------------------------------------------------------------------------------------------------------- ;WRITEEEPROMR是随机写EEPROM(AT24C02)子程序;入口1:EEPROMADRESS(拟读写EEPROM存贮单元地址,00~FFH);入口2:WRITEDATA(拟写入EEPROM的字节数据在主机的存放地址);--------------------------------------------------------------------------------------------------------------------- WRITEEEPROMR:;第1步,启动EEPROM读写操作lcall startEEPROM;调用启动子程序;第2步,输入设备号和功能选择码即10100000BMOV A,#10100000B;1010是规定的,000是设备地址,最低位0表示拟执行写操作LCALL SENDDA TA;调用串行发送字节数据子程序;第3步查询EEPROM应答信号情况LCALL WAITACK;调用应答响应子程序;第四步,传送数据拟贮存地址给EEPROM的地址指针MOV A,EPROMADDRESS;将拟贮存数据的EEPROM贮存单元地址送入SENDDATA子程序的入口ALCALL SENDDA TA;第五步,查询EEPROM应答信号情况LCALL WAITACK;调用应答响应子程序;第六步,传送8位数据到EEPROM缓存区,该循环完成第二个8时序(时序1~8)MOV A,writedataLCALL SENDDA TA;第七步,查询EEPROM应信号情况,完成第三个应答时序(时序9)LCALL WAITACK;调用应答响应子程序;第五步,主器件产生一个停止信号,即在scl高位时SDA由低到高跳变信号;让EEPROM自主启动内部写周期,将EERPOM缓存区数据写入EEPROMclr sdasetb SCL;该两句有两个作用,一方面是本次EEPROM操作的停止命令,让EEPROM 启动写周期;SETB SDA;另一方面,为下一次EEPROM读写操作作好了准备,只等启动命令到来。
;第六步,延迟等待写周期完成,否则影响下一次的读写EEPROM操作。
;应根据晶振频率调整下列的延迟时间MOV R0,#0FFHDELAYLOOP: NOPNOPNOPNOPNOPNOPNOPDJNZ R0,DELAYLOOPRET;----------------------------------------------------------------------------------------------------;随机读EEPROM(A T24C02)子程序;入口:EEPROMADRESS(拟读EEPROM存贮单元地址,00~FFH);出口:READDATA(读出字节数据在主机的存放地址);---------------------------------------------------------------------------------------------------- READEEPROMR:;第1步,启动EEPROM读写操作(时序0)lcall startEEPROM;调用启动子程序(时序1~8)?;第2步,输入设备号和功能选择码即10100000BMOV A,#10100000B;1010是规定的,000是设备地址,最低位0表示拟执行写操作LCALL SENDDA TA;调用串行发送字节数据子程序;第3步查询EEPROM应答信号情况(时序9)LCALL WAITACK;调用应答响应子程序;第四步,传送数据拟贮存地址给EEPROM的地址指针(时序1~8)MOV A,EPROMADDRESS;将拟贮存数据的EEPROM贮存单元地址送入SENDDATA子程序的入口ALCALL SENDDA TA;第五步,查询EEPROM应答信号情况(时序9)LCALL WAITACK;调用应答响应子程序;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;以上五步均属于伪写操作。
;因未实际输入输出数据和写周期,其内部数据地址指针不作变化,仍指向刚输入的地址;以下实际就是立即读操作,读出数据指针所指的地址单元内容,分六个步骤:;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;(1)启动EEPROM读写操作(时序0)?lcall startEEPROM;调用启动子程序;(2)输入设备号和功能选择码即10100001B;此处R/W位(最低一位)取1,表明读操作;使用了8个SCL时钟时序(时序1~8)MOV A,#10100001BLCALL SENDDA TA;(3)查询EEPROM应答信号情况(时序9)?LCALL WAITACK;(4)EEPROM输出一个8位数据到SDA总线上,主机作接收处理,使用8个SCL 时钟时序(时序1~8)lcall receivedataMOV READDATA,A;(5)不产生应答信号,但应保留应答时序SETB sclCLR scl;(6)主机发出停止信号clr sdasetb SCL;该两句是结束时序SETB SDARET;--------------------------------------------------------------------------------------------------------------------- ;STARTEEPROM子程序:向EEPROM发出读写操作的开始信号,在一个SCL时钟时序内完成(时序0);--------------------------------------------------------------------------------------------------------------------- STARTEEPROM:SETB SCLSETB SDA;停止EEPROM操作,为下一次写作准备CLR SDA;在SCL为高电平时,SDA由高变低,发出启动信号clr scl;完成一个时钟时序RET;---------------------------------------------------------------------------------------------------------------------;SENDDATA子程序:主机向EEPROM串行发送1个字节数据;入口:约定需发送的字节数据存在A中;使用资源:A、CY、R0;--------------------------------------------------------------------------------------------------------------------- SENDDATA: ;使用8个完整的SCL时钟时序(时序0~8)MOV R0,#08HSENDDATALOOP:RLC A;带CY的A内容循环左移位,先高位后低位MOV SDA,C;将位信息送到SDA线Setb scl;在SCL上升沿将SDA信息送入EEPROM缓存区Clr sclDJNZ R0,SENDDA TALOOPRLC A;让A和CY内容恢复为入口前状态,在某些情况上很有必要。