AT24C02读写C程序

简介:
A.本AT24C01A接口驱动程序的使用非常简单。在你的源程序包含此头文件后你所要做的是:
    1。定义与你单片机所连接的相应口线号(bSda & bScl)、单片机的时钟、通讯速率;
    2。设置你的芯片所连接的地址(A2-A0);你可以对你的芯片编号,比如Chip_1对应一个地址、Chip_2对应另一个地址(AT24家族中最多可以定义8个),访问芯片时你只需带入芯片号,程序便能连接你想要访问的芯片,同时进行读写操作。
B.此驱动程序与你有关的主要内容为:
    1.2个界面涵数<ReadMem(l,x,y);>、<WriteMem(l,x,y)>;
    2.几个宏定义<#define Chip_x(器件号) xx>、<#define Frequency(时钟频率) xx>、
        <#define Speed(通讯速率) xx>;
    3.2个口线定义<sbit bScl =Px^x;、sbit bSda =Px^x;>;
    4.一个缓冲数组<cShareBuf[xx]>,所有读写数据都会经此数组中转(注意页溢出)。
C.你在源程序中调用这里面的涵数相当方便,请看试例;
D.本程序的测试频率为:22.1184.000MHz
注意:
    1.如果在包含此头文件前有其他程序(包括其他程序、头文件里程序)使用了此头文件内的某一涵数、宏等,请将包含此头文件的关键词放置在它前面,或将本头文件内相应申明(或定义)放置于他的前面的任何一个地方甚至于他内部(也可以申明一个专门用于放置一些涵数的申明、宏定义、口线定义的头文件,然后将一些涵数的申明放在内部以实现共用不冲突)
    2.读写的数据都是通过变量数组交换的,所以写之前必须将数据有规律的放置在cShareBuf之中;执行完读功能后在cShareBuf之中取出数据;
    3.本驱动程序包含了从01-512的若干型号,在确定使用型号后和地址,你可以将相关型号选择、芯片地址选择等全部去掉,以节约系统资源,使用时将本文件放置于相应项目文件内,使用#include "AT24Cxx.h";如果你对时间、空间没有什么要求,你可以将本文件放置在系统头文件夹内,然后没有个项目都使用#include <AT24Cxx.h>(也可使用#include "AT24Cxx.h")
1/*Sample:
2/*main(){    ...
3/*  Mem_ReadOut(l,x,y);    /*读。l为本次访问的器件号,在宏定义时分配不同芯片的不同器件号,
4                          x为本次欲读出的字节数;y为本次读数的起始地址*/

5/*  Mem_WriteIn(l,x,y);  /*写。l为本次访问的器件号,在宏定义时分配不同芯片不同的器件号,
6                          x为本次欲写入的字节数;y为本次写数的起始地址,
7/*注:当心页写入的地址规律,即页地址在同一页内滚动;否则会出现页溢出*/

8/*}*/
9

  1/*==============================================================================
  2文件名称:AT24Cxxx.C
  3适用范围:EEPROM芯片AT24Cxx的驱动程序
  4
  5The header files name is AT24Cxx.H
  6include AT24C01/01A/02/04/08/16/32/64/128/256/512
  7
  8
  9 *the header files program's function is link exterior extend E2PROM
10 *the link chip's name is AT24C01A-512
11 * Debug frequency:22.1184MHz
12
13 * Author by: YanDeBao
14 * Modified : 03-09-2007
15 * Version  : V1.0
16==============================================================================*/

17#include  "ZYEL0301.H"  //包含硬件配置文件
18#include  "AT24Cxxx.H"
19
20/* 嵌入宏定义 */
21#define    OSC_freq    24        //MHz,系统时钟振荡频率
22#define    IIC_freq    400      //kHz,IIC总线最大通讯速率
23
24#if OSC_freq == 12
25  #define  Wait_1us {_nop_();};      //在OSC为11.0592或12MHz时
26#elif OSC_freq == 24
27  #define  Wait_1us {_nop_();_nop_();}; //在OSC为20,22.1184或24MHz时
28#elif OSC_freq == 40
29  #define  Wait_1us {_nop_();_nop_();_nop_();_nop_();}  //在OSC为40MHz时
30#endif
31
32#if IIC_freq == 100                //3V系统最高100kHz
33  #define  IIC_Wait {Wait_1us;Wait_1us;Wait_1us;Wait_1us;};
34#elif IIC_freq == 400              //5V系统最高400kHz
35  #define  IIC_Wait {Wait_1us;};
36#endif
37
38#define    AT24C01    0x01
39#define    AT24C01A    0x02
40#define    AT24C02    0x03
41#define    AT24C04    0x04
42#define    AT24C08    0x05
43#define    AT24C16    0x06
44#define    AT24C32    0x07
45#define    AT24C64    0x08
46#define    AT24C128    0x09
47#define    AT24C256    0x0a
48#define    AT24C512    0x0b
49
50#define    cmd_WR      0xa0        /*0000 0000*/
51#define    cmd_RD      0xa1        /*0000 0001*/
52
53#define    Mem_Type    AT24C02    /*01/01A/02/04/08/16/32/64/128/256/512*/
54#define    Dev_Addr    0x00        /*目的器件的器件地址,可以设置8个不同地
55                                    址的芯片使之能用同一段程序进行读写  */
56
57/* 串行引脚定义 ,具体请参照相应的硬件资源配置文件Target.H */
58
59/* 变量声明 */
60bit bScan_Err;
61unsigned char idata cIIC_Buf[9];    /*I2c read and write buffer*/
62
63/* 函数声明 */
64void IIC_Start(void);
65void IIC_End(void);
66unsigned char IIC_Scan();
67void IIC_Send(unsigned char cData);
68void IIC_Send_Ack(void);
69void IIC_Send_NotAck(void);
70void Mem_Write(unsigned char cMem_Type,cDev_Addr,cData_Size,unsigned int cStart_Addr);
71void Mem_Read(unsigned char cMem_Type,cDev_Addr,cData_Size,unsigned int cStart_Addr);
72
73/**********************************************************
74Name    : IIC_Start
75Function: Reset IIC Device
76**********************************************************/

