找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3481|回复: 1
打印 上一主题 下一主题
收起左侧

关于AT24C02芯片的读写问题详解,基于TX-1C单片机开发板

[复制链接]
跳转到指定楼层
楼主
ID:285031 发表于 2018-5-6 12:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作为基础入门级的TX-1C开发板,里面有AT24C02芯片,在编写程序时很多童鞋无法顺利使用该芯片。
我作为初学者也是捣鼓了两天,在详细阅读了datasheet之后,终于明白症结所在,在这里和大家分享一下。

TX-1C的开发板,都已经焊接好电路,需要我们做的只是写一下驱动程序。

该芯片可以采用IIC总线进行操作。时序图请大家参照datasheet(附件),之前很多童鞋遇到时序图写对但是数据读写错误的问题。
我也遇到了,这里应该注意芯片每次字节写操作(byte write opeartion)完成后,需要10ms的延时,用于芯片内部把数据转化为不可擦除的。这段期间芯片对读写信号是不响应的。如果这段时间进行读数据操作,就会出现错误。

另外,对于AT24C02芯片,2Kbit的EEPROM,也就是256Byte的大小,数据地址从0x00-0xff。需要注意的是,这个芯片是每8byte是一页,一共32页,这个在字节写操作(byte write opeartion)里面没影响,但是如果你想连续进字节,就需要注意了(AT24C04及以上型号都是16byte一页)。在页写操作里面
(page write opeartion),一次连续写只能写一页(8byte),只是因为芯片内部每写完一个字节,数据地址就自加1,但是写到这一页的结尾,指针就会调到这一页的开头,而不是跳到下一页的开头,如果继续写,就会覆盖前面的数据。写完这一页就要stop,在延时10ms,转化为不可擦除数据。之后,重新开始start,写下一页。这是非常需要注意的。



读操作没有这个问题,字节读取不需要延时10ms(读不需要不可擦除的转化),如果连续读也不存在页的问题,因为读完一个字节,地址指针会跳到下一个字节,从0x00一直到0xff(我想是因为在写操作的时候芯片需要转化为不可擦除的过程限制,芯片可能没有办法把0x00-0xff这么多字节一次性都转化为不可擦除的,所以才需要分页写)。



好了,要点已经讲完(以上都是在datasheet,write/read operation上看到的,如果没看明白可以参考原文),上代码了。

代码有点长,但是非常robust!!里面把ByteWrite,PageWrite,RandRead,SeqRead的代码都写进去,而且返回值是表示操作状态

0表示操作错误,1表示操作正确,Read出来的数据都存在了外部变量AT24C02_data[]数组里面,我定义的最大容量是30,大家可以根据需要自己更改。

经过封装以后可以直接作为AT24C02的驱动函数。

main函数是我写的测试函数,如果读写过程有错误会有很长的蜂鸣器,如果正确,每个周期后会有短促的蜂鸣。希望对大家有啊帮助。

