请问EEPROM编程的驱动该怎么写啊!

twtwvfwxf   2010-2-25 21:24 楼主
刚学单片机没多久,看不懂时序图,望各位大虾不吝赐教!谢谢了啊!

回复评论 (11)

EEPROM的读写一般都是采用I2C总线进行的。

有些MCU有I2C功能模块,有些MCU没有,但可以用IO模拟,


楼主用的是什么单片机啊?
楼主可以看看我上传的:
51单片机采用I2C读写EEPROM的源代码
http://download.eeworld.net/source/1977557
51单片机采用I2C读写EEPROM的源代码,采用C实现51单片机通过I2C 总线EEPROM(具体型号为24C02)的读写,并采用LED和LCD分别显示读写的内容,值得参考。
点赞  2010-2-25 23:12
先去搞懂时序图

回复内容     回复内容太短了
点赞  2010-2-25 23:48
楼主你用的是什么芯片,型号发来看看,或许我有驱动
点赞  2010-2-26 16:58

#include "W79E824.H"
#include
#define uint unsigned int
#define uchar unsigned char

//#define WP=0 _nop_()
//#define WP=1 _nop_()
bit flag;
#define SCL P12
sbit SDA1=P1^3;
//sbit WP=P3^4;

/*EEPROM Fuction*/
void delay(void)
{
  uchar i;
  for(i=20;i>0;i--)
  _nop_();
}
/*
void delayij(uchar i,uchar j)
{
        uchar m,n;
        for(m=0;m         {
                for(n=j;n>0;n--);  //延时124*8+10=1002us
                {
                        _nop_();
                }
        }
}
         */

/*********************************************************
**名称:I2C_Start
**功能:启动I2C
**输入:无
**返回:无
*********************************************************/
void I2C_Start()
{
        SDA1=1;
        delay();
        SCL=1;
        delay();
        SDA1=0;
        delay();
        SCL=0;
}

/**********************************************************
**名称:I2C_Stop
**功能:停止I2C
**输入:无
**返回:无
**********************************************************/
void I2C_Stop()
{
        SDA1=0;
        delay();
        SCL=1;
        delay();
        SDA1=1;
        delay();
}




/**********************************************************
**名称:Ack
**功能:应答信号
**输入:无
**返回:无
**********************************************************/
void Ack()
{
        SDA1=0;
        delay();
        SCL=1;
        delay();
        SCL=0;
        delay();
        SDA1=1;
        delay();
}



/********************************************************
**名称:NoAck
**功能:发送非应答信号
**输入:无
**返回:无
********************************************************/
void NoAck()
{
        SDA1=1;
        delay();
        SCL=1;
        delay();
        SCL=0;
        delay();
        SDA1=0;
        delay();
}




/********************************************************
**名称:Test_Ack()
**功能:检测应答位
**输入:无
**返回:flag,有应答时flag为0,无应答时flag为1
*********************************************************/
bit Test_Ack()
{
        SCL=0;
        SDA1=1;//读入数据
        _nop_();_nop_();_nop_();_nop_();
        SCL=1;
        _nop_();_nop_();_nop_();_nop_();
        if(SDA1==0)
                flag=1;
        else        flag=0;
        SCL=0;
        return(flag);
}



/********************************************************
**名称:SendData()        
**功能:发送一字节数据
**输入:buffer
**返回:
*******************************************************/
void SendData(uchar buffer)
{
        uchar BitCnt=8;//一字节8位
        uchar temp=0;
        do
        {
                temp=buffer;
                SCL=0;
                delay();
                if((temp&0x80)==0) //
                        SDA1=0;
                else
                        SDA1=1;
                delay();
                SCL=1;
                temp=_crol_(buffer,1);//rl buff
                buffer=temp;
                BitCnt--;
        }
        while(BitCnt);
        SCL=0;        
}

/**************************************************************
**名称:uint ReceiveData()
**功能:接收一字节数据
**输入:
**返回:ucReceData
**说明:将接收的数据存放在ucReceData中
**************************************************************/
uchar ReceiveData()
{
                uchar ucReceData;
        uchar BitCnt=8;
        uchar temp=0;
        SDA1=1;//读入数据
        do
        {
                SCL=0;
                delay();
                SCL=1;
                delay();
                if(SDA1==1)
                        ucReceData=ucReceData|0x01;
                else
                        ucReceData=ucReceData&0x0fe;
                if(BitCnt-1)
                {
                        temp=_crol_(ucReceData,1);
                        ucReceData=temp;
                }
                BitCnt--;
        }
        while(BitCnt);
        SCL=0;
        return(ucReceData);
}

/*************************************************************
**bit WriteNByte()
**24C64中写入多字节数据
**
** *s-data to write   sbbab-data address 8bits low
**sla-device address  suba-data address 8bits high  n-bytes(n<=32)
**************************************************************
bit WriteNByte(uchar sla,uchar suba,uchar subab,uchar *s,uint n)
{
        uchar i;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0)        return(0);
        SendData(suba);
        Test_Ack();
                if(flag==0)        return(0);

        SendData(subab);
        Test_Ack();
        if(flag==0)        return(0);

        for(i=0;i         {
                SendData(*(s+i));
                Test_Ack();
                if(flag==0)        return(0);
        }
        I2C_Stop();
        return(1);
}
*/
bit WriteNByte(uchar sla,uint addr,uchar *s,uint n)
{
        uchar i;
                uchar suba;
                uchar subab;
                suba=(addr>>8);
                subab=addr&0x00ff;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0)        return(0);
        SendData(suba);
        Test_Ack();
                if(flag==0)        return(0);

        SendData(subab);
        Test_Ack();
        if(flag==0)        return(0);

        for(i=0;i         {
                SendData(*(s+i));
                Test_Ack();
                if(flag==0)        return(0);
        }
        I2C_Stop();
        return(1);
}