77void IIC_Start(void)
78{
79  bSda=bScl=1;
80  IIC_Wait;IIC_Wait;
81  bSda=0;
82  IIC_Wait;IIC_Wait;
83  bScl=0;
84}

85
86/**********************************************************
87Name    : IIC_End
88Function: Release IIC Device
89**********************************************************/

90void IIC_End(void)
91{
92  bSda=0;
93  bScl=1;
94  IIC_Wait;IIC_Wait;
95  bSda=1;
96}

97
98/**********************************************************
99Name    : IIC_Scan
100Function: Read 1 byte data From IIC Device
101**********************************************************/

102unsigned char IIC_Scan()
103{
104  unsigned char /*idata*/ i,j;
105
106  bSda=1;j=0;
107  for(i=0;i<8;i++){
108    bScl=1;
109    j<<=1;
110    IIC_Wait;
111    j|=bSda;      /*Scan 0*/    /*Scan 1*/
112    bScl=0;
113    IIC_Wait;
114  }

115  return j;
116}

117
118/**********************************************************
119Name    : IIC_Send
120Function: Send 1 byte data to IIC Device
121**********************************************************/

122void IIC_Send(unsigned char cData)
123{
124  unsigned char /*idata*/ i;
125
126  for(i=0;i<8;i++){
127    bSda=(bit)(cData&0x80);
128    bScl=1;
129    cData<<=1;
130    IIC_Wait;
131    bScl=0;
132    IIC_Wait;
133  }

134  bSda=bScl=1;                  /*检测ACK*/
135  for(i=0;(bSda==1)&&(bScan_Err==0);i++)
136  {
137    if(i==30) bScan_Err=1;      /*如果101us没有响应就错误*/
138  }

139  bScl=0;
140}

141
142/**********************************************************
143Name    : IIC_Send_Ack
144Function: Send IIC Ack
145**********************************************************/

146void IIC_Send_Ack(void)
147{
148  bSda=0;bScl=1;
149  IIC_Wait;
150  bScl=0;bSda=1;
151}

152/**********************************************************
153Name    : IIC_Send_NotAck
154Function: Send IIC not Ack
155**********************************************************/

156void IIC_Send_NotAck(void)
157{
158  bScl=bSda=1;
159  IIC_Wait;
160  bScl=0;
161}
   
162
163/**********************************************************
164Name    : Mem_WriteIn
165Function: write data into AT24C01-512
166**********************************************************/

167void Mem_WriteIn(unsigned char cMem_Type,cDev_Addr,cData_Size,unsigned int cStart_Addr)
168{
169  unsigned char /*idata*/ i,cAddress[2];    /*0-L;1-H*/
170
171  bScan_Err=0;
172  cAddress[0]=cStart_Addr;
173  cAddress[1]=cStart_Addr>>8;
174  i  = cmd_WR;
175  i |= cDev_Addr<<1;
176
177  switch(Mem_Type){
178  case AT24C04:              /*匹配地址AT24C16              */
179      i &= 0xfd;
180      i |= cAddress[1]&0x02;    /*根据型号将高地址转为SLA      */
181    break;
182  case AT24C08:              /*匹配地址AT24C08              */
183      i &= 0xf9;
184      i |= cAddress[1]&0x06;    /*根据型号将高地址转为SLA      */
185    break;
186  case AT24C16:              /*匹配地址AT24C04              */
187      i &= 0xf1;
188      i |= cAddress[1]&0x0e;    /*根据型号将高地址转为SLA      */
189    break;
190  default:                    /*匹配地址AT24C01/01A/02/32-512*/
191    i &= 0xf7;
192    break;
193  }

194
195  IIC_Start();
196  IIC_Send(i);                  /*送出SLA:1010 xxx0*/
197  if(cMem_Type>=AT24C32)        /*AT24C 01-16用1个字节地址,32-512用2个字节地址*/
198    IIC_Send(cAddress[1]);      /*先发送高字节地址*/   
199 
200  IIC_Send(cAddress[0]);        /*如果是双字节地址则为低地址否则为高地址*/
201  for(i=0;(bScan_Err==0)&&(i!=cData_Size);i++)
202    IIC_Send(cIIC_Buf[i]);      /*写一个字节数据*/
203  IIC_End();
204}

205
206/**********************************************************
207Name    : Mem_ReadOut
208Function: Read data from AT24C01-512
209**********************************************************/

210void Mem_ReadOut(unsigned char cMem_Type,cDev_Addr,cData_Size,unsigned int cStart_Addr)
211{
212  unsigned char /*idata*/ i,cAddress[2];
213
214 for(i=0;i<sizeof(cIIC_Buf);i++){cIIC_Buf[i]=0x00;}
215
216  bScan_Err=0;
217  cAddress[0]=cStart_Addr;      /*将16位地址分解为高低字节*/
218  cAddress[1]=cStart_Addr>>8;
219