我购买的日历模块上除了DS1307外,还有一块AT24C32EEPROM,在DS1307成功驱动后,继续驱动AT24C32就顺理成章了。
: a$ w. U) \ o2 {9 Q) x 因为软件I2C在驱动DS1307时已经调试好了,所以AT24C32的驱动就异常顺利,加上我之前就有驱动AT24C02的代码,而AT24C32仅仅是地址比AT24C02多一个字节,复制过来后,只要稍作修改,并写单字节地址改为写双字节地址,整个驱动就算完成了。0 G3 e4 T3 Z0 o( x s7 F4 Z
下面是AT24C32的驱动代码,其实就是四个函数,分别是读写单个字节,读写连续的多个字节(此处没有考虑跨页处理)。
$ W' T/ k1 w, T8 B- % ^: G9 h1 Z0 ]6 E8 J/ [
- #include "i2c.h"
! k/ _- e: }- _+ W - #include "at24c32.h"
9 g9 o( s$ Q5 i
# w, e$ ^; K" k# N* D1 |% g- /*************************************************************9 d+ F0 E; P' y ~0 ]# V' x
- * 函数名: at24cxx_Wite_Data(uint8_t addr,uint8_t data)
0 B8 z9 G/ V& f: f. H - * 输入参数:addr = 要写入的地址: v4 E/ l: z1 N' g+ x% i" h
- * data = 要写入的数据
3 k% K( g( F) W/ A( i" q; P - * 输出参数:无6 p* ]$ N2 ?6 @- Z# d
- *************************************************************/4 B3 Z+ N/ t: _' g2 g9 j) w
- void at24cxx_Write_Data(uint16_t addr,uint8_t data) // 将数据data写入指定地址Addr# j/ d1 ^/ h8 d+ ?) r( @6 i2 }
- {* V p4 B6 F; J% o8 b
8 `. l4 B: ^ S$ n9 U0 K+ R- SI2C_Start(); //开始I2C通讯
3 m. D' r( z) e6 p9 [1 i - SI2C_Send(0xA0); //发送EEPROM器件写入地址' _, [6 F. L n g, |" m/ P8 `
- SI2CIsAck(); //等待应答* L, z& h! l5 @- c$ b8 o
- SI2C_Send(addr>>8); //发送高8位地址
' {8 E/ Y& M5 O& J# A7 ? - SI2CIsAck(); //等待应答
7 l# h! F2 I" E; N3 U3 |) ^: P3 F - SI2C_Send(addr%256); //发送低8位地址
7 V1 @% D. M/ Q5 V5 r5 i9 J) Z' } - SI2CIsAck(); //等待应答% R; ^' ?# C, |8 K0 u
- SI2C_Send(data); //发送数据! [8 M, \+ ^+ J, i# R" B( ]
- SI2CIsAck(); //等待应答+ ?6 i& K! \7 K! f2 I# ^' F
- SI2C_Stop(); //结束I2C通讯
* [$ ^3 a8 L. [ - delay_us(4);/ j4 z* D! Y2 C" b2 A/ o
- }2 h) @$ u# _2 j: D/ p9 d y
- * ] J4 D0 a2 i; P% Z. T6 {
- /*************************************************************! u' }5 m1 y! O# d; {3 R9 e1 U! U5 K4 {6 X
- * 函数名: at24cxx_Read_Data(uint8_t addr)8 t! m1 X% p, Z3 V
- * 输入参数:addr = 要读取的地址
5 g) v5 t0 K- P! C) d - * 输出参数:data = 读出的数据. q- `; [) i. A8 C5 I' D# J
- *************************************************************/+ V& R, R0 r1 E# B, I$ |% s* {
- uint8_t at24cxx_Read_Data(uint16_t addr) // 读指定地址Addr里的数据Data
. b- `: _3 I* r - {
3 c1 W% [: R4 ~( J- Q1 F - uint8_t data=0x00;
6 v( H' Z) [5 f+ o! B, m% [! P. H -
* y7 L6 W# H1 b9 K# ^5 j% P - SI2C_Start(); //开始I2C通讯6 T. H3 N4 P* O! f- }) E7 t$ n& E8 m
- SI2C_Send(0xA0); //发送EEPROM器件地址
0 k; S7 T$ L: v - SI2CIsAck(); //等待应答
/ [9 A1 s) ~4 c" k: d" @- W - SI2C_Send(addr>>8); //发送高8位地址& l' I% K+ L; O+ u5 s: O8 O! w
- SI2CIsAck(); //等待应答
: g, V6 n/ A! I. ]* A: G* w - SI2C_Send(addr%256); //发送低8位地址
. I: D4 h& K0 W. ^% d - SI2CIsAck(); //等待应答. [0 g. \3 h0 T+ X8 k! t7 T- B# B
; ~( A- |: I3 [ w# Q- SI2C_Start();
4 z9 ]$ ~* y8 v5 n0 J+ \! b - SI2C_Send(0xA1); //发送EEPROM器件读取地址& P+ Y, Z: M9 @- w- u8 V+ m5 ~
- SI2CIsAck();( y3 d6 L7 z( n* s N) T
- . e/ z! I z$ a" z. O2 d
- data = SI2C_Receive(); //读一字节数据* v$ z+ J4 t/ u ~
- SI2CDoAck();& j! ]/ w5 c1 o, A* B/ M! `
- SI2C_Stop();
2 w# R5 d5 B& C) ?1 S O - delay_us(4);9 h) W! v, b5 \' v: ]( m* Y1 l) O, G
- return data;, E5 [) ]1 a' U$ x* u- e$ s( P6 I
- }- N$ T* X& k* B6 m' x
0 Q( n+ I% c, U' M& N- /*************************************************************; r7 H" {6 N7 J8 D2 `2 F1 ~
- * 函数名: at24cxx_Page_Write(uint8_t addr,uint8_t *buff,uint8_t size)8 u4 h0 i. c5 [, h X
- * 输入参数:addr = 要写入的起始地址
3 V y7 ?4 n' e, t7 h' `* P# ~) v* Q - * *buff= 要写入的数组指针/ @9 h* r9 E' z3 x8 l& o
- * size = 数组的长度% g& Z3 M, T: l. ~% w- m1 e
- * 输出参数:无
$ M3 i% ]& b# ?7 W - *************************************************************/( E4 p) ^/ v/ K: v" J
- void at24cxx_Page_Write(uint16_t addr,uint8_t *buff,uint8_t size) // 将数据buff数组写入指定起的始地址Addr+ H; g+ M$ ]% u0 S, l ]! R( u
- {
: F; ?0 ]- b. Z% L - uint8_t i;
0 K* i( F0 i: X - # [1 C0 W0 I8 W5 I) Q, }& O
- SI2C_Start(); //开始I2C通讯) h; f2 f Q# G& @$ z
- SI2C_Send(0xA0); //发送EEPROM器件写入地址 }9 s, j# X& J" g% a
- SI2CIsAck(); //等待应答, g. z8 g S3 _5 Q3 e8 v
- SI2C_Send(addr>>8); //发送高8位地址
2 ?5 z. u7 n' W& u. [ - SI2CIsAck(); //等待应答+ C! a( S# t6 ]& u( J/ f
- SI2C_Send(addr%256); //发送低8位地址- {1 @! k t6 H+ F$ v* }
- SI2CIsAck(); //等待应答 ' b; b1 {$ f0 J, ~
- for(i=0; i<size; i++){# T4 b: n% s3 X% D c& Z
- SI2C_Send(buff[i]); //发送数据* h' ?! q$ i0 }6 C- i+ c. {
- SI2CIsAck(); //等待应答
( m- J4 q, K/ w - }+ ~% ]; ?; k6 s( g7 \7 w" Y. ?
- SI2C_Stop(); //结束I2C通讯
' H L+ o1 E& ^* |/ o; f - delay_us(4);
$ m2 b# l( `) f% U# h - }1 \- z2 ^- Z* X$ D; b% a
- ; ?7 G6 z5 q# i9 r! x/ ]1 p
- /*************************************************************% S3 E3 x& G0 U' z) L }
- * 函数名: at24cxx_Page_Read(uint8_t addr)
( f- L! W# x9 V% a" p - * 输入参数:addr = 要读取的地址
2 P# [, K0 a" p' S% A( _ - * 输出参数:data = 读出的数据/ N7 H: s* ^1 C7 J9 W
- *************************************************************/
! J z/ R! N! R; d - uint8_t at24cxx_Page_Rea(uint16_t addr,uint8_t size)// 读指定起始地址Addr里的数据到buff7 t: s, O O$ Z' K: e. ~+ o p0 K
- {; b3 V I: Z8 [
- uint8_t i,buff[size];, Y1 u+ {8 P4 B: v4 R
-
' l# q% m7 z+ ~ c - SI2C_Start(); //开始I2C通讯
( |! E& K! J$ c+ } - SI2C_Send(0xA0); //发送EEPROM器件地址& i/ w4 m3 p) l1 a
- SI2CIsAck(); //等待应答
1 O( N" D8 Q9 u. p$ b3 y0 z/ P - SI2C_Send(addr>>8); //发送高8位地址& o U, L$ u% Z! b( S/ z, M. f
- SI2CIsAck(); //等待应答
) N& L, A# t- T9 W4 v8 P) B - SI2C_Send(addr%256); //发送低8位地址8 ~ v9 M$ D2 o+ n* c) z( e9 v2 l
- SI2CIsAck(); //等待应答
' S+ c. @; ?8 a# O2 u2 }$ F# J - & G& N- D. d8 {! {: `' p G3 o# z
- SI2C_Start();
4 T0 H% l; o9 e% {3 U - SI2C_Send(0xA1); //发送EEPROM器件读取地址
. p; E3 @) ^- ~0 L/ U - SI2CIsAck();
3 V6 d: x+ j9 ^/ y6 S+ u - for(i=0; i<size; i++){
o) Q% k! J- I( d3 R - buff[i] = SI2C_Receive();//读一字节数据3 ^5 z4 a) Y2 o# C
- SI2CDoAck();/ k* Z3 ~# e* @7 r$ k) y( p. A. s
- }" X! Y; D, k6 [& t/ I' l& s0 @
- SI2C_Stop();- ]1 {, D: T7 P& Z# N2 @# Q% u1 A
- delay_us(4);
. p$ J2 h9 Q7 [7 n0 k2 m - return *buff;
) h1 C' O3 o$ b, r - }+ i* _& ]3 e3 q/ ]2 g- u- G4 X& D
1 ]4 d$ f! ~8 f/ B% k
复制代码
. ] ^! B& Y0 S) i0 J) O+ w7 B4 [3 j9 m, `& H
0 k9 g/ ^5 N+ {6 G0 f
4 A% G5 A/ X' b; x8 D Y3 }
5 A. a. x. q+ p' X |
0 ~- w! I2 U3 C7 X6 `2 L
( w* @& _1 |# t; F/ P2 F% S