一、AT24Cxx系列芯片简介
: N9 \% ], ^/ sEEPROM是指带电可擦可编程只读存储器,一种掉电后数据不丢失的存储芯片。
6 R+ H# p* Y3 d: f. T/ \/ jAT24Cxx系列芯片是EEPROM芯片的一种,它是基于IIC总线的存储器件,遵循二线制协议,由于其具有接口方便,体积小,数据掉电不丢失等特点,在仪器仪表及工业自动化控制中得到大量的应用。
. y- g# g5 y7 KAT24Cxx系列芯片 在电路中的主要作用就是在 掉电的情况下保存数据。* V0 i! v) |- j# r: N
2 y$ i* [# V4 X/ Y1 W1. 存储结构1 A" J( p& p( D6 x- s
p7 i) R% f. U: [/ z0 N& z8 d
2. 引脚$ E6 k- Y% A6 e4 F# K5 m+ q( J5 H" |
AT24C02,AT24C32,AT24C64,AT24C128,AT24C256" m i% y) ^. A: d- B
这五种型号的芯片,引脚图都如下所示:
5 Y6 W0 C, ~$ e
! d& P: F$ K) n8 Y" |
& S5 z2 V" a! \- s \
/ n6 I% f1 Y( I+ E# i' m- z1 V
引脚说明如下:
/ u, C' j% C4 D# k" ^
0 s6 S' _* \: ~
+ ?% D6 s7 N1 S; ?; u9 ]; j
" [" Z; p4 s5 g$ N* @. P2 d
AT24C04,AT24C08,AT24C16
7 h- b1 n C' Y# Z Q+ \% v这三种型号的芯片,引脚图都如下所示:
4 t+ h' _" m# R9 e
. u3 c* J' K1 C
* {2 _7 n( a! a+ e0 I
1 Y2 F/ X- N' _3 C* }AT24C5127 c; \& m9 m6 @5 |
引脚图都如下所示:# ^& C' P6 U9 V8 T- x" O
) ?6 j+ b* |& |. f9 Q5 r) D. G0 [1 I- S7 F
# a5 }7 g" G$ G" Z! b
A0和A1是硬件地址,NC空脚可接地,总线上同时级联4个AT24C512器件。
6 L8 I+ c( q" f4 w k3 Y& o, Q
, i5 _- g. Q. p0 G3. 原理图
6 Y* O" P' L3 [, P Q9 Q+ w
* z' m% s8 J+ I7 i6 Q
4 Q& c: ~6 T) j- J- B$ W$ y+ K& M
l# z9 ^5 m2 w6 Z4 g0 \6 t0 s4. 从控设备地址9 v' ]! _4 B6 z0 Y
从控设备地址前4位,所有型号都是一样的。2 e0 b4 [# V. H N6 }0 x! H
随后3位是A2,A1和A0为硬件地址位,与硬件输入引脚一致;P2,P1和P0为数据地址高位。! b1 T1 B2 n. d& F. k* K2 M
最后1位是读/写选择位,1为读操作,0为写操作。5 d2 m# e0 z; D5 o4 M
( m1 L2 l$ {# a9 g6 K
- T6 y* d, i7 W) e4 I$ d0 Q
% s% ~" y- o9 J4 s6 i二、IIC总线的数据传输
0 J2 v' ]! c! Z- `3 S% @8 nIIC总线上的每一个设备都可以作为主设备或者从设备。) `, ^" G( h$ W |3 \
每一个设备都有对应一个唯一的设备地址,设备地址就是通过A2,A1和A0物理接地和拉高决定,主从设备之间就通过设备地址来确定与哪个器件进行通信。- p2 Y1 x$ n! Q- S9 }3 k& `+ v
这次以STM32F103开发板为主控,以AT24Cxx为从控。
/ y6 o. w! y/ K7 h4 _
% f. Y, Y0 [& r/ t. q& p1. IIC总线数据传输协议, Y3 J0 V5 W' j Q* J. Z
主控设备在传输有效数据之前要先指定从控设备地址,然后确定数据传输方向 (0表示主控向从控写数据,1表示主控向从控读数据),然后传输数据。# s0 X% ^* n4 R6 ]% n- @
; z0 X9 K j9 t8 }* d
* m1 I9 K' F% X% W4 N- k
: H9 E7 V! e: i, Z$ ^4 o
2. IIC总线主控写数据5 B4 b8 N5 N- d. S1 z, B7 t" P
IIC总线主控写数据时序图
4 v7 ^+ y# h6 n' T3 ?
" Z3 F* y% q) w% ^% U
?, V, f3 m# o* B
9 z6 U' q! a2 p" i. D2 m) N) ?- e5 j主要流程:
: C+ l' y5 i& [4 M! e
. O5 o- u" [- R& k" T主控发送起始条件. f) a$ F" w T) P
主控发送从控设备地址
$ Y0 @9 S2 z7 w% I主控发送写操作% Z) ^! ^- M; g' W1 N$ e$ p
主控等待从控应答:应答失败,主控发送停止条件;: `5 P( [, X, o# S# Z
应答成功进行下一步
7 o/ p; \ z4 d& d, b从控应答后,主控发送要写入的数据7 E/ \5 P; a) K5 O1 g1 j7 l+ k
主控等待从控应答:应答失败,主控发送停止条件;
% L8 z. a8 Q5 ^6 h 应答成功,进行下一步+ [; ?4 w, R( a' `1 O
主控数据发送未完:重复5和6步骤;) l" |, C: D) W/ Y- e1 _0 l* z' P% a
主控数据发送完毕:主控发送停止条件
4 v( p: L( @, b3 Z% z9 J7 K" @1 @; [2 [4 n4 D' F3 f! _) o
3. IIC总线主控读数据( E5 E, ^! ~( R* t
IIC总线主控读数据时序图% o2 o6 w! i& x& I- i% L% M. u
9 L, [8 J/ e1 N
) E3 P7 X) r# r/ c+ y" H, h
8 j" O+ @( F5 j: D/ A3 f k/ }
主要流程:
1 @5 l& k* K5 D主控发送起始条件( @/ |1 P* h. L
主控发送从控设备地址
8 L. d. Q. V1 u; M Y) i主控发送*读操作**
' ^0 z' t' N2 Y2 K/ ^' m, R主控等待从控应答:应答失败,主控发送停止条件; m6 q; `- v; C5 L- G7 ^7 S9 @( E
应答成功进行下一步 R4 T% x2 g% @7 K2 N
从控应答后,主控读取从控发送的数据
T( d! U% J: K0 w8 Y# y2 v% w主控发送应答:应答失败,主控发送停止条件;- _9 h& D" A6 y" [+ t) b
应答成功,重复5和6步骤, k# w- c9 s" U
) o( y" T4 J, a# p' L" _7 ]
三、普通I/O口模拟IIC总线读写AT24C256+ J7 i1 _9 {( t" f$ c! n& R: c
# ~# R# _+ M2 W
q2 f' Z. I2 ?5 z7 x
8 w3 h, x2 e2 B
1. 原理图
& u3 B; k+ F( c: I+ ~6 I9 [. V
; a9 Y+ b' v9 T/ _
" h- h, N+ r2 n# Q; l7 W2 P
& h$ b3 r, d, H+ P0 d% C3 f2. IIC总线底层驱动程序) n2 l) C% i. [( p
文章链接:STM32F103标准库开发—IIC主控实验—普通I/O口模拟—基本原理和底层驱动程序
9 O3 Z( g3 h& l5 M* C: N8 a- D, [5 Z/ E( J3 p' P( f, f p; ]' @
3. 普通I/O口模拟IIC总线读取AT24C256数据
* x1 z* Y, S& E" g" B具体流程如下:
2 U( T! x+ O y( N) x写入数据地址----此地址为读取数据的起始地址
0 H6 ?3 l# ~1 e# v6 Y+ R读取数据----可以读取多字节数据# V" W: a' b; r9 F
. S' s0 c2 ~# p; P& O具体程序如下:/ B8 C8 E; z' n# ^) b& J. Q
# M$ h* s |! @/ y/ r6 ?* e- /**3 O9 x8 Z4 A; F& p6 _3 w
- *@功能:读取指定字节数据/ s4 e( h( z' _9 G6 x
- *@参数1:ReadAddr---读取数据的起始地址
# R; c. j5 m" g0 K# k - *@参数2:*Rdata ---读取到的数据缓存起始地址6 r% P9 S# x: v3 [% p/ ^
- *@参数3: Num ---读取数据的个数
2 G* i* [" J; p' W( W$ W6 `0 L - **/% p1 T7 @0 `6 K, h8 w% V
- void AT24C256_ReadData(u16 ReadAddr, u8* Rdata, u16 Num). \* h$ e7 V4 I
- { ) h; F2 v* O# l% G! F) f
- IIC_Start(); //发送起始条件 , i$ W! C; \& K& Z/ B
- IIC_Send_Byte(0XA0); //发送写命令& L; R3 Y2 A/ I) n& q! m9 y
- IIC_Wait_Ack(); //等待应答
' R: O; y: G! C/ c7 @+ p1 z* x, v% k4 x' j - IIC_Send_Byte(ReadAddr>>8); //发送高地址
* ?& o4 D) A0 ]% f - IIC_Wait_Ack(); //等待应答* `9 g5 n8 v3 \' ~
- IIC_Send_Byte(ReadAddr%256); //发送低地址! r6 y3 b" R8 y( N j
- IIC_Wait_Ack(); //等待应答' n4 X& B8 h- j3 x1 ]& @
- IIC_Start(); //发送起始条件
4 Y8 y0 J/ W/ v: a+ R" ~ - IIC_Send_Byte(0XA1); //发送读命令 8 G% V ^5 e0 Y# Y2 Z
- IIC_Wait_Ack(); //等待应答1 [5 J: M" k3 f0 R2 Q
- for(int i=0;i<Num;i++) //读取数据
- u6 h$ M" d, ?, J* R7 E# W. G* O - {
5 [& ?+ \3 w: p2 m2 X% n M+ e - if(i==Num-1) {Rdata<i>=IIC_Read_Byte(0);}//读取最后一个数据后,发送非应答命令$ N% Z _% ]* |! ?
- else {Rdata<i>=IIC_Read_Byte(1);}//读取其他数据后,发送应答命令
/ m8 q7 [" A) l: \6 G+ H - }
" _$ {+ t8 t& e/ K& m; j5 B7 g - IIC_Stop(); //发送停止条件
) ~. M. @! y$ c- i' U6 W: N - }</i></i>
复制代码
% ?3 O( p) U, [4. 普通I/O口模拟IIC总线写入AT24C256数据) M. w! H0 R+ ~' m/ Q! v
具体流程如下:
0 M5 q( }* a% e4 ~; p" f- ?: e写入数据地址----此地址为读取数据的起始地址# k2 W. O% j- r# H
写入数据----可以写入多字节数据
4 ~9 L* A9 { O5 T3 uAT24Cxx系列EEPROM,页与页之间写数据需要延时10ms。" e9 @9 S1 w* h# m3 }: x* U
AT24C256 每页可以写64个字节数据。
8 e H* }# X9 d+ G3 r8 R8 G页写程序如下:
# o+ t, [- V, v6 e5 b; n' `" r5 E' E/ d) L
- /**2 E, `' ?: x& g9 S. T( t
- *@功能:在一页中写多个数据( v/ y- J9 x( q& p
- *@参数1:WriteAddr---写入数据的起始地址
! a1 s) j$ b3 Q L5 ? - *@参数2:*Wdata ---写入数据缓存的起始地址3 M" \+ n9 Q8 V" K6 Z
- *@参数3: Num ---写入数据的个数+ d* R4 H0 `9 n
- **/
- |4 T. b4 A+ M - void AT24C256_PageWriteData(u16 WriteAddr,u8* Wdata,u16 Num)2 \1 l% ^$ j1 h/ F! L
- {
. Q$ P+ C6 G- `- Q, y - IIC_Start();
0 c( a, D* h( N% r6 q0 i, _ - IIC_Send_Byte(0XA0); //发送写命令
" }. N( J; K- p% E! P ~) D: \! m - IIC_Wait_Ack();
* ?$ z R! }& Z# ?4 } - IIC_Send_Byte(WriteAddr>>8);//发送高地址
/ n! A. o: U; j7 e. J! E, ]2 U - IIC_Wait_Ack();
1 q, E: H; t3 t& Y - IIC_Send_Byte(WriteAddr%256); //发送低地址
4 V/ @4 L; V, L, d. b2 g% ]5 K - IIC_Wait_Ack();
& u/ [: g4 P) w# g- E% i% ~( } - for(int i=0;i<Num;i++)
& D N* x. \8 m1 Q0 f/ k; Z - {
! E: B& Z. A0 O - IIC_Send_Byte(Wdata); //发送字节: x8 \1 M( b+ b: s. D
- IIC_Wait_Ack();
" ` o$ P8 |1 E4 } - } " i6 j. d, N" t; o
- IIC_Stop(); //产生一个停止条件
# W' n( H4 V, Q - delay_ms(10); //每写一页都需要延时10ms后再写入下一页1 ?, u1 W! c6 C( C1 T2 x& x T
- }
复制代码
+ d& m' ]# G% R+ |" {0 T, n5 _AT24C256 写入多个数据4 R! f8 O" l. ]0 J4 [
具体程序如下:" t- P& L; m- \7 `; h# \
* F3 \' z; z% E
- void AT24C256_WriteData(u16 WriteAddr,u8* Wdata,u16 Num)
8 t9 \# U {( G* ^4 [) Y - {
8 T' v: K: f. l7 U) R& k - u16 Addr_mod=WriteAddr%64; //起始地址在本页的位置: C9 ~! l, a& C5 L8 e
- u16 Num1=64-Addr_mod; //起始地址那一页数据个数5 }5 |/ i/ P: S2 U
- u16 PageNum = WriteAddr/64+1; //起始地址在第几页4 |( B% s- ?: c2 G
- if(Addr_mod+Num<=64)
8 ?& E% }. q3 \7 p: a! s4 _) r- Q - {
8 L1 a, m, m- A0 C, [% ~' h - AT24C256_PageWriteData(WriteAddr,Wdata,Num);' H: }( k* f1 ?, T. B7 _7 K5 Y
- }0 K- O. j& d' d' J. Y/ Z
- else' @, C. B6 Y" M7 H
- {) X5 I+ N5 w1 Y/ n# V5 r
- AT24C256_PageWriteData(WriteAddr,Wdata,Num1);//写入起始地址的那一页数据
% ] V% i. I1 l/ L( _ - for(int i=0;i<((Num+Addr_mod)/64);i++)% S" N* n Q% J( o6 o" G& b
- {
4 x3 t7 r2 g1 b3 d% O - if((Num-(i*64+Num1))>64) //判断这页是不是最后一页
0 r; I; L1 N& p- u! J6 a, \ - {
5 [1 f6 k& g2 R0 ?. o9 e6 c" @ - AT24C256_PageWriteData((PageNum+i)*64,&Wdata[i*64+Num1],64);//中间整页写入
6 W/ _2 z4 x0 k6 @ - }
% ], c$ b* L% {" i* @( X; w, Y - else3 h; w2 D) j( i: T
- {( h1 V7 l+ \9 |) L- w! c
- AT24C256_PageWriteData((PageNum+i)*64,&Wdata[i*64+Num1],Num-(i*64+Num1));//最后一页写入- v H5 L! C0 S
- }
, Y: n( }; V }+ ] - }
) H, x, q* A' j- A, V - }
; w/ C' O: ]8 P' i$ _3 _) |; T - }
7 Z" Y8 Q' L8 m" K& u
复制代码 & H; _& W- D9 I4 H
————————————————
1 Y; ^7 x- a9 v3 w8 l) v6 C版权声明:根号五) }5 e; Q3 R8 d) O
8 ^6 f4 F& J8 N# F
[+ D q6 Q0 K( L3 j; Z8 a) ]9 ]" Y: r: g1 }
|