单片机源码:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define MAXIUM 30
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6.    
  7. sbit SDA=P2^0;
  8. sbit SCL=P2^1;
  9. sbit beep=P2^3;

  10. uchar AT24C02_data[MAXIUM];

  11. void delay(uint ms){
  12.     uint j,k;
  13.     for(j=ms;j>0;j--)
  14.         for(k=110;k>0;k--);
  15. }
  16. void nop(){
  17.     _nop_();
  18.     _nop_();
  19. }
  20. void AT24C02_Start(){
  21.     SDA=1;
  22.     nop();
  23.     SCL=1;
  24.     nop();
  25.     SDA=0;
  26.     nop();
  27.     SCL=0;
  28.     nop();
  29. }
  30. void AT24C02_Stop(){
  31.     SDA=0;
  32.     nop();
  33.     SCL=1;
  34.     nop();
  35.     SDA=1;
  36.     nop();
  37.     SCL=0;
  38.     nop();
  39. }

  40. void AT24C02_SendAck(){
  41.     SDA=0;
  42.     nop();
  43.     SCL=1;
  44.     nop();
  45.     SCL=0;
  46.     nop();
  47.     SDA=1;
  48.     nop();
  49. }

  50. uchar AT24C02_RecAck(){
  51.     uchar i,flag;
  52.     flag=0;
  53.     i=0;
  54.     SCL=1;
  55.     nop();
  56.     while((SDA==1)&&(i<255)) i++;
  57.     if(i==255) flag=1;
  58.     SCL=0;
  59.     nop();
  60.     return flag;
  61. }
  62. void AT24C02_Write(uchar dat){
  63.     uchar i,temp;
  64.     temp=dat;
  65.     for(i=0;i<8;i++){
  66.         temp=temp<<1;
  67.         SDA=CY;
  68.         nop();
  69.         SCL=1;
  70.         nop();
  71.         SCL=0;
  72.         nop();
  73.     }
  74.     SDA=1; nop();
  75. }
  76. uchar AT24C02_Read(){
  77.     uchar i,temp;
  78.     for(i=0;i<8;i++){
  79.         SCL=1;
  80.         nop();
  81.         temp=(temp<<1)|SDA;
  82.         SCL=0;
  83.         nop();
  84.     }
  85.     return temp;
  86. }
  87. //Return data is the state(0 means fault, 1 means success);
  88. uchar AT24C02_ByteWrite(uchar add, uchar dat){
  89.     uchar flag;
  90.     flag=0;
  91.     AT24C02_Start();
  92.     AT24C02_Write(0xa0);
  93.     if(!AT24C02_RecAck()){
  94.         AT24C02_Write(add);
  95.         if(!AT24C02_RecAck()){
  96.             AT24C02_Write(dat);
  97.             if(!AT24C02_RecAck()) flag=1;
  98.         }
  99.     }
  100.     AT24C02_Stop();
  101.     delay(10);
  102.     return flag;
  103. }
  104. //data word add(0x00-0xff) must be divided by 8(32 in total);
  105. //*p points to 8 uchar array;
  106. //Return data is the state(0 means fault, 1 means success);

  107. uchar AT24C02_PageWrite(uchar add, uchar *dat){
  108.     uchar flag;
  109.     uchar i, *p;
  110.     flag=0;
  111.     p=dat;
  112.     AT24C02_Start();
  113.     AT24C02_Write(0xa0);
  114.     if(!AT24C02_RecAck()){
  115.         AT24C02_Write(add);
  116.         if(!AT24C02_RecAck()){
  117.             for(i=0;i<8;i++){
  118.                 AT24C02_Write(*(p+i));
  119.                 if(AT24C02_RecAck()) break;  
  120.             }
  121.             if(i==8) flag=1;
  122.         }
  123.     }
  124.     AT24C02_Stop();
  125.     delay(10);
  126.     return flag;
  127. }

  128. //Data is saved in external variable AT24C02_data[0];
  129. //Return data is the state(0 means fault, 1 means success);
  130. uchar AT24C02_RandRead(uchar add){
  131.     uchar flag;
  132.     flag=0;
  133.     AT24C02_Start();
  134.     AT24C02_Write(0xa0);
  135.     if(!AT24C02_RecAck()){
  136.         AT24C02_Write(add);
  137.         if(!AT24C02_RecAck()){
  138.             AT24C02_Start();
  139.             AT24C02_Write(0xa1);
  140.             if(!AT24C02_RecAck()){
  141.                 AT24C02_data[0]=AT24C02_Read();
  142.                 AT24C02_Stop();
  143.                 flag=1;
  144.             }
  145.         }
  146.     }
  147.     return flag;
  148. }
  149. //Data is saved in external variable AT24C02_data[0],maxium num is 30;
  150. //Return data is the state(0 means fault, 1 means success;

  151. uchar AT24C02_SeqRead(uchar add,uchar num){
  152.     uchar i,flag;
  153.     flag=0;
  154.     AT24C02_Start();
  155.     AT24C02_Write(0xa0);
  156.     if(!AT24C02_RecAck()){
  157.         AT24C02_Write(add);
  158.         if(!AT24C02_RecAck()){
  159.             AT24C02_Start();
  160.             AT24C02_Write(0xa1);
  161.             if(!AT24C02_RecAck()){
  162.                 for(i=0;i<num-1;i++){
  163.                     AT24C02_data[ i]=AT24C02_Read();
  164.                     AT24C02_SendAck();
  165.                 }
  166.                 AT24C02_data[ i]=AT24C02_Read();
  167.                 AT24C02_Stop();
  168.                 flag=1;
  169.             }
  170.         }
  171.     }
  172.     return flag;
  173. }


  174. void main(){
  175.     uchar i;
  176.     uchar array[8]={1,2,3,4,5,6,7,8};
  177.    
  178.     for(i=0;i<MAXIUM;i++) AT24C02_data[ i]=0;
  179.     P1=0x00;
  180.     delay(1000);
  181.    
  182.     if(AT24C02_ByteWrite(0x00,0xff)){
  183.         if(!AT24C02_RandRead(0x00)){
  184.             beep=0;
  185.             delay(2000);
  186.             beep=1;
  187.         }
  188.     }
  189.     else{
  190.         beep=0;
  191.         delay(1000);
  192.         beep=1;
  193.     }
  194.     P1=AT24C02_data[0];
  195.     delay(1000);
  196.    
  197.     if(AT24C02_PageWrite(0x00,array)){
  198.         if(!AT24C02_SeqRead(0x00,8)){
  199.             beep=0;
  200.             delay(2000);
  201.             beep=1;
  202.         }
  203.     }
  204.     else{
  205.         beep=0;
  206.         delay(1000);
  207.         beep=1;
  208.     }
  209.     while(1){
  210.         for(i=0;i<8;i++){
  211.             P1=AT24C02_data[ i];
  212.             delay(1000);
  213.         }
  214.         beep=0;
  215.         delay(100);
  216.         beep=1;
  217.     }
  218. }
复制代码


资料下载:
00_AT24C02A.pdf (184.52 KB, 下载次数: 11)


评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:285031 发表于 2018-5-6 12:47 | 只看该作者
自己抢沙发。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表