×
单片机 > 单片机程序设计 > 详情

MSP430平台下实现AT24C02的读写操作

发布时间:2020-12-22 发布时间:
|

EEPROM可以随机访问和修改其中的任何一个字节,可以往每个bit中写入0或者1,掉电后数据不丢失,可以保存100年,可以擦写100w次。具有较高的可靠性,但是电路复杂/成本也高。因此目前的EEPROM都是几十千字节到几百千字节的,绝少有超过512K的,常用来保存用户数据,运行过程中可以改变。


下面在MSP430平台下以AT24C02为例说明该类可擦除ROM的使用。AT24C02的存储容量为2K bits,内容分成32页,每页8 bytes,共256 bytes。


AT24C02对外以I2C总线形式传输数据,外观如下图所示:

A0、A1和A2三个引脚作寻址用;SDA和SCL即I2C总线的数据与时钟引脚;WP作写保护用,即WP在保持高电平时,MCU对AT24C02 的读写操作无效;VCC和GND分别接电源和接地。


MCU在挂载多片AT24C02时,其器件地址由8位构成,除A0、A1和A2三位外,其他位都被锁定为如下所示:

最低位为R/W,进行读操作时,该位 = 1,写操作时,该位 = 0。地址写入正确时,AT24C02将会应答以”0”。


AT24C02的读写遵循I2C总线的相关规范,所以有传输的开始条件和停止条件。每一次正常的读写均以开始条件开始,停止条件结束,这两者的时序如下图所示:

其软件模拟的实现为:


void start(void)

{

      SCL_H;

      SDA_H;

      _NOP();

      SDA_L;

      _NOP();

      SCL_L;

      _NOP();

}

void stop(void)

{

      SDA_L;

      _NOP();

      SCL_H;

      _NOP();

      SDA_H;

      _NOP();   

}





SCL_H、SDA_H、SDA_L和SCL_L均为宏定义,分别表示MCU向AT24C02相应引脚输出高电平和低电平。


AT24C02的写操作分两种模式,分别为字节写入和页写入两种。


1、字节写入


该写操作需要以MCU写入开始条件开始,继以器件地址,收到AT24C02的应答后继续写入要进行写操作的字地址(即要将数据写入该AT24C02的什么位置),收到应答后才正式写入一个字节的数据,收到应答后写入停止条件,一个完整的字节写入才算完成。

其软件模拟的实现为:


uchar Write_1Byte(uchar wdata,uchar dataaddress)

{

     start();

     write1byte(deviceaddress);

     if(check())

        write1byte(dataaddress);

     else

        return 0;

     if(check())

        write1byte(wdata);

     else

        return 0;

     if(check())         stop();

     else            return 0;

  delay_10ms();       //等待EEPROM完成内部写入

     return 1;

}



delay_10ms()是因为AT24C02的每两次写操作之间存在一个写入时间周期tWR,其最大值为5 ms。check()检查AT24C02的应答操作,收到AT24C02回复的0,则应答正确,其软件模拟实现为:


uchar check(void)

{

      uchar slaveack;

      SDA_H;

      _NOP(); _NOP();

      SCL_H;

      _NOP(); _NOP();

   SDA_in;

   _NOP(); _NOP();

      slaveack = SDA_val;   //读入SDA数值

      SCL_L;

      _NOP();

    SDA_out;

    if(slaveack)    return FALSE;

    else          return TRUE;

}



SDA_in和SDA_out分别表示MCU(MSP430)连接AT24C02的I/O引脚方向改为输入或输出,此处SDA_in的作用是为MCU接收AT24C02的应答信号做准备,接收完成后改回SDA_out。SDA_val = P2IN&BIT5,P2.5连接AT24C02的SDA引脚,接收应答信号。


write1byte()向I2C总线写一个字节的数据,其软件模拟实现为:


void write1byte(uchar wdata)

{

    uchar i;

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

    {

           if(wdata & 0x80)     write1();

           else                         write0();

           wdata <<= 1;

    }                  

    SDA_H;

    _NOP();  

}



write1()向I2C总线写一位“1”的数据,其软件模拟实现为:


void write1(void)

{

      SDA_H;

      _NOP();

      SCL_H;

      _NOP();

      SCL_L;                        

      _NOP();

}



write0()向I2C总线写一位“0”的数据,其软件模拟实现为:


void write0(void)

{

      SDA_L;

      _NOP();

      SCL_H;

      _NOP();              

      SCL_L;                        

      _NOP();

}



2、页写入


AT24C02可以实现8位的页写入操作。页写入的形式大体和字节写入类似,只是在MCU写入第一个字节的数据后将会继续写入第二个数据,而不会像字节写入一样写入停止条件。如果写入AT24C02的数据超过8位,超过的数据将会覆盖已被写入的部分。

其软件模拟的实现为:


uchar Write_NByte(uchar * outbuf,uchar n,uint dataaddress)

{

     uchar  flag,dataaddressl,dataaddressh;

        dataaddressl = dataaddress;

        dataaddressh = dataaddress>>8;

   

     start();

     write1byte(deviceaddress);                  //写入器件地址

     if(check() == 1)

        write1byte(dataaddressh);                //写入数据字地址

     else

        return 0;

   if(check())

        write1byte(dataaddressl);

   else

        return 0;

     if(check())

        flag=writeNbyte(outbuf,n);

     else

       return 0;

       delay_10ms();       //等待EEPROM完成内部写入

       

     if(flag)   

       return 1;

     else       

       return 0;

}



writeNbyte()向I2C总线写N个字节(对于AT24C02,N = 8)的数据,其软件模拟实现为:


uchar writeNbyte(uchar * outbuffer,uchar n)

{

     uchar i;

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

     {

            write1byte(* outbuffer);

            if(check())     

            {

                   outbuffer++;              

            }

            else

            {

                   stop();

                   return FALSE;

            }

     }

     stop();

     return TRUE;                    

}



AT24C02的读操作分三种模式,分别为当前地址读取、随机读取和顺序读取。


1、当前地址读取


上一次读写操作完成后,数据地址计数器加1,并停留在当前位置。这一位置只要不掉电就会一直有效。当R/W = 1时,就可以将当前地址位置的数据读出。

其软件模拟的实现为:


uchar Read_1Byte_currentaddress(void)

{

     uchar temp;

     start();

     write1byte((deviceaddress|0x01));

     if(check())    

        temp = read1byte();

     else

        return 0;

     mnack();

     stop();

     return temp;

}

uchar Read_NByte_currentaddress(uchar * readbuf,uchar n)

{  

    start();

     write1byte((deviceaddress|0x01));

     if(check())

        readNbyte(readbuf,n);

     else

        return 0;

   

     return  1;

}



read1byte()从I2C总线读取一个字节,其软件模拟的实现为:


uchar read1byte(void)

{

     uchar  rdata = 0x00,i;

   uchar flag;

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

     {

            SDA_H;

            _NOP();

            SCL_H;

        SDA_in;

            _NOP();

            flag = SDA_val;

            rdata <<= 1;

            if(flag)   rdata |= 0x01;

        SDA_out;

            SCL_L;

            _NOP();

     }

     return rdata;

}



readNbyte()从I2C总线读取一个字节,其软件模拟的实现为:


void readNbyte(uchar * inbuffer,uchar n)

{

     uchar i;

   

fo


关键字:MSP430平台  AT24C02  读写操作

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32中断向量表的位置.重定向