一、AT24C08的通讯方式
# O5 _- C& v" ^3 \$ ]AT24C08采用IIC通讯协议,本次例程是普通IO口模拟IIC端口
9 m9 g" W" H2 C5 x2 w( e, C# f9 F% H9 H3 K0 Z4 b& a
二、AT24C08的存储方式
2 |( X! K$ R( ?! j9 v" o7 O, @AT24C08有8K位存储空间,可以存储8K/8=1K字节的空间,
$ `7 y9 x+ F& I) \1K存储空间,是由外部的A2决定如何分配的,例如你的A2引脚固定接地,那么这1K的存储空间
/ N% Q( L; A/ i' K; _8 R5 W就分成了4块,每块都有256字节存储空间,每个字节是8位
* I9 ^% g8 m6 K( X0 W+ Z: c- o
5 x# f" N" ?5 h1 _4 ^器件写地址分别是0xA0,0xA2,0xA4,0xA6% X e A k1 k% C& y* ]( O
器件读地址分别是0xA1,0xA3,0xA5,0xA7
. j; n# ~/ @9 r1 k. n- /*3 l) g5 U. v$ @
- *描述: 在eeprom指定地址写入一个数据
# {) l& n: }' N$ \2 B8 T - *参数: WriteAddr :写入数据的目的地址% X4 I( s q7 l4 c w
- * DataToWrite:要写入的数据8 B& {5 C( g& J6 K( \0 c& d
- *返回值:读到的数据# W8 N, @1 V8 a) F' p+ m6 |- m! X
- */
4 X0 A( T& }6 t5 H) e6 C - void Eeprom_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
0 I E4 y) M' M7 K/ [6 ] - { " n# V4 O$ a, U# M- K
- IIC_Start(); ( ~/ a1 s' A; l9 h6 f- E; i3 o
9 [5 C! j! U: M$ k- IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据 0 J, }. H& N1 `) C: |! L
- IIC_Wait_Ack();
6 V. B$ D9 W E" ~ - IIC_Send_Byte(WriteAddr%256); //发送低地址
/ L2 M! d3 s8 \/ X - IIC_Wait_Ack();
7 O* g. n) s7 P+ [" W - IIC_Send_Byte(DataToWrite); //发送字节 ; p9 {5 {8 A4 N& z+ k4 \
- IIC_Wait_Ack(); : O0 V! N5 d* e2 y |
- IIC_Stop();//产生一个停止条件 ) ]# d- M. }- c S- l
- HAL_Delay(10); - w F4 R2 P7 ], M0 q( f8 f4 [6 Q
- }* x# W$ B( ^7 u/ r* T3 H, c
- /*
$ [2 d2 i. G) `; p - *描述: 在eeprom指定地址读出一个数据1 [9 q( E2 e2 {# P4 T
- *参数: ReadAddr:开始读数的地址# N* a0 s, w4 Q+ b0 r2 r$ _2 w) {" _
- *返回值:读到的数据6 `, i: b2 ^( h" g: ^9 D
- */' i* g% \8 B1 _8 A% E/ W
- u8 Eeprom_ReadOneByte(u16 ReadAddr)7 ]: ~: B6 p5 T- f5 _6 ~
- { : Q( R1 Z- B# T% [3 z7 z
- u8 temp=0;
' @) z, P5 k& m5 h" V* g& d9 i* x - IIC_Start();
8 v- V1 j, f3 j0 A& R -
) I2 h0 ~& `+ K - IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据
: _% h1 ?( t) e) z$ \ - IIC_Wait_Ack();
. v9 n" ?3 R% Z& m0 f% E0 N - IIC_Send_Byte(ReadAddr%256); //发送低地址
c9 T+ g( z' u0 w - IIC_Wait_Ack();
3 B* `* V) u. }7 y8 M/ k - IIC_Start();
& {" g5 K9 l7 p X7 {& \& k - IIC_Send_Byte(0XA1+((ReadAddr/256)<<1)); //进入接收模式 " k& [7 o" E" c* x3 G) t
- ' v, Q6 E7 `: |4 u0 y5 g, v z" L1 ^
- IIC_Wait_Ack();
% E. m8 N, m7 p8 ]( b" y3 i - temp=IIC_Read_Byte(0);& m& A$ X+ M k( ^, [( }( Z! F
-
7 z" D1 A+ S+ e& g - IIC_Stop();//产生一个停止条件 2 i' ~5 z- }/ U9 H+ n4 k1 e
-
9 V- h: i9 U' g$ k$ W; K - return temp;
9 F& m4 |7 k& m6 g: N - }9 T0 G; R) y: B
- ! ?3 T; k5 t/ `" _3 J# c& a6 f
- /*6 j4 M& y/ h" |# O8 u
- *描述: 检查EEPROM是否正常
" a, {) L! j! p2 e: b - *参数: 无3 K) ?, l0 ?0 N
- *返回值:外接EEPROM是否存在
# K- ` i0 Y) s+ P, l - */# f; M5 D7 o( Y' r8 \: n/ l% \" p1 |
- u8 Eeprom_Check(void)! F5 }1 V$ `6 [$ F/ @
- {0 `0 {& g! M* H( l. I
- u8 temp;
" \$ i o( W8 G) b - temp=Eeprom_ReadOneByte(1023);//避免每次开机都写EEPROM $ d/ H: [8 ]- r# a- G/ j: L0 X
- if(temp==0X55)return 0; . ^1 W N" r9 b( Q, w. f* }
- else//排除第一次初始化的情况5 `' P% `0 D: P6 F/ p$ y
- {
) [8 c* h/ X* S! Q( ^ - Eeprom_WriteOneByte(1023,0X55);
: T' O! M! s3 z& _4 }( E - temp=Eeprom_ReadOneByte(1023); 7 i+ g: c0 o O9 @, C4 v
- if(temp==0X55)return 0; z4 R1 o% o7 E) C
- }# M4 b; E# q0 T4 |! B& o
- return 1;
/ M& E& i( s* V - }, n" Z x- o- i
- : P8 Q$ [* T$ x& e+ ?6 b; s
; x# ?1 _3 }3 c0 C" \0 E" k( |- /*
3 k7 y% a& E. P: T; w - *描述: 在EEPROM里面的指定地址开始读出指定个数的数据
( ^* j, q9 [+ C& W - *参数: ReadAddr: 开始读出的地址
0 n! m r6 e: }7 ^& W - * pBuffer: 数据数组首地址8 P* U% j. @6 E1 p
- * NumToRead:要读出数据的个数
4 k- B: H- p, Z" W6 I" i4 {- R4 Z" b - *返回值:读到的数据5 I; O* V" {' F7 C
- */
" H& s- [2 i! `1 }) c! d - void Eeprom_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)% H) U+ W" d. m f. D
- {9 r1 m8 R3 d; C' z, `& Z& W
- while(NumToRead)
[- G/ E9 E1 V% @5 |* E5 D/ B - {8 y m6 c( [% ]3 x6 U( R+ G
- CLRWDG();' E0 O- |* H! A0 j: _. E+ Q: }
- *pBuffer++=Eeprom_ReadOneByte(ReadAddr++); ) z9 N# J5 C' p+ J* B+ q$ t
- NumToRead--;, [3 t6 O+ _# z6 Q: @5 g5 M
- }3 o- h; F8 u6 F* ?2 R! ^( y
- } + I; v6 _/ C4 t. w. E
- + u0 H, G3 T% O. V9 m0 H$ H* H9 c
- /*
+ q! W( X; A I& X6 r) B5 V# H0 g - *描述: 在EEPROM里面的指定地址开始写入指定个数的数据: m4 X& ~# |) B5 {$ s- w
- *参数: WriteAddr: 开始写入的地址
. H0 T( Q5 Q6 r+ Y$ T3 s; | - * pBuffer: 数据数组首地址
& @# E) q3 A) d E% r- h$ Q - * NumToWrite: 要写入数据的个数
, _2 L) h$ x/ w* e/ {1 i" x2 |5 Y, N - *返回值:读到的数据
3 S' E' G$ F$ Q2 G% t1 W5 @9 s- t - */( L- [* e0 ^8 z1 A4 D% {
- void Eeprom_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)% ?- R8 }# y* V6 ?
- {% Y9 D9 Q: R3 k# K* F
- while(NumToWrite--)
* j+ r" k* ]5 G - {
E% r& K3 k& \" ?% p/ z - CLRWDG();
, P: j4 B- ~* N5 g$ M, w - Eeprom_WriteOneByte(WriteAddr,*pBuffer);
4 x. G* ]$ m6 N. P* {/ `: s. g5 G - WriteAddr++;1 F/ s( Y$ w" [, ]1 P" V1 z
- pBuffer++;9 j7 J5 J. [# l
- }& p, @/ ?+ K) q% C" H
- } M4 f/ A7 r, s/ P- H
- $ ~1 g" ^! _9 r. U5 v
复制代码
, W" z: Z, S7 y
1 z& I2 d* a! S# y' \
. q8 P2 w u2 T+ D4 u' o7 ?
* k% ?+ O7 A: K' N' v! e8 e* {; i |