24c02的连续读写
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)。
外部存储器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总线。
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的数据手册
首先先看AT24C02的数据手册1、24C02读写规则。
器件地址:此处将A2A1A0接地。
所以地址为0x50;最低位为读写标志位,有DSP自动发送。
2、I2C总线初始化:void InitI2C(void){InitI2CGpio();//将对应的IO口功能设置成I2C总线工作模式。
// Initialize I2CI2caRegs.I2CSAR = 0x50; // Slave address=0x00;- EEPROM control codeI2caRegs.I2CPSC.all = 9; // I2C模块时钟频率=100MHZ/(9+1)=10MHZI2caRegs.I2CCLKL = 10; //I2caRegs.I2CCLKH = 5; // SCL--Master Clock=10M/(CLKL+CLKH+10)=400k;I2caRegs.I2CIER.all = 0x2C; // Enable SCD & ARDY interruptsI2caRegs.I2CMDR.all = 0x0020; // Take I2C out of resetI2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFOI2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,}3、I2C页写子程序:对某个页面进行写8个数据。
起始地址:MemoryAddressvoid I2C_PageWrite(Uint16 MemoryAddress,Uint16 write_buffer[8]){Uint16 i;// 设置器件地址I2caRegs.I2CSAR=0x0050;// 需要发送的数据个数:=需要发送的数据个数+1个数据长度的地址I2caRegs.I2CCNT =8+1;// 第一个发送的数据:存储地址I2caRegs.I2CDXR =MemoryAddress;//接着是要发的数据。
I2C24LC02C读写例程(PIC单片机)
I2C24LC02C读写例程(PIC单片机)I2C 24LC02 C读写例程(PIC单片机)[单片机]发布时间:2008-04-22 10:11:001 I2C总线特点I2C总线最主要的优点是其简单性和有效性。
由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。
总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。
I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。
一个主控能够控制信号的传输和时钟频率。
当然,在任何时间点上只能有一个主控。
2 I2C总线工作原理I2C总线上的数据稳定规则,SCL为高电平时SDA上的数据保持稳定,SCL为低电平时允许SDA变化。
如果SCL处于高电平时,SDA 上产生下降沿,则认为是起始位,SDA上的上升沿认为是停止位。
通信速率分为常规模式(时钟频率100kHz)和快速模式(时钟频率400kHz)。
同一总线上可以连接多个带有I2C接口的器件,每个器件都有一个唯一的地址,既可以是单接收的器件,也可以是能够接收发送的器件。
每次数据传输都是以一个起始位开始,而以停止位结束。
传输的字节数没有限制。
最高有效位将首先被传输,接收方收到第8位数据后会发出应答位。
数据传输通常分为两种:主设备发送从设备接收和从设备发送主设备接收。
这两种模式都需要主机发送起始位和停止位,应答位由接收方产生。
从设备地址一般是1或2个字节,用于区分连接在同一I2C上的不同器件。
I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC 发出特定的低电平脉冲,表示已收到数据。
24c02的连续读写
it(list[i]);
respons_24c02(1);
}
else
{
stop_24c02(); //写完一页,则进入启动内部写周期
do
{
start_24c02();
write_8bit(W24C02);
void respons_24c02(bit ack) //ak为1则单片机接收24c02的应答信号;ak为0则24c02接收单片机的应答信号
{
uchar i=0;
SDA=ack;
while(i<250&&SDA==1)i++;
SCL=1;
_nop_();
_nop_();
{
dat=dat<<1;
SDA=CY;
SCL=1;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
}
/********************
从24c02读取一字节(8位)
的数据
********************/
uchar read_8bit()
{
uchar i,k;
for(i=0;i<8;i++)
{
SCL=1;
_nop_();
_nop_();
k=(k<<1)|SDA;
SCL=0;
_nop_();
_nop_();
}
return k;
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个数码管。
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 驱动器)或者可以接收也可以发送的器件(例 如:存储器)。发送器或接收器可以在主模式或从模式下操作,这取决于芯片是否必须启动数据的传输还是仅仅被
AT24C02的读写
; (R1)=欲写数据存放地址指针
; (R7)=连续写字节数n
EEPW: MOVP1,#0FFH
CLRP1.0;发开始信号
MOVA,R3;送器件地址
ACALLSUBS
MOVA,R4;送片内字节地址
ACALLSUBS
AGAIN: MOVA,@R1
ACALL SUBS;调发送单字节子程序INCR1
DJNZR7,AGAIN;连续写n个字节
CLRP1.0;SDA置0,准备送停止信号
ACALLDELAY ;延时以满足传输速率要求
SETBP1.1;发停止信号
ACALLDELAY
SETBP1.0
RET
SUBS: MOVR0,#08H ;发送单字节子程序
LOOP: CLRP1.1
RLCA
MOVP1.0,C
SETOK: ACALL DELAY
SETBP1.1
ACALL DELAY
CLRP1.1
ACALL DELAY
SETBP1.0;应答毕,SDA置1
RET
程序中多处调用了DELAY子程序(仅两条NOP指令),这是为了满足I2C总线上数据传送速率的要求,只有当SDA数据线上的数据稳定下来之后才能进行读写(即SCL线发出正脉冲)。另外,在读最后一数据字节时,置应答信号为“1”,表示读操作即将完成
RET
SUBR: MOVR0,#08H ;接受单字节子程序
LOOP2: SETBP1.1
ACALL DELAY
MOVC,P1.0
RLCA
CLRP1.1
ACALL DELAY
DJNZ R0,LOOP2
CJNE R7,#01H,LOW
SETB P1.0;若是最后一个字节置A=1
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数据读写
一这物行时每如一、认识IIC 这是最常用、物理结构上,行信息 传输。
时钟。
信息传每个器件都有如:存储器)C 总线的工作方最典型的II IIC 系统由一。
在数据传输传输的对象和方有一个唯一的地。
发送器或接方式C 总线连接方一条串行数据输时,由主机初方向以及信息地址,而且可接收器可以在IIC 时方式。
据线SDA 和一条初始化一次数息传输的开始可以是单接收的在主模式或从模时序24C02的条串行时钟线数据传输,主和终 止均由的器件(例如模式下操作,的操作 线SCL 组成。
主机使数据在S 主机决定。
如:LCD 驱动器这取决于芯片主机按一定的SDA 线上传输器)或者可以接片是否必须启的通信协议向输的同时还通过接收也可以发启动数据的传从机寻址和进过SCL 线传输发送的器件(例传输还是仅仅被进输例被寻1I 在低2I 寻址。
1.总线上数据IIC 总线是以在时钟线高电低电平时,才2.总线上的信IIC 总线在传据的有效性串行方式传输电平期间数据线才允许数据线上信号送数据过程中输数据,从数据线上必须保持上的电平状态中共有四种类据字节的最高持稳定 的逻辑态变化,如图类型信号,它们高位开始传送,辑电平状态,11-2所示。
们分别是:开,每一个数据位高电平为数据开始信号、停止位在SCL 上都据1,低电平为止信号、重新都有一个时钟为数据0。
只新开始信号和应脉冲相对应。
有在时钟线为应答信号。
为开的停停重之所开始信号(STA 的时候,例如停止信号(STO 停止信号,结重新开始信号之前,主机通所示,当SCL ART):如图1如,没有主动设OP):如图11结束数据通信。
号(Repeated S 通过发送重新开L为高电平时,1-3所示,当设备在使用总-3所示,当。
START):在I 开始信号,可,SDA由高电当SCL 为高电总线(SDA 和S SCL 为高电平IC 总线上,由可以转换与当电平向低电平跳平时,SDA 由CL 都处于高电平时,SDA 由低由主机发送一前从机的通信跳变,产生重由高电平向低电电平),主机通低电平向高电一个开始信号启信模 式,或是重新开始信号,电平跳变,产通过发送开始电平跳变,产生启动一次通信是切换到与另,它的本质就产生开始信号始(START)信号生停止信号。
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 提供 串行时钟信号。
IIC总线24C02读写
实验说明:T24C01A/AT24C02为I2C总线型EEPROM存储器,容量为1K/2K位(128/256*8),前读/写时序遵循I2C总线协议标准。
A T24C01A/A T24C02内部设有一个控制寄存器,其每一位的含义如下:Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit01 0 1 0 A2 A1 A0 R/W其中A2/A1/A0用于选择总线上待访问的I2C器件,R/W=1读操作,R/W=0写操作;从上述时序可以看出,I2C总线上最多可以扩展23=8片同样的1K/2K容量EEPROM存储器或者可以扩展1片容量为16K Bits的EEPROM存储器。
如果扩展8片2K以内容量的EEPROM 存储器,每片存储器将对应一个地址,这个由于实验仪上的A T24C01A/AT24C02的A2/A1/A0引脚全部接地,等效为实验仪上的AT24C01A/AT24C02的地址为0,所以在实验中读写控制字分别为:0xa1/0xa0实验要求利用实验仪上的I2C总线器件AT24C01A/AT24C02,编写I2C总线读写程序并自行验证程序的正确性。
c语言:/* 实验四十二IIC总线24C02读写*//* C51 */#include <reg51.h>#include <intrins.h>/* **********************************************************24C01/02 为IIC总线EEPROM存储器, 容量为1k位(128 * 8)************************************************************//* **********************************************************EEPROM控制字节格式:[1, 0, 1, 0, A2, A1, A0, (R/W)], 其中R/W=1读,R/W=0写;由于实验仪上的AT24C01A(AT24C02) 的A2/A1/A0全部接地,所以读/写控制字分别为:0xa1/0xa0************************************************************/#define WriteDeviceAddress 0xa0#define ReadDeviceAddress 0xa1/******************IIC器件驱动引脚定义**********************/sbit SCL = P1^0;sbit SDA = P1^1;/***********************简单延时****************************/void DelayMs(unsigned int number){unsigned char temp = 112;while(number--!=0){while(temp--!=0){}}}/*********************启动IIC总线***************************/void Start() {SDA = 1;SCL = 1;SDA = 0;SCL = 0;}/*********************停止IIC总线***************************/void Stop() {SCL = 0;SDA = 0;SCL = 1;SDA = 1;}/***********************请求相应****************************/void Ack() {SDA = 0; /*从器件响应信号将SDA线拉到低电平*/SCL = 1;SCL = 0;SDA = 1; /*响应结束,SDA回到高电平继续下一个传送周期*/ }/*******************不对IIC总线产生应答*********************/void NoAck() {SDA = 1; /*从机不响应时,数据线保持高电平*/SCL = 1;SCL = 0;}/**********************检查应答位***************************/bit TestAck() {SDA = 1;SCL = 1;CY = SDA;SCL = 0;return(CY); /*CY=0表应答*/}【关于I2C的检查应答信号的程序】unsigned char I2C_CheckAck(void){unsigned char i;unsigned char Ack=1;I2C_SDA=1;DelayUs(I2C_DELAY);I2C_SCL=1;DelayUs(I2C_DELAY);for(i=0;i<10;i++){Ack=I2C_SDA;if(!Ack){I2C_SCL=0;return 1;}}I2C_Stop();return 0;}/********************向IIC总线写数据************************/ bit 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; /*input左移输入下一位*/ }return(0);}/****************从IIC总线上读数据子程序********************/unsigned char Read8Bit(){unsigned char temp, rbyte=0;for(temp=8;temp!=0;temp--){SCL=1;rbyte=rbyte<<1;rbyte=rbyte|((unsigned char)(SDA)); /*循环结束把8位的SDA(串行的)读成了一个8位的数放到rbyte中*/SCL=0;}return(rbyte);}/*******************向EEPROM中写入数据块********************/void AT24C02WriteBlock(unsigned char *Wdata, unsigned char RomAddress, unsigned char number){if(number > 8)number %= 8; /*对于24C02, 一个页为8字节,所以最大的块写操作字节数为8*/ Start();Write8Bit(WriteDeviceAddress); //总线上器件地址TestAck();Write8Bit(RomAddress); //器件内部要写入地址,有时将此处省略默认从00开始TestAck();for(;number!=0;number--){Write8Bit(*Wdata);TestAck();Wdata++;}Stop();DelayMs(10);}/**************从EEPROM中读出数据块到指定RAM中**************/void AT24C02ReadBlock(unsigned char *RamAddress, unsigned char RomAddress, unsigned char bytes){EA = 0; //单片机读操作限制在外部ROMStart();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start(); //重新启动总线Write8Bit(ReadDeviceAddress);TestAck();while(bytes!=1){*RamAddress = Read8Bit();Ack();RamAddress++;bytes--;}*RamAddress = Read8Bit();NoAck();Stop();}/*****************向EEPROM中写入单字节数据******************/ void AT24c02WriteByte(unsigned char WriteData, unsigned char RomAddress) { Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Write8Bit(WriteData);TestAck();Stop();DelayMs(10);}/************从EEPROM中读出单字节数据到指定RAM中************/ unsigned char AT24c02ReadByte(unsigned char RomAddress) {unsigned char ReadData;Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start();Write8Bit(ReadDeviceAddress);TestAck();ReadData = Read8Bit();NoAck();Stop();return(ReadData);}void main(void){unsigned char i;unsigned char WriteBuff[8], ReadBuff[8];/* 读写缓冲初始化*/for(i = 0; i < 8; i++){WriteBuff[i] = 0x55 + i;ReadBuff[i] = 0xff;}/* 从地址0开始按字节方式写入8个数据'0' */for(i = 0; i < 8; i++){A T24c02WriteByte(0, i);}/* 按字节方式读出数据*/for(i = 0; i < 8; i++) {ReadBuff[i] = AT24c02ReadByte(i);}/* 按写Page方式从地址0开始写入WriteBuff指向的8个数据*/ A T24C02WriteBlock(WriteBuff, 0x00, 8);/* 按连续读取方式读出从地址0开始的8个数据*/A T24C02ReadBlock(ReadBuff, 0x00, 8);while(1);}汇编语言:; 实验四十二IIC总线24C02读写; ASM51; ********************************************************** ; 24C01/02 为IIC总线EEPROM存储器, 容量为1k位(128 * 8); **********************************************************; ********************************************************** ; EEPROM控制字节格式:; [1, 0, 1, 0, A2, A1, A0, (R/W)], 其中R/W=1读,R/W=0写;; 由于实验仪上的AT24C01A(AT24C02) 的A2/A1/A0全部接地, ; 所以读/写控制字分别为:0xa1/0xa0; ********************************************************** WriteDeviceAddress equ 0a0hReadDeviceAddress equ 0a1h; ******************IIC器件驱动引脚定义********************* SCL equ P1.0SDA equ P1.1; *******************读写数据缓冲定义*********************** ReadBuff equ 40hWriteBuff equ 48hRWLength equ 30hRomAddress equ 31horg 0000hljmp Mainorg 0100h; ***********************简单延时*************************** DelayMs:push 06nopDelayMsLoop2:mov r6, #0ffhDelayMsLoop1:djnz r6, DelayMsLoop1djnz acc, DelayMsLoop2pop 06ret; ********************启动IIC总线*************************** Start:setb SDAsetb SCLclr SDAclr SCLret; ********************停止IIC总线*************************** Stop:clr SCLclr SDAsetb SCLsetb SDAret; **********************请求相应**************************** Ack:clr SDAsetb SCLclr SCLsetb SDAret; ******************不对IIC总线产生应答********************* NoAck:setb SDAsetb SCLclr SCLret; *********************检查应答位*************************** TestAck:setb SDAsetb SCLmov C, SDAclr SCLnopnopnopret; *******************向IIC总线写数据************************Write8Bit:push 07mov r7, #8Write8BitLoop:rlc amov SDA, Csetb SCLclr SCLnop ; 此处建议加入几个NOP指令降低MCU对器件操作的速度nopnopdjnz r7, Write8BitLooppop 07ret; ***************从IIC总线上读数据子程序********************Read8Bit:push 07clr amov r7, #8Read8BitLoop:clr Csetb SCLmov C, SDArlc aclr SCLnop ; 此处建议加入几个NOP指令降低MCU对器件操作的速度nopnopdjnz r7, Read8BitLooppop 07ret; ******************向EEPROM中写入数据块********************AT24C02WriteBlock:clr eamov r0, #WriteBuffinc RWLengthanl RWLength, #0f0h ;对于24C02, 一个页为8字节,所以最大的块写操作字节数为8*/mov r7, RWLengthcall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckAT24C02WriteBlockLoop:mov a, @r0call Write8Bitcall TestAckinc r0djnz r7, AT24C02WriteBlockcall Stopmov a, #10call DelayMsret; *************从EEPROM中读出数据块到指定RAM中************** AT24C02ReadBlock:clr eamov r0, #ReadBuffmov r7, RWLengthcall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckcall Startmov a, #ReadDeviceAddresscall Write8Bitcall TestAckAT24C02ReadBlockLoop:call Read8Bitmov @r0, acall Ackinc r0djnz r7, AT24C02ReadBlockcall NoAckcall Stopret; ****************向EEPROM中写入单字节数据****************** AT24c02WriteByte:clr eacall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckmov a, @r0call Write8Bitcall TestAckcall Stopmov a, #10call DelayMsret; ***********从EEPROM中读出单字节数据到指定RAM中************ AT24c02ReadByte:clr eacall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckcall Startmov a, #ReadDeviceAddresscall Write8Bitcall TestAckcall Read8Bitmov @r0 ,acall NoAckcall StopretSetReadBuff:mov r0, #ReadBuffmov r7, RWLengthSetReadBuffLoop:mov @r0, ainc r0djnz r7, SetReadBuffLoopretSetWriteBuff:mov r0, #WriteBuffmov r7, RWLengthSetWriteBuffLoop:mov @r0, ainc r0djnz r7, SetWriteBuffLoopretMain:mov SP, #60h; 读写缓冲初始化mov a, #00mov RWLength, #8call SetReadBuffmov a, #00mov RWLength, #8call SetWriteBuff; 写缓冲初始化mov r0, #WriteBuffmov r7, #8mov a, #55hInitWriteBuffLoop:mov @r0, ainc ainc r0djnz r7, InitWriteBuffLoop; 从地址0开始按字节方式写入8个数据'0' mov RomAddress, #0mov r7, #8mov r0, #WriteBuffWriteLoop:call AT24c02WriteByteinc RomAddressinc r0djnz r7, WriteLoop; 按字节方式读出数据mov RomAddress, #0mov r7, #8mov r0, #ReadBuffReadLoop:call AT24c02ReadByteinc RomAddressinc r0djnz r7, ReadLoop; 按写Page方式从地址0开始写入WriteBuff指向的8个数据mov RomAddress, #0mov RWLength, #8mov r0, #WriteBuffcall AT24C02WriteBlock; 按连续读取方式读出从地址0开始的8个数据mov RomAddress, #0mov RWLength, #8mov r0, #ReadBuffcall AT24C02ReadBlockjmp $end。
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;}。
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;}。
实战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++);}}。
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为例的。
AT24C02数据的连续写入
AT24C02数据的连续写入#include <reg51.h> // 包含51单片机寄存器定义的头文件#include <intrins.h> //包含_nop_()函数定义的头文件#define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写入操作,0xa1即为1010 0000B sbit SDA=P3^4; //将串行数据总线SDA位定义在为P3.4引脚sbit SCL=P3^3; //将串行时钟总线SDA位定义在为P3.3引脚sbit P2_3=P2^3;sbit P2_2=P2^2;sbit P2_1=P2^1;sbit P2_0=P2^0;/*****************************************************函数功能:延时1ms(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒***************************************************/void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}void delay(){unsigned char i,j;for(j=0;j<16;j++)for(i=0;i<255;i++);}/*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/void delaynms(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}void hung(){}/***************************************************函数功能:开始数据传送***************************************************/void start()// 开始位{SDA = 1; //SDA初始化为高电平“1”SCL = 1; //开始数据传送时,要求SCL为高电平“1”_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期SDA = 0; //SDA的下降沿被认为是开始信号_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)}/***************************************************函数功能:结束数据传送***************************************************/void stop()// 停止位{SDA = 0; //SDA初始化为低电平“0”_nSCL = 1; //结束数据传送时,要求SCL为高电平“1”_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期SDA = 1; //SDA的上升沿被认为是结束信号_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期SDA=0;SCL=0;}/***************************************************函数功能:从AT24Cxx读取数据出口参数:x***************************************************/unsigned char ReadData()// 从AT24Cxx移入数据到MCU{unsigned char i;unsigned char x; //储存从A T24Cxx中读出的数据for(i = 0; i < 8; i++){SCL = 1; //SCL置为高电平x<<=1; //将x中的各二进位向左移一位x|=(unsigned char)SDA; //将SDA上的数据通过按位“或“运算存入x中SCL = 0; //在SCL的下降沿读出数据}return(x); //将读取的数据返回}/***************************************************函数功能:向AT24Cxx的当前地址写入数据入口参数:y (储存待写入的数据)***************************************************///在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0bit WriteCurrent(unsigned char y){unsigned char i;bit ack_bit; //储存应答位for(i = 0; i < 8; i++) // 循环移入8个位{SDA = (bit)(y&0x80); //通过按位“与”运算将最高位数据送到S//因为传送时高位在前,低位在后_nop_(); //等待一个机器周期SCL = 1; //在SCL的上升沿将数据写入AT24Cxx_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期SCL = 0; //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲y <<= 1; //将y中的各二进位向左移一位}SDA = 1; // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,//以让SDA线转由接收设备(AT24Cxx)控制_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期SCL = 1; //根据上述规定,SCL应为高电平_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期ack_bit = SDA; //接受设备(A T24Cxx)向SDA送低电平,表示已经接收到一个字节//若送高电平,表示没有接收到,传送异常SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)return ack_bit; // 返回AT24Cxx应答位}/***************************************************函数功能:向AT24Cxx中的指定地址写入数据入口参数:add (储存指定的地址);dat(储存待写入的数据)***************************************************/void WriteSet(unsigned char add, unsigned char dat)// 在指定地址addr处写入数据WriteCurrent{start(); //开始数据传递WriteCurrent(OP_WRITE); //选择要操作的A T24Cxx芯片,并告知要对其写入数据WriteCurrent(add); //写入指定地址WriteCurrent(dat); //向当前地址(上面指定的地址)写入数据stop(); //停止数据传递delaynms(4); //1个字节的写入周期为1ms, 最好延时1ms以上}/***************************************************函数功能:从AT24Cxx中的当前地址读取数据出口参数:x (储存读出的数据)***************************************************/unsigned char ReadCurrent(){unsigned char x;start(); //开始数据传递WriteCurrent(OP_READ); //选择要操作的AT24Cxx芯片,并告知要读其数据x=ReadData(); //将读取的数据存入xstop(); //停止数据传递return x; //返回读取的数据}/***************************************************函数功能:从AT24Cxx中的指定地址读取数据入口参数:set_addr出口参数:x***************************************************/unsigned char ReadSet(unsigned char set_addr)// 在指定地址读取{start(); //开始数据传递WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据WriteCurrent(set_addr); //写入指定地址return(ReadCurrent()); //从指定地址读出数据并返回}/***************************************************函数功能:主函数***************************************************/main(void){SDA = 1; // SDA=1,SCL=1,使主从设备处于空闲状态SCL = 1;WriteSet(0x36,0x3f);WriteSet(0x26,0x06);WriteSet(0x16,0x5b);WriteSet(0x06,0x4f);while(1){ P2=0xff;P2_3=0;P0=ReadSet(0x36);delay();P2=0xff;P2_2=0;P0=ReadSet(0x26);delay();P2=0xff;P2_1=0;P0=ReadSet(0x16);delay();P2=0xff;P2_0=0;P0=ReadSet(0x06);delay(); }}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
/********************
从addr中读取一字节数据
返回dat
********************/
uchar read_byte(uchar addr)
{
uchar dat;
start_24c02();
write_8bit(W24C02);
respons_24c02(1);
write_8bit(addr);
respons_24c02(1);
start_24c02();
write_8bit(R24C02);
respons_24c02(1);
dat=read_8bit(); //读取一字节后若发送停止指令,则结束并返回dat
write_8bit(W24C02);
respons_24c02(1);
write_8bit(addr);
respons_24c02(1);
do
{
if(i==0||i%8!=0) //判断是否到了页的边缘
{
write_8bit(list[i]);
respons_24c02(1);
SCL=1;
_nop_();
_nop_();
SCL=0; //应答
write_8bit(i);
respons_24c02(1);
write_8bit(list[i]);
respons_24c02(1);
}
}
while(list[i++]!='\n');
stop_24c02();
return dat;
}
/********************
从地址addr开始连续读
取数据,并存入list中
以'\n'为结束
********************/
void read_list(uchar addr,uchar *list)
{
{
start_24c02();
write_8bit(W24C02);
respons_24c02(1);
write_8bit(addr);
respons_24c02(1);
write_8bit(dat);
respons_24c02(1);
stop_24c02();
}
uchar i=0;
start_24c02();
write_8bit(W24C02);
respons_24c02(1);
write_8bit(addr);
respons_24c02(1);
start_24c02();
write_8bit(R24C02);
respons_24c02(1);
}
}
/********************
从24c02读取一字节(8位)
的数据
********************/
uchar read_8bit()
{
uchar i,k;
for(i=0;i<8;i++)
{
SCL=1;
_nop_();
_nop_();
uchar read_8bit(); //读8位
uchar read_byte(uchar); //从某一地址读1字节
void read_list(uchar,uchar *); //从某一地址开始连续读,存到*所指位置
/********************
开始,在读\写前调用
do
{
list[i]=read_8bit(); //读取1字节后,若其不为结束标志,则发送应答信号,继续读下一个
if(list[i]!='\n')
respons_le(list[i++]!='\n');
stop_24c02();
}
}
else
{
stop_24c02(); //写完一页,则进入启动内部写周期
do
{
start_24c02();
write_8bit(W24C02);
SDA=1;
//delay(2);
}while(SDA==1); //等待24c02完成写周期发出的应答信号,从而继续下一个读写操作
void response_24c02(bit); //应答
void write_8bit(uchar); //写8位
void write_byte(uchar,uchar); //写一字节
void write_list(uchar, uchar *); //写*指向的数据(以'\n'作结束)
********************/
void start_24c02()
{
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
}
/********************
/********************/
sbit SDA=P3^6; //AT24C02串行数据 5脚
sbit SCL=P3^7; //AT24C02串行时钟 6脚
void start_24c02(); //开始
void stop_24c02(); //停止
结束,在读\写完后调用
********************/
void stop_24c02()
{
SDA=0;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
}
/********************
应答
当单片机写时,ack=1,为等待24c02的应答信号
当单片机读时,ack=0,为向24c02发送应答信号
********************/
void respons_24c02(bit ack) //ak为1则单片机接收24c02的应答信号;ak为0则24c02接收单片机的应答信号
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define W24C02 0xA0 //存储器的写地址
#define R24C02 0xA1 //存储器的读地址
/**********************************************
24c02驱动程序
SDA=P3^6;SCL=P3^7;
可以写一个字节,写一串字符(以'\n'作为结束标志)
可以读一个字节,读一串字符(以'\n'作为结束标志)
**********************************************/
{
uchar i=0;
SDA=ack;
while(i<250&&SDA==1)i++;
SCL=1;
_nop_();
_nop_();
SCL=0;
_nop_();
SDA=1;
}
/********************
向24c02写入一字节(8位)的数据
********************/
k=(k<<1)|SDA;
SCL=0;
_nop_();
_nop_();
}
return k;
}
/********************
向地址addr写入数据dat
********************/
void write_byte(uchar addr,uchar dat)
void write_8bit(uchar dat)
{
uchar i;
SCL=0;
for(i=0;i<8;i++)
{
dat=dat<<1;
SDA=CY;
SCL=1;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
/********************
从地址addr形如连续写入
list中的数据,以'\n'为
结束标志
********************/
void write_list(uchar addr, uchar *list)
{
uchar i=0;
start_24c02();