网站导航: 首页 > 设计参考 > 正文 文章搜索
AT24XX(AT24C01~AT24C256) 的接口程序(C51)
 
文章编号:
091114225733
文章分类: 单片机 51系列
点 击:
...
关 键 词: AT24XX,AT24C01,AT24C256,EEPROM
文章来源:
网络
摘 要:

 
  1. /* 以下为AT24C01~AT24C256的读写程序,各人可根据自己的需要应用。  
  2. 在buf1中填入需要写入的内容,buf2的大小可根据需要定义。  
  3. addr可根据使用的芯片选择,可从任何位置读写,只要在该芯片的范围内。  
  4. enumer=ATxxx,根据使用的芯片赋值。各函数中的形式参数不需改变。  
  5. 本程序只要在调用的程序中定义实际参数即可,下述各子程序不必改动。*/  
  6.   
  7. #include <reg52.h>   
  8. #include <intrins.h>   
  9. #define  ERROR 10     //允许ERROR的最大次数          
  10. sbit     SDA=P3^0;   
  11. sbit     SCL=P3^1;   
  12. enum  eepromtype {AT2401,AT2402,AT2404,AT2408,AT2416,AT2432,AT2464,AT24128,AT24256};/*器件的型号*/  
  13. enum  eepromtype enumer;   //定义一个枚举变量   
  14. unsigned char code buf1 []={1,3,5,7,9,10,11,12,13,15}; /* 发送缓冲区 */  
  15. unsigned char buf2 [10]; /* 接收缓冲区 */  
  16.   
  17.                          /* 一个通用的24C01-24C256共9种EEPROM的字节读写操作程序,  
  18.                          此程序有五个入口条件,分别为读写数据缓冲区指针,  
  19.                          进行读写的字节数,EEPROM首址,EEPROM控制字节,  
  20.                          以及EEPROM类型。此程序结构性良好,具有极好的容错性,程序机器码也不多:  
  21.                          DataBuff为读写数据输入/输出缓冲区的首址  
  22.                          Length 为要读写数据的字节数量  
  23.                          Addr 为EEPROM的片内地址 AT24256为0~32767  
  24.                          Control 为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,  
  25.                          表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;  
  26.                          enumer为枚举变量,需为AT2401至AT24256中的一种,分别对应AT24C01至AT24C256;  
  27.                          函数返回值为一个位变量,若返回1表示此次操作失效,0表示操作成功;  
  28.                          ERROR为允许最大次数,若出现ERRORCOUNT次操作失效后,则函数中止操作,并返回1  
  29. SDA和SCL由用户自定义,这里暂定义为P3^0和P3^1; */  
  30. /*对于1K位,2K位,4K位,8K位,16K位芯片采用一个8位长的字节地址码,对于32K位以上  
  31. 的采用2个8位长的字节地址码直接寻址,而4K位,8K位,16K位配合页面地址来寻址*/  
  32.   
  33. /* -----  AT24C01~AT24C256 的读写程序 ------ */  
  34. bit   RW24xx(unsigned char *DataBuff,unsigned char Length,unsigned int Addr,   
  35.              unsigned char Control,enum eepromtype enumer)   
  36. {   
  37.     void Delay(unsigned char DelayCount);  /*   延时   */  
  38.     void Start(void);  /*   启动总线   */  
  39.     void Stop(void);   /*   停止IIC总线   */  
  40.     bit  RecAck(void); /*   检查应答位   */  
  41.     void NoAck(void);  /*   不对IIC总线产生应答   */  
  42.     void Ack(void);    /*   对IIC总线产生应答   */  
  43.     unsigned char Receive(void); /*   从IIC总线上读数据子程序  */  
  44.     void Send(unsigned char sendbyte); /*   向IIC总线写数据   */  
  45.     unsigned char data j,i=ERROR;   
  46.     bit errorflag=1;  /*   出错标志   */  
  47.     while(i--)   
  48.     {   
  49.         Start();  /*   启动总线   */  
  50.         Send(Control & 0xfe); /*   向IIC总线写数据,器件地址 */  
  51.         if(RecAck()) continue/*   如写不正确结束本次循环   */  
  52.         if(enumer > AT2416)   
  53.         {   
  54.             Send((unsigned char)(Addr >> 8));//把整型数据转换为字符型数据:弃高取低,只取低8位.如果容量大于32K位,使用16位地址寻址,写入高八位地址   
  55.             if(RecAck())  continue;   
  56.         }   
  57.         Send((unsigned char)Addr); /*   向IIC总线写数据   */  
  58.         if(RecAck())  continue/*   如写正确结束本次循环   */  
  59.         if(!(Control & 0x01))   //判断是读器件还是写器件   
  60.         {   
  61.             j=Length;   
  62.             errorflag=0;         /* 清错误特征位 */  
  63.             while(j--)   
  64.             {   
  65.                 Send(*DataBuff++); /*   向IIC总线写数据   */  
  66.                 if(!RecAck()) continue/*   如写正确结束本次循环   */  
  67.                 errorflag=1;   
  68.                 break;   
  69.             }   
  70.             if(errorflag==1) continue;   
  71.             break;   
  72.         }   
  73.         else  
  74.         {   
  75.             Start();  /*   启动总线   */  
  76.             Send(Control); /*   向IIC总线写数据   */  
  77.             if(RecAck()) continue;//器件没应答结束本次本层循环   
  78.             while(--Length)  /*   字节长为0结束   */  
  79.             {    
  80.                 *DataBuff ++= Receive();   
  81.                 Ack();   /*   对IIC总线产生应答   */  
  82.             }   
  83.             *DataBuff=Receive(); /* 读最后一个字节 */  
  84.             NoAck();  /*   不对IIC总线产生应答   */  
  85.             errorflag=0;   
  86.             break;   
  87.         }   
  88.     }   
  89.     Stop();  /*   停止IIC总线   */  
  90.     if(!(Control & 0x01))   
  91.     {    
  92.         Delay(255); Delay(255); Delay(255); Delay(255);   
  93.     }   
  94.     return(errorflag);   
  95. }   
  96.   
  97. /* * * * * 以下是对IIC总线的操作子程序 * * * * */  
  98. /* * * * * * 启动总线 * * * * */  
  99. void Start(void)   
  100. {   
  101.     SCL=0; /* SCL处于高电平时,SDA从高电平转向低电平表示 */  
  102.     SDA=1; /* 一个"开始"状态,该状态必须在其他命令之前执行 */  
  103.     SCL=1;   
  104.     _nop_(); _nop_(); _nop_();   
  105.     SDA=0;   
  106.     _nop_(); _nop_(); _nop_(); _nop_();   
  107.     SCL=0;   
  108.     SDA=1;        
  109. }   
  110.   
  111. /* * * * * 停止IIC总线 * * * * */  
  112. void Stop(void)   
  113. {    
  114.     SCL=0; /*SCL处于高电平时,SDA从低电平转向高电平 */  
  115.     SDA=0; /*表示一个"停止"状态,该状态终止所有通讯 */  
  116.     SCL=1;   
  117.     _nop_(); _nop_(); _nop_(); /* 空操作 */  
  118.     SDA=1;   
  119.     _nop_(); _nop_(); _nop_();   
  120.     SCL=0;   
  121. }   
  122.   
  123. /* * * * * 检查应答位 * * * * */  
  124. bit RecAck(void)   
  125. {   
  126.     SCL=0;   
  127.     SDA=1;   
  128.     SCL=1;   
  129.     _nop_(); _nop_(); _nop_(); _nop_();   
  130.     CY=SDA;     /* 因为返回值总是放在CY中的 */  
  131.     SCL=0;   
  132.     return(CY);   
  133. }   
  134.   
  135. /* * * * *对IIC总线产生应答 * * * * */  
  136. void Ack(void)   
  137. {    
  138.     SDA=0; /* EEPROM通过在收到每个地址或数据之后, */  
  139.     SCL=1; /* 置SDA低电平的方式确认表示收到读SDA口状态 */  
  140.     _nop_(); _nop_(); _nop_(); _nop_();   
  141.     SCL=0;   
  142.     _nop_();   
  143.     SDA=1;   
  144. }   
  145.   
  146. /* * * * * * * * * 不对IIC总线产生应答 * * * * */  
  147. void NoAck(void)   
  148. {   
  149.     SDA=1;   
  150.     SCL=1;   
  151.     _nop_(); _nop_(); _nop_(); _nop_();   
  152.     SCL=0;   
  153. }   
  154.   
  155. /* * * * * * * * * 向IIC总线写数据 * * * * */  
  156. void Send(unsigned char sendbyte)   
  157. {    
  158.     unsigned char data j=8;   
  159.     for(;j>0;j--)   
  160.     {    
  161.         SCL=0;   
  162.         sendbyte <<= 1; /* 使CY=sendbyte^7; */  
  163.         SDA=CY; /* CY 进位标志位 */  
  164.         SCL=1;   
  165.     }   
  166.     SCL=0;   
  167. }   
  168.   
  169. /* * * * * * * * * 从IIC总线上读数据子程序 * * * * */  
  170. unsigned char Receive(void)   
  171. {    
  172.     register receivebyte,i=8;   
  173.     SCL=0;   
  174.     while(i--)   
  175.     {    
  176.         SCL=1;   
  177.         receivebyte = (receivebyte <<1 ) | SDA;   
  178.         SCL=0;   
  179.     }   
  180.     return(receivebyte);   
  181. }   
  182.   
  183. /* * * * * * * * 一个简单延时程序 * * * * * * * * * * * * */  
  184. void Delay(unsigned char DelayCount)   
  185. {    
  186.     while(DelayCount--);   
  187. }   
  188.   
  189. /* -----  AT24C01~AT24C256 的读写程序 ------ */  
  190. void main()   
  191. {    
  192.     unsigned char Control,*p1,*p2;   
  193.     unsigned char Length;   
  194.     unsigned int addr ; /* 24Cxx片内地址 */  
  195.     p1=buf1;p2=buf2;   
  196.     addr=0; /* 片内地址 AT24C256为0~32767 */  
  197.     Length=8; /* 读写长度 */  
  198.     enumer=AT24256; /* 读写AT24C256 */  
  199.     Control=0xa0; /* 写操作 */  
  200.     RW24xx(p1,Length,addr,Control,enumer); /* 写 */  
  201.     Control=0xa1; /* 读操作 */  
  202.     RW24xx(p2,Length,addr,Control,enumer); /* 读 */  
  203. }   

 

 
相关文章:

 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4