简介:
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
5
The header files name is AT24Cxx.H
6
include 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
/**//* 变量声明 */
60
bit bScan_Err;
61
unsigned char idata cIIC_Buf[9]; /**//*I2c read and write buffer*/
62
63
/**//* 函数声明 */
64
void IIC_Start(void);
65
void IIC_End(void);
66
unsigned char IIC_Scan();
67
void IIC_Send(unsigned char cData);
68
void IIC_Send_Ack(void);
69
void IIC_Send_NotAck(void);
70
void Mem_Write(unsigned char cMem_Type,cDev_Addr,cData_Size,unsigned int cStart_Addr);
71
void Mem_Read(unsigned char cMem_Type,cDev_Addr,cData_Size,unsigned int cStart_Addr);
72
73
/**//**********************************************************
74
Name : IIC_Start
75
Function: Reset IIC Device
76
**********************************************************/
77
void 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
/**//**********************************************************
87
Name : IIC_End
88
Function: Release IIC Device
89
**********************************************************/
90
void IIC_End(void)
91
...{
92
bSda=0;
93
bScl=1;
94
IIC_Wait;IIC_Wait;
95
bSda=1;
96
}
97
98
/**//**********************************************************
99
Name : IIC_Scan
100
Function: Read 1 byte data From IIC Device
101
**********************************************************/
102
unsigned 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
/**//**********************************************************
119
Name : IIC_Send
120
Function: Send 1 byte data to IIC Device
121
**********************************************************/
122
void 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
/**//**********************************************************
143
Name : IIC_Send_Ack
144
Function: Send IIC Ack
145
**********************************************************/
146
void IIC_Send_Ack(void)
147
...{
148
bSda=0;bScl=1;
149
IIC_Wait;
150
bScl=0;bSda=1;
151
}
152
/**//**********************************************************
153
Name : IIC_Send_NotAck
154
Function: Send IIC not Ack
155
**********************************************************/
156
void IIC_Send_NotAck(void)
157
...{
158
bScl=bSda=1;
159
IIC_Wait;
160
bScl=0;
161
}
162
163
/**//**********************************************************
164
Name : Mem_WriteIn
165
Function: write data into AT24C01-512
166
**********************************************************/
167
void 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
/**//**********************************************************
207
Name : Mem_ReadOut
208
Function: Read data from AT24C01-512
209
**********************************************************/
210
void 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