/*************************************************************
**bit ReadNByte()
**24C64中读出N字节数据(n<=32)
**
**
**
**************************************************************
bit ReadNByte(uchar sla,uchar suba,uchar subab,uchar *p,uint n)
{
        uchar i;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0){return(0);}
        SendData(suba);
        Test_Ack();
        if(flag==0){return(0);}

                SendData(subab);
        Test_Ack();
        if(flag==0){return(0);}

        I2C_Start();
        SendData(sla+1);
        Test_Ack();
        if(flag==0){return(0);}
        for(i=0;i         {
                *(p+i)=ReceiveData();
                Ack();
        }
        *(p+n-1)=ReceiveData();
        
        NoAck();
        I2C_Stop();
        return(1);
}
*/
bit ReadNByte(uchar sla,uint addr,uchar *p,uint n)
{
        uchar i;
                uchar suba;
                uchar subab;
                suba=(addr>>8);
                subab=addr&0x00ff;
        I2C_Start();
        SendData(sla);
        Test_Ack();
        if(flag==0){return(0);}
        SendData(suba);
        Test_Ack();
        if(flag==0){return(0);}

                SendData(subab);
        Test_Ack();
        if(flag==0){return(0);}

        I2C_Start();
        SendData(sla+1);
        Test_Ack();
        if(flag==0){return(0);}
        for(i=0;i         {
                *(p+i)=ReceiveData();
                Ack();
        }
        *(p+n-1)=ReceiveData();
        
        NoAck();
        I2C_Stop();
        return(1);
}

/*
bit ReadNByte(uchar sla,uchar suba,uchar subab,uchar *p,uint n)
{
        uchar i;
        ENS1=1;
        I2DAT=sla;
        STA=1;
        while(SI==0);
        SI=0;
//        if(AA==0)return(0);
        I2DAT=suba;
        while(SI==0);
        SI=0;
//        if(AA==0)return(0);
        I2DAT=subab;
        while(SI==0);
        SI=0;
//        if(AA==0)return(0);
        for(i=0;i         {
                while(SI==0);
                *(p+i)=I2DAT;
                SI=0;
        }
        *(p+n-1)=I2DAT;
        STO=1;
        ENS1=0;
        return(1);
}*/

/*
bit ClearROM(uchar s)
{
        uint i;
//                uchar j;
        I2C_Start();
        SendData(0xa0);
        Test_Ack();
        if(flag==0)        return(0);
        SendData(0x00);
        Test_Ack();
                if(flag==0)        return(0);

        SendData(0x00);
        Test_Ack();
        if(flag==0)        return(0);

        for(i=0;i<0x8000;i++)
        {
//                                j=i*100/0x8000;
//                                PrintNumber(36,5,j);
                SendData(s);
                Test_Ack();
                if(flag==0)        return(0);
        }
        I2C_Stop();
        return(1);
}
/*========================================*/

修改下就可以用了,不过建议时序图还是努力看懂比较好
点赞  2010-2-26 17:41
EEPROM有很多,楼主用的是哪款?
点赞  2010-2-26 19:31
x24c02
程序
void delay()
{ ;; }
void start()  //开始信号
{       
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}

void stop()   //停止
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}

void respons()  //应答
{
        uchar i;
        scl=1;
        delay();
        while((sda==1)&&(i<250))i++;
        scl=0;
        delay();
}

void init()
{
        sda=1;
        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;
            delay();
                sda=CY;
                delay();
                scl=1;
                delay();
        //        scl=0;
     //   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();       
        }
        return k;
}

void delay1(uchar x)
{
        uchar a,b;
        for(a=x;a>0;a--)
         for(b=100;b>0;b--);
}

void write_add(uchar address,uchar date)
{
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);
        respons();
        write_byte(date);
        respons();
        stop();
}

uchar read_add(uchar address)
{
        uchar date;
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);
        respons();
        start();
        write_byte(0xa1);
        respons();
        date=read_byte();
        stop();
        return date;
}
点赞  2010-3-1 16:28
谢谢各位的回答!我的芯片是STC89C52RC,EEPROM是24C512!看不懂时序图啊
点赞  2010-3-2 21:33
引用: 引用 7 楼 wumingrenzhe 的回复:
谢谢各位的回答!我的芯片是STC89C52RC,EEPROM是24C512!看不懂时序图啊


所谓时序就是按照时间的排序依次进行信号的传播。
点赞  2010-3-3 21:00
引用: 引用 8 楼 hallowwar 的回复:
引用 7 楼 wumingrenzhe 的回复:谢谢各位的回答!我的芯片是STC89C52RC,EEPROM是24C512!看不懂时序图啊

能具体解释一下下面这个时序图吗!尤其是最下面那一行信号!

所谓时序就是按照时间的排序依次进行信号的传播。
点赞  2010-3-3 21:34
一下是图片的地址!
[url=http://home.51.com/hezhifeng8881966/photo/item/100145614.html][/url]
点赞  2010-3-3 21:35
谁能解释一下下面这张时序图啊![url=http://home.51.com/hezhifeng8881966/photo/item/100145614.html][/url]
点赞  2010-3-4 13:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复