一、AT24C08的通讯方式6 D" A) w6 k7 K# S9 W& b g
AT24C08采用IIC通讯协议,本次例程是普通IO口模拟IIC端口# E4 a2 f4 \' ?7 V) j) O
$ E k; f. U5 j# C% o+ J/ u二、AT24C08的存储方式
( V3 q, E$ g; b) jAT24C08有8K位存储空间,可以存储8K/8=1K字节的空间,- v9 s4 C5 @7 W! j! e+ D
1K存储空间,是由外部的A2决定如何分配的,例如你的A2引脚固定接地,那么这1K的存储空间
( k" @( |$ `2 o7 I0 O1 I就分成了4块,每块都有256字节存储空间,每个字节是8位9 t, A) @+ i, R5 Z7 u
1 n' X! _& [5 u* y% s
器件写地址分别是0xA0,0xA2,0xA4,0xA6( j; c" d+ c" o$ ]( d! A
器件读地址分别是0xA1,0xA3,0xA5,0xA7- ?. ~. P7 P( }! c$ ^1 ?
- /*, u9 }$ e) h6 G3 J) V/ [, A
- *描述: 在eeprom指定地址写入一个数据* P8 M' s' V8 a G$ ~8 v* z
- *参数: WriteAddr :写入数据的目的地址
0 A# R, P) m, J$ ?" q1 K - * DataToWrite:要写入的数据
+ y# K( O- D) r& @6 Z/ {; O' F - *返回值:读到的数据
$ P3 T H$ d/ e$ Y. N9 F% W - */
& O' W2 M$ ]' {( | R - void Eeprom_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
c* W& r, o, m - {
& {4 `7 C5 d! q8 b! r - IIC_Start();
+ F3 o. D N" C5 a d
7 }3 W# y+ N/ B4 B& E% l' T- IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据 ; u: L- r n; J# }
- IIC_Wait_Ack();
3 y* F3 L' h2 c8 j- [ - IIC_Send_Byte(WriteAddr%256); //发送低地址
, s1 i( z* r, I/ W2 U - IIC_Wait_Ack();
( C! R) h$ P, ` - IIC_Send_Byte(DataToWrite); //发送字节 # D/ q! T2 L/ q
- IIC_Wait_Ack(); ) l6 |/ b/ H7 j$ u/ q$ Z3 z
- IIC_Stop();//产生一个停止条件
4 ]6 B+ {. D9 Q: k0 L - HAL_Delay(10); # w# ?3 F2 t+ N. R+ B
- }, e9 q4 `' b/ X0 ~# ?( B/ t$ i
- /*
$ R9 U" A" ~2 Q& u+ l - *描述: 在eeprom指定地址读出一个数据
" s% n2 H' _0 J& c! X - *参数: ReadAddr:开始读数的地址
7 H7 @$ \' ], ~2 V" R3 r - *返回值:读到的数据; E2 `+ e; r) i/ Q c* \/ |, y
- */
* u z- }# [% I9 ?6 q/ }; L - u8 Eeprom_ReadOneByte(u16 ReadAddr)
- D6 x, v! v" q* _" i! u/ z0 `" K - {
* I# u. `! ~/ l4 H. {) K - u8 temp=0;
0 \. _' i! p# L* u8 A ` - IIC_Start(); ' d! h: z" X- U8 n$ Q
-
O8 ^7 s$ b$ X0 B# M - IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据
6 v! R I$ G5 X# w* S! ] - IIC_Wait_Ack(); " n3 x* |' s" y6 X' S4 u
- IIC_Send_Byte(ReadAddr%256); //发送低地址
+ ` d+ [+ {" M C6 ` - IIC_Wait_Ack();
' p- r1 R% U2 J - IIC_Start();
5 x) G; R& F: A1 b - IIC_Send_Byte(0XA1+((ReadAddr/256)<<1)); //进入接收模式 # `# K& |4 u" ^$ X- R, [
- ' A" ?$ }1 t5 u/ \# d0 r6 p
- IIC_Wait_Ack();
; D+ R: l. S+ X$ g/ B - temp=IIC_Read_Byte(0);" c5 L( q3 l0 V6 c$ J; p
-
; Z# k! R' M5 f9 U6 K( F - IIC_Stop();//产生一个停止条件 ) y3 U2 z {6 N3 s5 X+ A5 D
- 3 P& h! |7 V& s, N( t3 u
- return temp;
+ C7 e0 X' d+ V8 T1 o- r - }& \7 F( h! m" ~, G
- 9 A: s l0 v1 {% T
- /*
4 K9 E" G8 ]; X& K. G - *描述: 检查EEPROM是否正常
4 p% B4 i( l! }- b8 ? - *参数: 无
% ? m$ H" B1 l+ P4 k9 F - *返回值:外接EEPROM是否存在
5 M6 ~: V5 h! D2 p, Y4 D4 v9 Q - */& Q, ~& D1 d) Z0 q. C' m
- u8 Eeprom_Check(void)
6 u: I- t* E# G/ R$ t; S* T/ ?5 a& m - {9 {& L$ g- k3 t" I- o7 S
- u8 temp;
1 y" ~* S7 p% l: d9 r5 T. H- g2 M - temp=Eeprom_ReadOneByte(1023);//避免每次开机都写EEPROM % D+ ^ ?' @9 \1 E, [8 |
- if(temp==0X55)return 0;
) {( V1 z1 s* G* v, K - else//排除第一次初始化的情况0 ^1 U- D! L r9 T9 g* B: r
- {, \" q$ g+ q) N: l% S0 y, H
- Eeprom_WriteOneByte(1023,0X55);
3 _: x$ O: x6 \3 K3 x& x - temp=Eeprom_ReadOneByte(1023);
0 y; z' E' q3 _8 f3 z C - if(temp==0X55)return 0;
! R8 ?/ v( \5 F3 A) W - }* ], Q. _" \% P
- return 1; # b' _3 V% n( B* Z L
- }
9 F1 T6 t7 Z* i' @# t1 l% o4 |: x - 9 I# E" ?7 _* r! J, o7 I. u# M3 P
- ; B* z0 y5 U0 V
- /*. N ^3 N4 A0 Z6 J n
- *描述: 在EEPROM里面的指定地址开始读出指定个数的数据3 |# @* e4 `7 k$ p
- *参数: ReadAddr: 开始读出的地址' L1 U" G# s; E) w; q) _
- * pBuffer: 数据数组首地址
9 F9 J$ a: B, }& t9 R - * NumToRead:要读出数据的个数0 l$ U1 A$ ?# b% T4 H
- *返回值:读到的数据
% r6 P% X4 V: B" z - */+ O- A+ x/ u. P( |) C# h
- void Eeprom_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
% R% C6 _: Q" N- l7 S4 b! [ - {
E6 X3 w% [$ n+ s6 _2 H: ^4 K8 T - while(NumToRead). ^4 j; W. R* l3 [5 n0 w
- {% {6 h! Y+ B2 u! I7 h. Q9 T y, i5 g
- CLRWDG();/ x, X$ W: @' k
- *pBuffer++=Eeprom_ReadOneByte(ReadAddr++);
6 w8 q9 F* R; I" E& t - NumToRead--;3 X9 \. ]3 H, [9 L- ~2 I
- }
. H4 z6 {8 w/ j1 s5 ?! o2 ^ - } . o" K9 y# p2 s, _" s4 Q9 b& K0 I
$ g+ T8 o# E" n/ Q0 x* L) f; V2 o- /*+ ~0 }3 T: l2 Y1 r1 f9 @. v: @
- *描述: 在EEPROM里面的指定地址开始写入指定个数的数据) K* T1 N' V4 |% B4 t' |5 Q
- *参数: WriteAddr: 开始写入的地址0 t4 Q$ x( g& A3 U3 p
- * pBuffer: 数据数组首地址6 `! P$ s. m c- _$ g, L
- * NumToWrite: 要写入数据的个数
& Z& n+ Z! c* h - *返回值:读到的数据
2 S! A; I- A! c6 E$ ~1 k - */# S' P3 M% [2 _& L/ ]5 m, _
- void Eeprom_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
- u$ T$ y+ L. [* c1 t - {
1 c) K- u/ j- f5 d9 X( ? - while(NumToWrite--)
) d* m+ J& g* k M* ]* s - {
" I; o6 p1 T* g - CLRWDG();( M/ S9 @, N* m8 \
- Eeprom_WriteOneByte(WriteAddr,*pBuffer);
/ o0 h6 j! [& Z# V* p - WriteAddr++;4 M0 r# w. h4 G5 m' {
- pBuffer++;+ W; x9 j$ D2 R1 s+ X
- }
8 W# {4 l; t' \- B0 ^ - }
3 m7 o5 j* E( a0 _) \
7 ^+ v- s( p2 ~' W4 B4 V& ]$ g
复制代码
1 F! M$ h% r; e0 o
3 P, E! c P: [% U1 N, J1 ]2 q# v) N- c' m& I, Y; \
) Z( z& F7 N; M |