⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom.c

📁 MCS51 C语言操作AT24Cxx的函数。采用头文件加c文件的形式。可对AT24Cxx系列的EEPROM进行单字节和多字节的读写操作。可作底层库函数使用。在EEPROM.c文件修改编译设置
💻 C
字号:
/*************************************************************************
File Name:	eeprom.c
Description:	AT24cXX
By:	Jemmydeng
Date:	2008-06-xx
*************************************************************************/
#include <reg51.h>
#include <intrins.h>

#include <delay.h>
#include <eeprom.h>


#define uchar unsigned char
#define uint  unsigned int

//#define _PAGES_	1			//单字节地址,多页时定义此项(for 24c04,24c08,24c16)

//#define _16_BITS_ADDRESS_	1	//双字节地址时定义此项(for 24c32,24c64)
//=======================================================================
sbit SCL=P0^4;
sbit SDA=P0^5;

bit ack_state=0;
//=======================================================================

void ST_EEPROM(void)
{
    SDA=1;
    SCL=1;
    delay_us(10);
    SDA=0;
    delay_us(10);
    SCL=0;
    delay_us(10);
}

//------------------------------------
void END_EEPROM(void)
{
    SDA=0;
    SCL=0;
    delay_us(10);
    SCL=1;
    delay_us(10);
    SDA=1;
    delay_us(10);
}

//------------------------------------
void write(unsigned char byte)
{
    unsigned char i,j;
    
    for(i=0;i<8;i++)
    {
	j = (0x80>>i);
	j = j&byte;
        if(j)
        {
            SDA=1;
            }
        else
        {
            SDA=0;
        }
        
	delay_us(10);

        SCL=1;
        delay_us(10);
        SCL=0;
        delay_us(10);
    }
}

//------------------------------------
unsigned char read(void)
{
    bit data1=0;
    unsigned char a=0,i;
    
    for(i=0;i<8;i++)
    {
        SDA=1;
        SCL=1;
        delay_us(10);
        data1=SDA;
        delay_us(10);
        SCL=0;
        delay_us(10);
	a=a<<1;
        if(data1)
        {
            a+=1;
        }
    }
    
    return a;
}

//-------------------------------------
bit TEST_ACK(void)
{
     bit ack1;
     SDA=1;
     SCL=1;
     delay_us(10);
     ack1=SDA;
     delay_us(10);
     SCL=0;
     delay_us(10);
     return ack1;
}

//----------------------
void ACK(void)
{
	SDA=0;
	SCL=1;
	delay_us(10);
	SCL=0;
	SDA=1;
}

//---------------------
void NOT_ACK(void)
{
     	SDA=1; 
	SCL=1;
	delay_us(10);
	SCL=0;
}

//===============================================================
//  写EEPROM单字节程序,参数1为高地址,参数2为低地址,参数3为要写的数据
//  器件地址引脚固定接地(0xa0)
//------------------------------------------------------------

void WR_BYTE(unsigned char page,uchar address_h,uchar address_l,uchar data1)
{
    unsigned char device_addr;
    
    #ifdef _PAGES_
    page = (page<<1);
    device_addr = (0xa0|page);	//器件地址引脚固定接地
    #else
    device_addr = 0xa0;
    #endif
    
    ST_EEPROM();               //启动开始
    write(device_addr);        //写器件地址10100000
    ack_state = TEST_ACK();
    
    #ifdef _16_BITS_ADDRESS_
    write(address_h);          //写高地址
    ack_state=TEST_ACK();
    #endif
    
    write(address_l);          //写低地址
    ack_state=TEST_ACK();
    write(data1);              //写数据
    ack_state=TEST_ACK();
    END_EEPROM();              //结束
	delay_us(300);
}

//-----------------------------------------------------
//  读EEPROM单字节程序,参数1为高地址,参数2为低地址
//----------------------------------------------------
uchar RD_BYTE(unsigned char page, uchar address_h,uchar address_l)
{
    	unsigned char rd_data=0;
    	unsigned char device_addr;
    
    	#ifdef _PAGES_
    	page = (page<<1);
    	device_addr = (0xa0|page);	//器件地址引脚固定接地
    	#else
    	device_addr = 0xa0;
    	#endif
    
    	ST_EEPROM();               //启动
    	write(device_addr);               //写器件地址
    	ack_state=TEST_ACK();
    	
    	#ifdef _16_BITS_ADDRESS_
    	write(address_h); 
    	ack_state=TEST_ACK();
    	#endif
    	
    	write(address_l);
    	ack_state=TEST_ACK();
    	ST_EEPROM();               //再次启动
    	write(device_addr|1);               //读器件地址10100001
    	ack_state=TEST_ACK();
    	rd_data=read();            //读数据
    	NOT_ACK();                 //无应答信号
    	END_EEPROM();
	delay_us(300);
	
    	return rd_data;
}

//===============================================================================
//连续写EEPROM多个字节子程序,参数1为要写首地址的高字节,参数2为要写首地址的低字节,
//参数3为要写的字节数,参数4为要写字节的首地址
//-------------------------------------------------------------------------------

void WR_BYTES(unsigned char page,uchar init_address_h,uchar init_address_l,uchar number,uchar *data1)
{
    unsigned char i;
    unsigned char device_addr;
    
    #ifdef _PAGES_
    page = (page<<1);
    device_addr = (0xa0|page);	//器件地址引脚固定接地
    #else
    device_addr = 0xa0;
    #endif
    
    ST_EEPROM();
	write(device_addr);
	ack_state=TEST_ACK();
	
	#ifdef _16_BITS_ADDRESS_
	write(init_address_h);
	ack_state=TEST_ACK();
	#endif
	
	write(init_address_l);
	ack_state=TEST_ACK();
	
	for(i=0;i<number;i++)
	{
	    	write(data1[i]);
		if(TEST_ACK())
		    ;
	}
	END_EEPROM();
	delay_us(300);
}

//===============================================================================
//连续读EEPROM多个字节子程序,参数1为要读首地址的高字节,参数2为要读写首地址的低字节,
//参数3为要读的字节数,参数4为要读字节的首地址
//-------------------------------------------------------------------------------
void RD_BYTES(unsigned char page,uchar init_address_h,uchar init_address_l,uchar number,uchar *data1)
{
    unsigned char i;
    unsigned char device_addr;
    
    #ifdef _PAGES_
    page = (page<<1);
    device_addr = (0xa0|page);	//器件地址引脚固定接地
    #else
    device_addr = 0xa0;
    #endif
    
    ST_EEPROM();
	write(device_addr);
	ack_state=TEST_ACK();
	
	#ifdef _16_BITS_ADDRESS_
	write(init_address_h);
	ack_state=TEST_ACK();
	#endif
	
	write(init_address_l);
	ack_state=TEST_ACK();
	ST_EEPROM();
	write(device_addr|1);
	ack_state=TEST_ACK();
	
	for(i=0;i<number-1;i++)
	{
	    	*data1=read();
		ACK();
		data1++;
	}
	
	*data1 = read();
	NOT_ACK();
	
	END_EEPROM();
	delay_us(300);
}



//---------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -