24C01驱动

来源:互联网 发布:linux mint与ubuntu 编辑:程序博客网 时间:2024/05/17 01:48
24C01驱动
[ 2012-5-18 13:48:00 | By: 吴师傅 ]
 
8
推荐

.概述

24系列I2C串行总线EEPROM芯片应用非常广泛,在51单片机控制系统中如影随形。24系列EEPROM可重复擦写100万次,数据可以掉电保存100年不变,有1K位、2K位、4K位、8K位等存储容量的系列产品,24C01就是其中的1K位容量的产品。

I2C串行总线是Philips公司推出的一种双向二线制通信总线,由一条数据线和一条时钟线组成,主要应用于芯片之间的通信。支持I2C总线接口的芯片非常多,所以学习单片机一定要掌握I2C总线协议。51单片机本身并不带I2C总线接口,要想访问I2C接口芯片,只有通过软件模拟实现。51单片机IO口操作简单,软件模拟I2C总线轻而易取。

.电路设计

WSF-51DB开发板上,利用AT89S52单片机的P0.3P0.4P0.5来驱动AT24C01P0口的上拉排阻为4.7K欧姆。需要注意的是AT24C01SDA管脚是漏极开路,所以一定要在这个管脚上接一个上拉电阻,阻值在2K-10K欧姆范围内选择,传输速率越高,阻值应当越小。

 

         

  

.软件设计

/*****************************************************************

*程序名称:24C01驱动

*程序功能:写人8个数据,再读出来,放在P2口显示。

*开发工具:WSF-51DB开发板

* MCU型号:AT89S52-24PU

*时钟频率:12MHZ

*程序作者:吴师傅

*版权说明:吴师傅版权所有。转载请注明来源和作者。

*****************************************************************/

#i nclude<reg52.h>

unsigned char code dat[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//写入24C01的数据

sbit wp=P0^3;//写保护

sbit scl=P0^4;//时钟线

sbit sda=P0^5;//数据线 

 

//延时15us函数:  

void Delayus()

{

    unsigned char i;

    for(i=5;i>0;i--);

}

 

//延时1ms函数:

void Delayms(unsigned int t)

{

    unsigned int x,y;

    for(x=t;x>0;x--)

            for(y=120;y>0;y--);

}

 

//起始信号函数:

void Start(void)

{    

        sda=1;//时序要就很严格

        scl=1;   

        Delayus();

        sda=0;

        scl=0;

}

//停止信号函数:

void Stop(void)

{

        scl=0;//时序要就很严格

        sda=0;

        Delayus();    

        scl=1;

        sda=1;

}

//应答信号函数:

void ACK(void)

{

        sda=1;//先释放总线

        scl=1;//启动应答时钟(第九个脉冲)

        Delayus();//器件发出应答信号(sda被拉低)   

        scl=0;

        Delayus();//等待应答脉冲变高后结束应答

}

 

//写字节函数:

void Write24c01Byte(unsigned char wbyte)

{

        unsigned char i;

        for(i=0;i<8;i++)

        {

            sda=(wbyte&0x80)?1:0;//从高到低逐位写数据,

            Delayus();

            scl=1;

            Delayus();

            scl=0;

            Delayus();

            wbyte<<=1;

        }

}

 

//读数据函数:

unsigned char Read24c01Byte(void)

{

         unsigned char i,rbyte;

         for(i=0;i<8;i++)

         {

                rbyte<<=1;

                scl=1;

                Delayus();

                if(sda==1) rbyte|=0x01;//逐位读取数据

                else rbyte&=(~0x01);

                scl=0;

                Delayus();

         }

         return rbyte;

}

//字节模式写数据函数:

void Write24c01ByteData(unsigned char waddr, unsigned char wdata)

{

        Start();

        Write24c01Byte(0xa0);//器件地址1010000+写(0

        ACK();

        Write24c01Byte(waddr);//写地址

        ACK();

        Write24c01Byte(wdata);//写数据

        ACK();

        Stop();

        Delayms(1);//写延时,最大5毫秒

}

//页模式写数据函数:

void Write24c01PageData(unsigned char saddr,unsigned char *pd,unsigned char num)

//saddr---页起始地址;pd---指针;nun---字节个数,不能大于一页的字节数

{

        unsigned char i;

        Start();

        Write24c01Byte(0xa0);//器件地址1010000+写(0

        ACK();

        Write24c01Byte(saddr);//写页起始地址,24C01一页8个字节,共16

        ACK();

        for(i=0;i<num;i++)//在一页范围内连续写多个字节

        {

             Write24c01Byte(*pd++);//写数据

             ACK();

        }

        Stop();

}

 

//读数据函数:

unsigned char Read24c01Data(unsigned char raddr)

{

         unsigned char rdat;

         Start();

         Write24c01Byte(0xa0);//器件地址+写(0

         ACK();

         Write24c01Byte(raddr);//写数据存放地址

         ACK();

         Start();

         Write24c01Byte(0xa1);//器件地址1010000+读(1

         ACK();

         rdat=Read24c01Byte();

         Stop();

         return rdat;

}

 

//主函数:

int main(void)

{

         unsigned char i;

         wp=0;//写使能

         //for(i=0;i<8;i++)

             // Write24c01ByteData(i,datacode[i]);//字节模式从0地址开始写入8个数据

         Write24c01PageData(0,dat,8);//页模式从0地址开始写入8个数据

         while(1)

         {

                for(i=0;i<8;i++)

                {        

                    P2=Read24c01Data(i);//0地址开始读出数据,点亮P2口的8LED

                    Delayms(500);

                }

         }

         return 0;

}

原创粉丝点击