我购买的日历模块上除了DS1307外,还有一块AT24C32EEPROM,在DS1307成功驱动后,继续驱动AT24C32就顺理成章了。) c+ k6 f% m* g
因为软件I2C在驱动DS1307时已经调试好了,所以AT24C32的驱动就异常顺利,加上我之前就有驱动AT24C02的代码,而AT24C32仅仅是地址比AT24C02多一个字节,复制过来后,只要稍作修改,并写单字节地址改为写双字节地址,整个驱动就算完成了。 w* Y7 Q' {7 t# W1 c5 i! e$ s1 {$ r
下面是AT24C32的驱动代码,其实就是四个函数,分别是读写单个字节,读写连续的多个字节(此处没有考虑跨页处理)。9 b$ o3 r' Z0 a! v I. x' \- w% ^
- 1 O! [7 @* ~- H& f6 e
- #include "i2c.h"7 f5 |+ G9 V, v' Y2 {$ |! H4 z
- #include "at24c32.h"1 J) N* n- a5 b% l" c7 G2 {; [
4 [( b8 T7 `8 j7 B- c9 u( x- /*************************************************************
7 N! E9 {- Q1 M* A6 }3 c' s - * 函数名: at24cxx_Wite_Data(uint8_t addr,uint8_t data)
) @7 w5 z; O' \: f- d$ j - * 输入参数:addr = 要写入的地址
' P1 o2 K" N! O, p; t0 T% w - * data = 要写入的数据
' U* s- U. d% c+ |' z* G# o* ]8 Y - * 输出参数:无( l3 J# E8 b) C* H0 v
- *************************************************************/
9 q8 M# q! W9 f; u* A - void at24cxx_Write_Data(uint16_t addr,uint8_t data) // 将数据data写入指定地址Addr
k5 a/ `- C7 b+ x2 U4 b - {
$ y3 _% m9 _2 ^9 `5 ~
7 p2 p0 I( `6 f/ i8 T3 s$ x- SI2C_Start(); //开始I2C通讯- Q& M' @( R* n* b
- SI2C_Send(0xA0); //发送EEPROM器件写入地址
/ n7 x9 B3 Z# Q' J! E& p3 i - SI2CIsAck(); //等待应答6 S# `+ }& Z3 {1 N$ c |
- SI2C_Send(addr>>8); //发送高8位地址% a4 r2 E' n/ h8 `7 Z6 G* \
- SI2CIsAck(); //等待应答
# U& }: Z& t# v1 s - SI2C_Send(addr%256); //发送低8位地址, X" e% U8 r, [& H
- SI2CIsAck(); //等待应答* h# ~# Q$ `# `" z3 v) b% o
- SI2C_Send(data); //发送数据
$ M. f! s% j: k( I - SI2CIsAck(); //等待应答9 _% z) h( k7 N4 M1 X4 P7 h Z( A
- SI2C_Stop(); //结束I2C通讯: U" N( R: |. }4 C
- delay_us(4);
. D# x5 S6 ^3 K+ \/ x - }
8 j8 K9 U& g0 r- _$ @
0 M1 I) c5 T, i. p- /*************************************************************
& F) ` K/ f6 E7 t' O - * 函数名: at24cxx_Read_Data(uint8_t addr)' D4 t& O4 I. j* r( g9 M, _: v6 {1 {& V4 A
- * 输入参数:addr = 要读取的地址
7 t! m$ B6 j0 ~7 Z% K, P+ g - * 输出参数:data = 读出的数据! u% s+ a5 V- d: a0 |4 e- t. _; t
- *************************************************************/* z% f& Z. F# y8 J A% O7 `' b7 E
- uint8_t at24cxx_Read_Data(uint16_t addr) // 读指定地址Addr里的数据Data
5 }/ @. ?6 y% @/ f - {7 n$ v8 Y. N- u5 ^& K+ E& P, ^
- uint8_t data=0x00;3 q8 b8 a: u; J% v; u3 x4 s1 Q3 d
- . V( ?+ D5 s: P4 [6 J1 w O
- SI2C_Start(); //开始I2C通讯
% F% }" u* P" I9 L$ H% w - SI2C_Send(0xA0); //发送EEPROM器件地址$ u" f! v) x& `* m2 {* f
- SI2CIsAck(); //等待应答
. u$ p2 o/ L1 S - SI2C_Send(addr>>8); //发送高8位地址
" B; M* V: L( x% R3 ~! i% a* c5 u2 h' W - SI2CIsAck(); //等待应答5 F0 t* Q/ v; l" G7 ]
- SI2C_Send(addr%256); //发送低8位地址0 J2 ?! e& V* V% p- @
- SI2CIsAck(); //等待应答
, n' z8 f$ ^" ~
: H- I# J6 n7 g% s. ~- SI2C_Start();0 f4 h7 {! i- Y: x2 i7 `
- SI2C_Send(0xA1); //发送EEPROM器件读取地址
; z5 A: a5 y7 g+ v - SI2CIsAck();
; }( i) y. M f& W -
$ G. M" [2 Z* J) n - data = SI2C_Receive(); //读一字节数据
3 e; k. k$ e) J7 i7 t( | - SI2CDoAck();
9 T' a! u- E0 n9 \ - SI2C_Stop();; U S8 F5 j/ O5 r: `4 N
- delay_us(4);
" o! M/ t' T8 L1 p4 _ - return data;( ?7 X7 e6 B+ k' X% L
- }0 Q0 k$ \$ U; @$ I
3 X. L Z- }: j/ j- /*************************************************************+ R- \, g& K+ ?$ W( E
- * 函数名: at24cxx_Page_Write(uint8_t addr,uint8_t *buff,uint8_t size)/ f4 Z/ j0 c7 K
- * 输入参数:addr = 要写入的起始地址6 t) }0 {" Y1 Y8 u3 ~
- * *buff= 要写入的数组指针
8 W; B. d, I/ N+ Y* p, D) m' D2 F - * size = 数组的长度
. t; i8 n, p( @+ A0 W3 U - * 输出参数:无2 l; ?6 h9 X7 N3 }! e J$ k& x
- *************************************************************/7 x$ d# w' I- ?+ ?2 W6 |/ x
- void at24cxx_Page_Write(uint16_t addr,uint8_t *buff,uint8_t size) // 将数据buff数组写入指定起的始地址Addr9 D% j6 ^% p f% _ }. ?( A
- {
1 ]6 C; k x3 {# `. f - uint8_t i;
& w7 {5 ?2 [* l/ G" Z - ' p) y- S: s9 }3 X, o0 v1 Z
- SI2C_Start(); //开始I2C通讯1 o s4 z a! u4 M/ d8 r' f
- SI2C_Send(0xA0); //发送EEPROM器件写入地址
* P+ c/ C5 s4 z$ Y' _: l8 q& Z, ? - SI2CIsAck(); //等待应答
5 ~- \/ \7 I/ c# I1 H) Q - SI2C_Send(addr>>8); //发送高8位地址
( P2 d9 w5 L8 q- j5 o) J# P/ P+ a - SI2CIsAck(); //等待应答& ~! h4 |; |7 n% w7 `! m
- SI2C_Send(addr%256); //发送低8位地址
' o7 j/ v7 K9 v: X; D - SI2CIsAck(); //等待应答
; o" H! k1 u. o O8 W" H - for(i=0; i<size; i++){6 g2 A/ H$ c# l/ j
- SI2C_Send(buff[i]); //发送数据
2 d0 r' t$ a# a" V - SI2CIsAck(); //等待应答" C- T. m: n- {+ Q1 x
- }6 ~; Z& r$ c6 }! z' W: u! H5 N
- SI2C_Stop(); //结束I2C通讯
+ {4 Q: y* S2 C. l' Y, _# i - delay_us(4); o D# q( { A
- }5 A( } ]/ n; K6 P
- 5 i% r, S. I" j) ~
- /*************************************************************
8 o2 I& f7 V7 _1 n8 { - * 函数名: at24cxx_Page_Read(uint8_t addr)6 I7 n2 B/ i% D# O$ e) l- e
- * 输入参数:addr = 要读取的地址
3 t- p- ^+ k( c& a - * 输出参数:data = 读出的数据* ^7 ` f! I/ Z9 i5 o3 l
- *************************************************************/
- }( e3 @5 i% z- ] - uint8_t at24cxx_Page_Rea(uint16_t addr,uint8_t size)// 读指定起始地址Addr里的数据到buff
9 }0 m% G0 |5 m - {
. n# A( f$ @- b; _, p - uint8_t i,buff[size];/ Y3 k- U# q! K* s" l
- 4 E( E6 |( v2 Z2 k9 \( p& c
- SI2C_Start(); //开始I2C通讯; ?$ H* b7 E# v/ G6 N* v/ u
- SI2C_Send(0xA0); //发送EEPROM器件地址/ l7 q8 u: K1 K4 K; ^9 d! Q& i
- SI2CIsAck(); //等待应答! \# U A% V) z3 _. a
- SI2C_Send(addr>>8); //发送高8位地址0 o2 b6 o5 Y( X; i2 k0 K
- SI2CIsAck(); //等待应答
6 b; D: |# D& O3 r - SI2C_Send(addr%256); //发送低8位地址
& P* l: t- F2 x - SI2CIsAck(); //等待应答6 c9 F! v9 `( T" M* x: M# {! x6 @
( Y" p0 y- k; V q% p- SI2C_Start();
- m3 C1 o e8 \$ F. Q - SI2C_Send(0xA1); //发送EEPROM器件读取地址
+ ]+ m; A( R1 k2 L; U! @ - SI2CIsAck();6 @2 e0 |- {1 I8 N
- for(i=0; i<size; i++){
. r* }- C5 `3 t - buff[i] = SI2C_Receive();//读一字节数据# p* P% R% A: L( z: q
- SI2CDoAck();( M. ^9 {) @, U6 S# w5 ^' o/ M
- }
* Z. p6 ?. t# y- w6 T - SI2C_Stop();+ D3 m7 g* n, A' z0 _4 d5 t
- delay_us(4);
0 w) m( C' L8 @" } - return *buff;, P5 S5 i6 o' B
- } F/ A; I4 k0 N" A$ [
1 V X; s& p0 D5 P; }: _
复制代码
8 d& v6 O0 j& I7 U, t/ H
! y& m4 [; M- E1 I' m; |" o% z6 w9 C7 |& |3 g; _, [2 @2 F% Z
% h& l' K* A1 R! a# b, Q$ s+ h0 w I
7 n5 j, D5 f" u, V0 M$ R$ j) w |
. \. v' a0 a$ R% k& i: c( c9 M. {/ C