编写好 I2C 数据读写函数, 下面就可以编写 AT24CXX 的读写函数, 代码如下: - /****************************************************************3 l1 X4 n* X w5 T# \! e% M- [
- * 函 数 名 : AT24CXX_ReadOneByte
' n! g0 ~2 O9 J1 H5 y - * 函数功能 : 在AT24CXX 指定地址读出一个数据
* ]% q2 A4 h; C; V+ N; Y& B6 ^; i - * 输 入 : ReadAddr:开始读数的地址5 n- I* q* F' Z8 e( ]
- * 输 出 : 读到的数据
$ R, I: c k$ l; ~5 V - *****************************************************************/
+ T- E7 B6 h* ~ - u8 AT24CXX_ReadOneByte(u16 ReadAddr)
& A, c( O& ]/ J- l9 X2 Z. R$ _" K0 j - {# J0 [2 ]$ R% q( H D- @4 ]
- u8 temp=0;+ V- o! q. L# Q( J$ o
- IIC_Start();
' t }" V. D8 X+ m* K5 ^ - if(EE_TYPE>AT24C16)
3 `+ B7 g5 Y7 d0 c& r) o - {
; I/ p/ W/ e& R/ c - IIC_Send_Byte(0XA0); //发送写命令
5 p S& _6 L+ W - IIC_Wait_Ack();) i2 d q" h6 _( ~+ r7 a
- IIC_Send_Byte(ReadAddr>>8);//发送高地址' P( C6 G+ b9 B/ U( Z$ H$ n
- }" a0 D9 J1 z" x' z! v# f, W8 p6 Y
- else3 u/ O: q/ K6 X+ J0 q+ p) M
- {
6 m8 G) _! \: k - IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据/ m c- k0 N, o5 j
- }
5 `0 ?) B: n" f! X7 c, [ - IIC_Wait_Ack();5 |4 U9 D$ ]/ q
- IIC_Send_Byte(ReadAddr%256); //发送低地址
, B$ R# V# f8 D. x4 r( ?( { - IIC_Wait_Ack();
& p1 n/ `5 ?7 Z& q. N - IIC_Start();
( P, o+ q# v+ r5 d$ R {( e - IIC_Send_Byte(0XA1); //进入接收模式
& W" r8 d" {3 v' P( b - IIC_Wait_Ack();. C, M( R l" a7 S5 w# |
- temp=IIC_Read_Byte(0);
) t7 d' S5 Q$ ~; S4 w$ I - IIC_Stop();//产生一个停止条件: j. O" g6 g5 I- Q& @- M. @8 J
- return temp;" k! p# Y+ x: p" Z; n) u' U0 h
- }
复制代码- /****************************************************************
/ _+ T1 @7 g8 |( E: e; K - * 函 数 名 : AT24CXX_WriteOneByte
; Q9 D4 L/ B8 u - * 函数功能 : 在AT24CXX 指定地址写入一个数据
& y: I$ E, Q+ j+ R: ~ - * 输 入 : WriteAddr :写入数据的目的地址DataToWrite:要写入的数据
; m. J7 a; F/ `) i' B3 X5 ~ - * 输 出 : 无
- E4 o2 h, t2 e - *****************************************************************/
7 }( l$ x5 R2 t' A - void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
( |9 y& j M+ |1 `& c/ s% c - {' j7 S& N( S4 F! C
- IIC_Start();0 z8 c7 l- I/ w' V
- if(EE_TYPE>AT24C16)4 v/ ~8 {& s+ G5 |8 `. ?
- {4 p6 ^: h/ k9 ~, H% A8 @5 X
- IIC_Send_Byte(0XA0); //发送写命令+ t9 h8 y& }8 X+ W: a+ q( K* q
- IIC_Wait_Ack();7 Z; T* }, X1 l1 w: ^; k# P: E- L
- IIC_Send_Byte(WriteAddr>>8);//发送高地址
8 e% C" B8 J, v9 ~ - }. X7 a- B: A; A+ W
- else
/ j) {: C' p5 z7 o; ` - {7 j' {5 [6 y/ V# V6 b
- IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据/ V* R2 w# K5 B
- }
" f8 Q/ n8 T }: I# P) ^2 W5 c - IIC_Wait_Ack();3 D! ^: `: @1 m4 y
- IIC_Send_Byte(WriteAddr%256); //发送低地址# ^" C* ^: E, z" H7 u
- IIC_Wait_Ack();
7 O! d7 ]4 Y {. \ ` - IIC_Send_Byte(DataToWrite); //发送字节 C! F) R0 J$ U+ I5 U+ X( v
- IIC_Wait_Ack();
7 w) A2 S2 H: v) m6 y0 X. m - IIC_Stop();//产生一个停止条件2 B% \9 \! F7 {
- delay_ms(10);# E2 A+ x8 [* y0 N" }
- }
复制代码- /****************************************************************
6 i G( g' C/ J& w+ v7 F. G; u( }2 Q - * 函 数 名 : AT24CXX_WriteLenByte
2 U8 c4 |# n [+ V6 V6 y2 h - * 函数功能 : 在 AT24CXX 里面的指定地址开始写入长度为 Len的数据用于写入 16bit 或者 32bit 的数据# O/ e7 `: I+ b
- * 输 入 : WriteAddr :写入数据的目的地址! F; v/ I4 ~ @ w3 |* F
- DataToWrite:要写入的数据" s1 u# ]( ], F$ C. P
- Len :要写入数据的长度 2,4
$ F' c% Z- J. w! W - * 输 出 : 无4 h2 A E8 E) a/ b. M5 C$ ?
- *****************************************************************/+ K3 `) q h- O% A1 @
- void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
+ ], h6 D( D+ G - { H3 B4 N7 d+ }8 x) G3 w' G& {
- u8 t;+ L4 A' }8 `: {8 m: T- |
- for(t=0;t<Len;t++)7 d- x5 I$ N! {* p7 h# d1 D
- {1 h; Q/ V- B- e/ n; x5 Q5 K- b4 j
- AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
7 W" p7 a& N% N0 U2 d* G$ K - }# E. X7 {! A% Z; D$ T1 @) E/ ?3 ~
- }
复制代码- /****************************************************************
9 w1 J& A& V* E! m' Y - * 函 数 名 : AT24CXX_ReadLenByte k4 ^6 e( Y; g: ?- U6 c% g" C6 T# t$ n
- * 函数功能 : 在 AT24CXX 里面的指定地址开始读出长度为 Len的数据用于读出 16bit 或者 32bit 的数据1 _( K$ {( k) X" H4 t
- * 输 入 : ReadAddr :开始读出的地址
* I. t7 n1 g4 P2 F - Len :要读出数据的长度 2,4
: ~! T# Q% y% p - * 输 出 : 读取的数据
b, s' |. A4 x* j - *****************************************************************/, \2 d& L: J7 k! b. h& K
- u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len): w0 [/ B( M" ^# W- ^( N' W
- {
2 k) b5 S% }) }# C# c$ {) j - u8 t;& L) u' u; S/ `+ w* u% K
- u32 temp=0;
+ `. |/ J: M, @ k - for(t=0;t<Len;t++)7 P" @& x6 c. y! X; ]
- {
! y2 G& Q9 f$ U' i7 U* z - temp<<=8;# t# W( V7 [ h& U" B$ k
- temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
1 m; y! F$ @7 u8 Y. Z' M" J2 f - }/ r8 I8 {5 f& t+ K% z0 [
- return temp;) v. R8 L: i1 b: G G; e# U; S$ z
- }
复制代码- /****************************************************************
6 s, v8 l# \ ~2 T - * 函 数 名 : AT24CXX_Check1 Z. D2 G5 P( O
- * 函数功能 : 检查 AT24CXX 是否正常
7 |, D [% W1 L9 l8 y - * 输 入 : 无2 j2 {6 z2 R S: p5 H
- * 输 出 : 1:检测失败,0:检测成功
0 a2 x- f2 x: G6 Q9 z0 y/ M - *****************************************************************/
$ c7 S) A1 t5 [* c - u8 AT24CXX_Check(void)
+ `- P/ ^. L7 F. r" p, h - {, O2 N' M& l' d
- u8 temp;
1 R+ F7 e' P: L7 _ - temp=AT24CXX_ReadOneByte(255);//避免每次开机都写 AT24CXX& { F! k1 H& s( u+ G
- if(temp==0x36)return 0;7 ]0 A! H, l2 i- E: @" U
- else//排除第一次初始化的情况/ G) O/ e; y" P) a7 p5 c" x
- {3 f( t7 ^& H) S0 ~ s2 R
- AT24CXX_WriteOneByte(255,0X36);3 {+ d( j0 i" M7 p* I! I
- temp=AT24CXX_ReadOneByte(255);! ]7 `. J7 ?3 F% I3 r' p: E; q
- if(temp==0X36)return 0;
% A/ m$ n, p4 Z2 u: ` - }
2 b5 D* L4 O5 |* ?, N" V" L$ p - return 1;
' S% Q, A, w1 u2 c$ x - }
复制代码- /**************************************************************** X# B, ^ X9 |6 m) w5 N# r
- * 函 数 名 : AT24CXX_Read
0 q# d+ Z4 x( i' `2 I/ o2 y9 e6 j - * 函数功能 : 在 AT24CXX 里面的指定地址开始读出指定个数的数据
' v/ x0 |% a1 O8 q - * 输 入 : ReadAddr :开始读出的地址 对 24c02为0~255
& i) p+ W5 d1 S - pBuffer :数据数组首地址
1 U8 s- u. ]2 M* s- ] - NumToRead:要读出数据的个数9 T E4 E* Y7 w+ V d- ?0 y3 A( H! c
- * 输 出 : 无" l) _: q* g9 L7 ^+ a' A
- *****************************************************************/- X, B+ _6 ]' M9 Y
- void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)6 B/ g$ j' S) f$ u! i$ t' F
- {: B9 \; f& r% ]. l# T- S" |# i
- while(NumToRead)
' ]+ P% z2 p7 K' ]% w0 A m; K - {
: o, {7 S0 P2 g8 R. _1 I2 h+ h - *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);/ D+ E& g: `) H, A) F8 N' G
- NumToRead--;' H% M) x& f' K+ v8 X! I
- }' U9 c/ b6 A0 y. O- Y f2 D
- }
复制代码- /****************************************************************! t" X" j1 {# ?% S, a$ [0 h& t* d# M s
- * 函 数 名 : AT24CXX_Write
! R& T8 R( z* W2 t( S - * 函数功能 : 在 AT24CXX 里面的指定地址开始写入指定个数的数据
+ l& p8 `. S0 e: j% f - * 输 入 : WriteAddr :开始写入的地址 对 24c02为0~255
1 |4 s4 S m& s7 a O - pBuffer :数据数组首地址
0 N8 r8 x+ Z2 d - NumToRead:要读出数据的个数; |' G' v) r9 ~$ P
- * 输 出 : 无
1 P" n" n' Y: X - *****************************************************************/; u. ~* d( S# J4 }* Z1 N) Q+ {
- void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
. _, L2 ]; T4 l5 T W& s - {$ c( D8 _* {" |) d I
- while(NumToWrite--)
, h ~) I' f/ d, V# X$ O5 N - {! c* r3 I* C. z: z! {8 i+ I) c# v
- AT24CXX_WriteOneByte(WriteAddr,*pBuffer);6 g* w& i: l, g8 H* w3 J
- WriteAddr++;) K& r- B$ V; `; C2 \! \8 f* G( {
- pBuffer++;; I5 g$ H0 X7 J# r& a
- }
, k; e, _3 }- T; o6 X# x6 Z1 k' D - }
复制代码 这部分函数在 24cxx.c文件内,这个文件支持 AT24CXX 系列的很多芯片,可通过 24cxx.h 文件内的 EE_TYPE宏来修改,可修改的宏定义如下: - #define AT24C01 127# q& i/ P1 K6 O4 U; W A
- #define AT24C02 2551 T2 D h2 o$ m# y. M$ u( F* |
- #define AT24C04 511& q. F* O( z- ~0 X1 A! s6 o1 r
- #define AT24C08 1023
* C7 Y) ]0 G5 h' g4 a! a - #define AT24C16 2047
7 @4 z# C" j) m - #define AT24C32 4095
6 A% ]% N% Z1 @0 C$ Q d - #define AT24C64 8191
! @+ {* n+ ?5 s7 k0 g1 z; M5 q' C' U$ @ - #define AT24C128 16383
0 d- p5 y& t) R7 v+ t( e - #define AT24C256 32767
复制代码
o0 h6 O, {, a4 [: ?
由于我们开发板上使用的是 AT24C02,所以宏定义默认是: # {4 q% }# z1 m7 N2 J) O3 h
如果你自己设计的电路板上使用的是其他的 AT24CXX 芯片, 那么可以修改这个宏,实现不同芯片数据的读取和写入操作。
3 i/ B5 P! v: K/ K |