我购买的日历模块上除了DS1307外,还有一块AT24C32EEPROM,在DS1307成功驱动后,继续驱动AT24C32就顺理成章了。; x) v: b6 r+ |: s4 ^
因为软件I2C在驱动DS1307时已经调试好了,所以AT24C32的驱动就异常顺利,加上我之前就有驱动AT24C02的代码,而AT24C32仅仅是地址比AT24C02多一个字节,复制过来后,只要稍作修改,并写单字节地址改为写双字节地址,整个驱动就算完成了。
. T7 g. C+ L$ [ 下面是AT24C32的驱动代码,其实就是四个函数,分别是读写单个字节,读写连续的多个字节(此处没有考虑跨页处理)。
9 }9 c7 d) ?+ T- 5 f4 Y& S3 i* A
- #include "i2c.h"
! {7 v; D$ L- N: @- d - #include "at24c32.h"
9 X1 }8 g9 N* c' e) g' l; I/ _
; { p" E& l" d k! j- /*************************************************************" @- p1 r3 L. B% E2 e
- * 函数名: at24cxx_Wite_Data(uint8_t addr,uint8_t data)
, \6 O1 P( L, y8 q% R- J- M2 p - * 输入参数:addr = 要写入的地址' A& t, Z0 T3 _+ e+ p
- * data = 要写入的数据, D" `/ u O3 x+ }( g
- * 输出参数:无+ B& ~. L" |; f4 o
- *************************************************************/8 r1 G3 R) q- C8 ]- c/ g
- void at24cxx_Write_Data(uint16_t addr,uint8_t data) // 将数据data写入指定地址Addr
! ~+ {% `. W( i% C8 e7 q& B! C - {
4 C5 r0 A: i0 i0 G* S7 w1 i - ; J: t" b4 @, t+ I2 P+ k
- SI2C_Start(); //开始I2C通讯
' i9 @2 |& U& p - SI2C_Send(0xA0); //发送EEPROM器件写入地址( B' }, T% L# \0 c) m5 N) \
- SI2CIsAck(); //等待应答
$ v; e2 x( `; P& [: ?. w* i+ r - SI2C_Send(addr>>8); //发送高8位地址, L9 n+ U) ]1 q7 E3 N5 R9 K, t
- SI2CIsAck(); //等待应答" e, J- ?, B" P! v2 N
- SI2C_Send(addr%256); //发送低8位地址
: c) z* X& q, [: B! ^% C/ _ - SI2CIsAck(); //等待应答: R$ U9 Y8 E, z0 P
- SI2C_Send(data); //发送数据6 G2 x5 f) s& c5 }
- SI2CIsAck(); //等待应答
" V5 k6 w" U8 q - SI2C_Stop(); //结束I2C通讯2 T4 ]% o2 @5 ~
- delay_us(4);
! k- P1 Z& Q& a; F2 [1 X - }' [7 B, h2 ~ q; s8 X4 |+ K
) |' m; e1 i6 O- q- /*************************************************************7 X' w0 L g j2 t9 t. ~' R
- * 函数名: at24cxx_Read_Data(uint8_t addr)
9 {* K, |$ K0 Z- q: s3 q - * 输入参数:addr = 要读取的地址
M! V9 ^7 b9 P - * 输出参数:data = 读出的数据
5 F0 d; Q/ |9 \5 Q - *************************************************************/) D# f8 P& K5 ~' ?7 k
- uint8_t at24cxx_Read_Data(uint16_t addr) // 读指定地址Addr里的数据Data! W# Y) y F" E/ V- r @* `9 e
- {
# ~& Q( c) M0 d( z; ]4 L r: K0 d - uint8_t data=0x00;: J0 W0 E' K4 l; @
- " p2 ]8 F0 [) C6 i0 z/ E# s
- SI2C_Start(); //开始I2C通讯4 `, ~7 h. f$ E2 x( E2 S" P$ Q0 C
- SI2C_Send(0xA0); //发送EEPROM器件地址: e4 \) A P: b8 e3 F9 Y
- SI2CIsAck(); //等待应答
0 x/ W4 y, R) G# H/ l/ a* i - SI2C_Send(addr>>8); //发送高8位地址
1 y" ^, U# r& B4 N7 ^1 m: X - SI2CIsAck(); //等待应答( n& c6 q Q: M- ~, F
- SI2C_Send(addr%256); //发送低8位地址7 x# K. n$ O4 ?: r7 G) q/ f
- SI2CIsAck(); //等待应答+ q- `+ K1 R& P: R& P+ b, u4 d- Z
- " z; t% Y' F# u. q! q5 Z
- SI2C_Start();
. f. b4 K8 x3 q% | - SI2C_Send(0xA1); //发送EEPROM器件读取地址% I" C8 j! C- ~* i
- SI2CIsAck();
9 M; B L# f% C0 I) |6 N - 4 ^& @$ u) _2 Y
- data = SI2C_Receive(); //读一字节数据) Q& e9 O+ E" s' X* e9 o& `
- SI2CDoAck();
9 \) J0 Q4 p# i - SI2C_Stop();
/ r, m: w8 p: P9 W# k/ p d - delay_us(4);9 W H$ k2 }0 K# \) q
- return data;
: @6 R+ S) @* b - }; Q$ t5 h7 ]2 Y7 Q" K4 w! a2 O
- 3 R4 i) S0 z4 p5 r# N7 B
- /*************************************************************8 a4 Z0 D2 R4 G2 s% s& N N
- * 函数名: at24cxx_Page_Write(uint8_t addr,uint8_t *buff,uint8_t size)
) ^& M# f5 A! v" p0 I! i - * 输入参数:addr = 要写入的起始地址
8 p( N: j0 }( X! F - * *buff= 要写入的数组指针( P! a1 Z0 ?8 `. ]+ l! |. ^- s4 i
- * size = 数组的长度- J9 n: _- o, U' B0 a8 c( g' C a
- * 输出参数:无
$ f$ g. d$ m' M - *************************************************************/
3 i( U, x8 b- K/ u - void at24cxx_Page_Write(uint16_t addr,uint8_t *buff,uint8_t size) // 将数据buff数组写入指定起的始地址Addr
0 O P8 [" y4 ?0 G1 g1 x3 ~7 I - {
) n3 |+ Z4 _0 e6 V/ \ - uint8_t i;4 k4 r+ \+ G; e) A- g5 B
- 0 T% R: B# g0 n3 q3 f3 m& ~
- SI2C_Start(); //开始I2C通讯
" m# k; x0 N5 S' P* Z- j/ m" X0 z - SI2C_Send(0xA0); //发送EEPROM器件写入地址4 W! l; f f ]
- SI2CIsAck(); //等待应答8 B$ k& h3 V/ y- @1 @/ ^! p3 ^
- SI2C_Send(addr>>8); //发送高8位地址
% t5 k) \9 A; r' t7 K - SI2CIsAck(); //等待应答& m- K/ B8 t$ `/ p
- SI2C_Send(addr%256); //发送低8位地址
$ g0 ?: k8 Z @" @( c - SI2CIsAck(); //等待应答
% n& v7 f. x; t7 i2 Z - for(i=0; i<size; i++){/ s/ ]4 i' v3 p4 @
- SI2C_Send(buff[i]); //发送数据* A& }2 ~+ [! ~) O: g2 E+ Y6 Q
- SI2CIsAck(); //等待应答3 _% o8 ] S" {, ]! _7 Z
- }# W6 ]+ Z9 `$ q9 c }8 Y: n4 S9 w' a
- SI2C_Stop(); //结束I2C通讯& F. K m7 A+ @% w7 L& c: y
- delay_us(4);
& } N; p: L1 K - }
# h, d7 F# M: f1 u$ b" M* m6 m4 R
; q, v5 K" @5 b2 C+ l/ y/ p# d- /*************************************************************
2 A, B) U9 a1 ~( _1 C! n - * 函数名: at24cxx_Page_Read(uint8_t addr)
7 R9 w4 }* M& j+ V9 M: u7 Q - * 输入参数:addr = 要读取的地址
* j6 d" n% j" |2 |2 ^ - * 输出参数:data = 读出的数据
+ t+ [2 u9 n" a, H5 I) w - *************************************************************/
2 ]" B0 U+ G& n- i+ f) w9 Z - uint8_t at24cxx_Page_Rea(uint16_t addr,uint8_t size)// 读指定起始地址Addr里的数据到buff
! [) f9 ~3 `6 S+ [/ o( o - {
# `& V: G' J* }* R' w - uint8_t i,buff[size];4 Y4 ~0 p! _7 Q: ?3 Z5 ~
- * H, V' _' S9 ?
- SI2C_Start(); //开始I2C通讯
* w& x t( d2 I( w: z% n - SI2C_Send(0xA0); //发送EEPROM器件地址
- w1 S' G5 p5 \9 \# U9 e - SI2CIsAck(); //等待应答
6 X) K1 e; K+ t8 Q# V4 ? - SI2C_Send(addr>>8); //发送高8位地址
% Z) R. Q3 c. D! U' I5 } - SI2CIsAck(); //等待应答+ m0 N/ `0 I" \3 S7 t
- SI2C_Send(addr%256); //发送低8位地址# P( C# z, L* _$ t
- SI2CIsAck(); //等待应答
) L6 t$ S' R; D# l
. x# `. }& f1 I- SI2C_Start();
; u% x& m7 t# P1 s - SI2C_Send(0xA1); //发送EEPROM器件读取地址
/ R! l# J. A F7 v: f" J - SI2CIsAck();- E2 }! Y: S3 i4 u
- for(i=0; i<size; i++){
% e7 b9 X' ?$ I" r) b8 q" \ - buff[i] = SI2C_Receive();//读一字节数据
W3 ?8 h A: K# G% `: @ - SI2CDoAck();
) _3 M% ?9 b6 W- y" ] - }. J9 Z6 Y. I( g- Y
- SI2C_Stop();: Z+ h( p: }) Q; R5 L. V7 @
- delay_us(4);( k- H/ V: x& Y' `4 Q
- return *buff;3 p' n/ @& A, [) w+ R
- }
$ m8 O7 s) G* L" _( ?( n5 n
4 C% \) K. R8 D- j5 ^
复制代码
- _+ |" G4 O; F* ~6 S) G$ y6 l/ k$ o8 [- R8 V( D) b
2 l6 h6 H2 ~) e! v$ V
9 R! @3 w* B2 r3 R6 D+ u! D1 ^8 J9 ]" S
|