AT24C02

AT24C02A, 2K SERIAL EEPROM:

Internally organized with 32 pages of 8 bytes each,
the 2K requires an 8-bit data word address for random word addressing.

24c02有32个页,每页8字节,本帖中不讨论页写的方式

-------------------------------------------------------------------




 
 

AT24C02内部设有一个8位控制寄存器,其每一位的含义如下: 
Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 
 1      0     1    0    A2   A1   A0  R/W 
其中前4位数据是芯片固定的标识,
A2/A1/A0用于选择总线上待访问的I2C器件,R/W=1读操作,R/W=0写操作;
I2C总线上最多可以扩展8片同样的2K容量EEPROM存储器,
或者是4片4Kb的EEPROM,
或者是2片容量为8Kb的EEPROM存储器。
或者是1片容量为16Kb的EEPROM存储器(此时硬件就固定了,因为A2/A1/A0已经被P2P1P0占用),
如果扩展8片2K以内容量的EEPROM存储器,每片存储器将对应一个地址,
我们的实验板上的AT24C02的A2/A1/A0引脚全部接地,
所以在实验中读写控制字分别为:0xa1/0xa0

 

主芯片stc89c52rc,晶振11.0592M

 

C代码   收藏代码
  1. #include <reg52.h>  
  2. #include "MY51.H"  
  3.   
  4. sbit sda=P2^0;      //总线连接口定义  
  5. sbit scl=P2^1;      //总线连接口定义  
  6.   
  7. void delayus()  //需要4个机器周期,大概4.34us  
  8. {  
  9.     ;                   //晶振频率11.0592M,机器周期为1.085微秒  
  10. }  
  11.   
  12. void iic_start()  //启动信号  
  13. {  
  14.     sda=1;  
  15.     scl=1;  
  16.     delayus();      //sda和scl同为高电平保持4.7us以上  
  17.     _nop_();            //1.085us,共5.78us,下面sda=0是下降沿,不能计算在延时时间中  
  18.     sda=0;          //下降沿  
  19.     delayus();      //sda低电平保持4us以上 ,这里是4.34us满足要求  
  20. }  
  21.   
  22. void iic_stop() //停止信号  
  23. {  
  24.     sda=0;_nop_();  //准备状态  
  25.     scl=1;  
  26.     delayus();      //该状态稳定时间要求保持4us以上  
  27.     sda=1;          //scl高电平期间,sda来一个上升沿  
  28.     delayus();      //sda保持4.7us以上,4.34加上函数返回时间大于4.7us  
  29.                         //注:此时scl和sda都为1      
  30. }  
  31.   
  32. void iic_sendByte(uchar byteData) //mcu发送一个字节  
  33. {  
  34.     uchar i;  
  35.     uchar temp=byteData;  
  36.     for(i=0;i<8;i++)  
  37.     {  
  38.         temp=temp<<1;   //移动后最高位到了PSW寄存器的CY位中  
  39.         scl=0;           //准备  
  40.         _nop_();            //稳定一下  
  41.         sda=CY;          //将待发送的数据一位位的放到sda上  
  42.         _nop_();  
  43.         scl=1;           //每一个高电平期间,ic器件都会将数据取走  
  44.         _nop_();          
  45.     }  
  46.   
  47.     scl=0;              //如果写成scl=1;sda=1就是停止信号,不能这么写  
  48.     _nop_();                  
  49.     sda=1;              //释放总线,数据总线不用时要释放  
  50.     _nop_();  
  51. }  
  52.   
  53. uchar iic_readByte() //读一个字节  
  54. {  
  55.     uchar i,temp;  
  56.     scl=0;              //准备读数据  
  57.     _nop_();  
  58.     sda=1;              //释放总线  
  59.     _nop_();  
  60.   
  61.     for(i=0;i<8;i++)  
  62.     {  
  63.         scl=1;          //mcu开始取数据  
  64.         delayus();      //scl为高电平后,ic器件就会将1位数据送到sda上  
  65.                             //总共用时不会大于4.34us的,然后就可以让mcu读sda了  
  66.         temp=(temp<<1)|sda; //读一位保存到temp中  
  67.         scl=0;  
  68.         delayus();        
  69.     }  
  70.     return temp;  
  71. }  
  72.   
  73. bool iic_checkACK()     //处理应答信号  
  74. {  
  75.     uchar errCounts=255; //定义超时量为255次  
  76.     scl=1;  
  77.     _nop_();  
  78.       
  79.     while(sda)  
  80.     {   //在一段时间内检测到sda=0的话认为是应答信号  
  81.         if(0==errCounts)  
  82.         {  
  83.             scl=0;        //钳住总线  
  84.             _nop_();  
  85.             return false//没有应答信号  
  86.         }  
  87.         errCounts--;  
  88.     }  
  89.   
  90.     scl=0;            //钳住总线,为下1次通信做准备   
  91.     _nop_();  
  92.     return true;      //成功处理应答信号  
  93. }  
  94.   
  95. void iic_init() //总线初始化  
  96. {  
  97.     scl=1;  
  98.     sda=1;  
  99.     delayus();  
  100. }  
  101.   
  102. void iic_sendACK(bool b_ACK)    //发送应答或非应答信号  
  103. {  
  104.     scl=0;          //准备  
  105.     _nop_();  
  106.   
  107.     if(b_ACK)       //ACK  
  108.     {  
  109.         sda=0;  
  110.     }  
  111.     else               //unACK  
  112.     {  
  113.         sda=1;  
  114.     }  
  115.   
  116.     _nop_();  
  117.     scl=1;  
  118.     delayus();      //大于4us的延时  
  119.     scl=0;              //钳住scl,以便继续接收数据      
  120.     _nop_();  
  121. }  
  122.   
  123.   
  124. void AT24C02_writeByte(uchar address,uchar dataByte)//向24c02写一字节数据  
  125. {  
  126.     iic_start();  
  127.     iic_sendByte(0xa0);//mcu写控制字,前4位固定1010,后三位地址0,末位0是写  
  128.     iic_checkACK();        //mcu处理应答信号  
  129.     iic_sendByte(address);  //准备在指定地址处写入      
  130.     iic_checkACK();  
  131.     iic_sendByte(dataByte); //写数据  
  132.     iic_checkACK();  
  133.     iic_stop();  
  134.     delayms(2);   
  135.     //按字节写入时,24c02在接收到停止信号后将数据擦写到内部,这需要时间  
  136.     //并且在这段时间内不会响应总线上的任何请求,故让mcu有2毫秒以上的等待     
  137. }  
  138.   
  139. void AT24C02_writeData(uchar address,uchar numBytes,uchar* buf)//写入任意长度数据  
  140. {  
  141.     while(numBytes--)  
  142.     {  
  143.         AT24C02_writeByte(address++,*buf++);  
  144.     }  
  145. }  
  146.   
  147. void AT24C02_readData(uchar beginAddr,uchar dataSize,uchar* buf)//读取任意长度字节  
  148. {  
  149.     iic_start();                    //起始信号  
  150.     iic_sendByte(0xa0);         //控制字,写  
  151.     iic_checkACK();             //处理应答信号  
  152.     iic_sendByte(beginAddr);    //发送地址  
  153.     iic_checkACK();             //处理应答信号      
  154.     iic_start();                //发送起始信号  
  155.     iic_sendByte(0xa1);         //控制字,读  
  156.     iic_checkACK();             //处理应答信号  
  157.     while(dataSize--)               //读取dataSize个字节  
  158.     {  
  159.         *buf++=iic_readByte();  //读取一个个字节并保存到缓冲区buf中  
  160.         iic_sendACK(dataSize);  //发送应答,当dataSize为0时发送非应答  
  161.     }  
  162.     iic_stop();                     //发送停止信号  
  163. }  
  164.   
  165. void main()  
  166. {  
  167.     uchar buf[2];                   //接受数据的缓冲区  
  168.     uchar arr[34]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,               //0x00-0x0f  
  169.                         16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,//0x10-0x1f  
  170.                         32,0x55};                                                   //0x20-0x21  
  171.     iic_init();                                         //总线初始化  
  172.     //AT24C02_writeByte(0x08,0x11);             //向指定地址处写入一个字节数据,代码测试  
  173.     AT24C02_writeData(0x00,sizeof(arr),arr);    //向指定地址处开始写入34字节的数据  
  174.     AT24C02_readData(0x20,sizeof(buf),buf);   //从指定地址开始读2个字节  
  175.     P1=buf[1];  //buf中的第二个元素就是arr中的最后一个数据0x55  
  176.                                               
  177.     while(1){P1=~P1;delayms(500);} //将这个0x55用led灯显示出来10101010变化  
  178. }  

 

C代码   收藏代码
  1. my51.h头文件中主要用到  
  2. #include <intrins.h>  
  3. typedef unsigned char  uchar ;  
  4.   
  5. void delayms(uint16 ms)  //软延时函数  
  6. {  
  7.     uint16 i,j;  
  8.     for(i=ms;i>0;i--)  
  9.     {  
  10.         for(j=113;j>0;j--)  
  11.         {}  
  12.     }  
  13. }  

  

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值