一、AT24Cxx系列芯片简介7 n V5 n W: k9 }4 Q
EEPROM是指带电可擦可编程只读存储器,一种掉电后数据不丢失的存储芯片。4 l% {1 O v$ O- \7 v: L
AT24Cxx系列芯片是EEPROM芯片的一种,它是基于IIC总线的存储器件,遵循二线制协议,由于其具有接口方便,体积小,数据掉电不丢失等特点,在仪器仪表及工业自动化控制中得到大量的应用。8 x$ X4 T \: q
AT24Cxx系列芯片 在电路中的主要作用就是在 掉电的情况下保存数据。
/ i( }" z4 w" a) _( n v* Y
L) \) G- G& j# y( H- j' N8 `+ {# i& [1. 存储结构* Q( p6 l, Z2 W0 t
% s4 U" d' ?4 p* C" G; A3 X4 v7 E
& E, O+ c; _1 n* G3 |
2. 引脚
2 X7 S. L4 G5 Z% wAT24C02,AT24C32,AT24C64,AT24C128,AT24C256' C& `- a7 E. @' E( H
这五种型号的芯片,引脚图都如下所示:
0 N5 O9 v }1 z
2 O" x" ?% t5 J/ j; l5 `# F7 g
6 w1 x% X/ L2 ]" v
5 C; _# L, r) o5 f: z! z引脚说明如下:+ W6 h* y# ^$ s% Z
6 M4 ~+ x2 |; b* C
6 U8 T. P! K1 Z3 t% E* ?0 y
4 R8 ]( k+ T1 t& BAT24C04,AT24C08,AT24C16
N8 s) {) _& y+ P这三种型号的芯片,引脚图都如下所示:* H# r% w4 U' u5 C5 [9 h+ Y
$ V3 r' I8 Q% A6 |3 r8 a8 m; ?
3 h. V' I) P: W. v& |
4 j4 t( y6 q- B* ~! _3 P, g# j
AT24C5129 h8 F8 F" e2 A% i: W
引脚图都如下所示:
5 e' S+ b- n3 T8 ~! W- U$ {! c/ c; r/ \, ~7 `0 W8 Q; ~$ P' D
0 W4 ?5 \( [& l9 i( `4 g4 ~# s5 D
, k# X7 \% n, W% @
A0和A1是硬件地址,NC空脚可接地,总线上同时级联4个AT24C512器件。2 W6 M* l l3 [5 F" c9 L* T0 Q, E
; t, L% T) j2 l, c$ N* ?3. 原理图. M" z `3 d- R6 [# Z
7 m/ i1 ^3 X) T
9 n7 {- K3 q/ l1 C& z/ s, L+ @! t: D& p1 r; h3 x
4. 从控设备地址& H$ i1 S8 l1 L* n3 G
从控设备地址前4位,所有型号都是一样的。
2 E) ?0 `% S5 U$ p3 p随后3位是A2,A1和A0为硬件地址位,与硬件输入引脚一致;P2,P1和P0为数据地址高位。5 H. u' @- b, I, c6 e
最后1位是读/写选择位,1为读操作,0为写操作。) [; O6 ~* g2 t; c8 f( `
7 M, j8 z& y8 }
+ T5 b9 e& s. X' s
/ B- U& Q4 u4 u" B% X( @ f. ?+ w二、IIC总线的数据传输$ ^, X/ |7 B, z( C
IIC总线上的每一个设备都可以作为主设备或者从设备。- g! ]$ w# U: d3 h
每一个设备都有对应一个唯一的设备地址,设备地址就是通过A2,A1和A0物理接地和拉高决定,主从设备之间就通过设备地址来确定与哪个器件进行通信。
3 o8 g: J$ F) w( G" }这次以STM32F103开发板为主控,以AT24Cxx为从控。
. o8 L# b( W" f p- ~
$ _% r5 {6 f9 r2 ~& C# S- C1. IIC总线数据传输协议# S5 m/ ?& F: y; K0 j' R: o5 f: d
主控设备在传输有效数据之前要先指定从控设备地址,然后确定数据传输方向 (0表示主控向从控写数据,1表示主控向从控读数据),然后传输数据。2 r) M9 q% O3 C$ b6 ^* t4 D& w
- i+ y+ v) \' T: X
- ]* i2 H& V# h' @% n
& }5 P& s; h! A# W) A/ K
2. IIC总线主控写数据+ L- K0 I/ E) ]' ^3 V5 v
IIC总线主控写数据时序图3 W+ j+ K; h, |' x/ N: m
?3 r- W$ ? L' K: F/ D
. C m0 R U6 F. x) T# }. ~
- K, u1 V% H: f W0 U1 ~主要流程:
, D; K' R" N: c: F# j8 o3 l9 ^3 ^& u; l- Y8 `
主控发送起始条件- d: x6 j" j, |' G
主控发送从控设备地址0 P$ b+ L7 R# J- k& a
主控发送写操作
* F9 G$ W' a& n; g1 K8 E主控等待从控应答:应答失败,主控发送停止条件;8 L% ]2 V' x; t" r" o( e8 e
应答成功进行下一步9 E2 N/ _0 _- b! _: {$ G6 i- @
从控应答后,主控发送要写入的数据
- ]* r: P1 L. A b# d! y: R* c6 A主控等待从控应答:应答失败,主控发送停止条件;
0 X( m! x* C& J! O. S6 x' s 应答成功,进行下一步
6 s# X( v8 y9 w2 m5 X主控数据发送未完:重复5和6步骤;8 n0 O4 q; X: R
主控数据发送完毕:主控发送停止条件, V7 ^( x1 [, K/ J) W
: u: _+ x- n) c1 \, v. H3. IIC总线主控读数据0 f& W. M6 `0 A! ^
IIC总线主控读数据时序图5 v9 L0 B _; z Y% B5 Q% c
; d6 s1 D5 r' d F
, r! k3 M. B* D3 m( T: D& R
1 Z& r! N% B" {: f/ r主要流程:
4 Q4 A. P" _8 _* n9 n: ]. T% Z0 r主控发送起始条件7 y" q/ Z: E; l0 y7 F! Q: \
主控发送从控设备地址
; d2 c( L3 |; p+ T2 p主控发送*读操作**
4 G Y/ ?* g5 x3 ]7 t4 K) Z主控等待从控应答:应答失败,主控发送停止条件;; j: Y) `* S. i0 w% t
应答成功进行下一步0 m! F4 u. @2 v" Y
从控应答后,主控读取从控发送的数据
- B2 O) M+ i# R+ \% T主控发送应答:应答失败,主控发送停止条件;
5 K' \/ C B2 _ 应答成功,重复5和6步骤( b3 I# t W6 V
+ F) i8 D- B' V8 A( @三、普通I/O口模拟IIC总线读写AT24C256( I) Y, o" D+ s7 J
$ p5 U9 G5 g; }
( |7 l0 J7 n0 |9 P" M( ]
, p5 r' F" O* T9 s, T- U1. 原理图
: D) E0 }, Q+ D, M" T, E) E% N; A% q) h; K" o
$ |5 z4 @1 u) F1 M/ N) _/ Q/ I' w" L
2. IIC总线底层驱动程序9 V+ j( M. ~% @) W
文章链接:STM32F103标准库开发—IIC主控实验—普通I/O口模拟—基本原理和底层驱动程序
2 k" B' ]) U' G" s+ R: z/ c) N. p. o2 t! ~ \, Q# l6 K. X( @
3. 普通I/O口模拟IIC总线读取AT24C256数据$ j, N* d) v4 G
具体流程如下:
' v5 ^3 K* D+ c3 ?) {$ ^# H写入数据地址----此地址为读取数据的起始地址
( X* T' u |9 K& I/ M读取数据----可以读取多字节数据/ `/ J/ q |# l9 t' B, F4 d
) M7 O1 A$ |0 I8 L& w' r& [8 o具体程序如下:
$ K# E* p$ ^; C/ h6 @" j; I9 [! C: _, R" k
- /**' Y9 ]1 f. M0 Q
- *@功能:读取指定字节数据, D0 f8 e2 K( c. O) c% Z
- *@参数1:ReadAddr---读取数据的起始地址0 v% v% }0 U ?# o- r
- *@参数2:*Rdata ---读取到的数据缓存起始地址0 ?; V |' D) z$ y
- *@参数3: Num ---读取数据的个数
% H$ @8 ~6 o6 d" v- r( g# P* t+ D - **/: P \1 y: X5 h/ }4 R* N
- void AT24C256_ReadData(u16 ReadAddr, u8* Rdata, u16 Num). k( u# ?# j1 v- }8 L/ [7 I; n
- {
- P8 i) C: K- G2 p! f* w8 D2 L - IIC_Start(); //发送起始条件 1 n" s% O! j" f
- IIC_Send_Byte(0XA0); //发送写命令
5 F' K! P6 x, b1 h; y3 I - IIC_Wait_Ack(); //等待应答
. \, Z* Z( _+ `- M. d' z7 T# Q% G - IIC_Send_Byte(ReadAddr>>8); //发送高地址
* A0 N7 l( T2 T" C) J - IIC_Wait_Ack(); //等待应答- z6 @+ I* t5 |$ z- R
- IIC_Send_Byte(ReadAddr%256); //发送低地址# O, [5 x$ ?* L2 } {" `, t
- IIC_Wait_Ack(); //等待应答
! v+ N5 h2 {/ Y& ?! m - IIC_Start(); //发送起始条件
; T; d: n5 R3 Y; l, r - IIC_Send_Byte(0XA1); //发送读命令
6 ?/ ^ p4 Z p j3 p - IIC_Wait_Ack(); //等待应答
& ?4 d7 R" i) {9 j2 K, L - for(int i=0;i<Num;i++) //读取数据6 H0 r4 K3 f, A& l) |; I2 ^
- {
( \, Z/ ?/ @# r) w6 c H - if(i==Num-1) {Rdata<i>=IIC_Read_Byte(0);}//读取最后一个数据后,发送非应答命令
$ c1 O: Q5 ]. @5 l( n X9 ?& O - else {Rdata<i>=IIC_Read_Byte(1);}//读取其他数据后,发送应答命令 x$ q, {8 R F0 A
- }8 P2 a0 i3 h* Y+ X+ t: _) w
- IIC_Stop(); //发送停止条件 : t/ u* k1 p8 a5 w4 R3 g! n
- }</i></i>
复制代码
; X9 P j% z& u4. 普通I/O口模拟IIC总线写入AT24C256数据
# r1 t# X4 q! r具体流程如下:3 ~& v7 b) `7 c& T( P7 k
写入数据地址----此地址为读取数据的起始地址
$ X9 F$ {# |/ L+ s写入数据----可以写入多字节数据- F7 Z4 o# S3 w2 P3 O' _4 E, Q
AT24Cxx系列EEPROM,页与页之间写数据需要延时10ms。 W( \* Y& o( L: ~, Y. t
AT24C256 每页可以写64个字节数据。
( r, A, ?: P( _8 D$ U; }# `$ e1 W页写程序如下: y: s! X4 ?( _5 ?
7 ]/ g) ?5 N" l7 c
- /** S% g2 h! e K9 e. v" J$ v0 q
- *@功能:在一页中写多个数据
- @% g+ ]+ S0 o+ c) Y ^; K! P - *@参数1:WriteAddr---写入数据的起始地址6 Q; L) L5 \1 W2 c& U
- *@参数2:*Wdata ---写入数据缓存的起始地址' [2 v4 p6 j) l
- *@参数3: Num ---写入数据的个数
8 s4 j" p+ z# T# C - **/
# G$ v, N+ d, w! G6 i - void AT24C256_PageWriteData(u16 WriteAddr,u8* Wdata,u16 Num)
9 L; ~5 @! c/ l! q2 } I* j+ z/ E - {! W" }/ R! F, h0 t
- IIC_Start();
! r4 r* }( P0 F& C - IIC_Send_Byte(0XA0); //发送写命令- N& d/ k: K z; p1 A
- IIC_Wait_Ack();( u; r. }6 o2 k( \& u3 Q' A
- IIC_Send_Byte(WriteAddr>>8);//发送高地址% G* V9 ?6 K. o1 O) `2 f9 U4 y
- IIC_Wait_Ack(); " L" x# j5 k6 x( e$ Y, L9 A) J
- IIC_Send_Byte(WriteAddr%256); //发送低地址
& Z# ]2 ?% d1 A5 Q' w! {+ R - IIC_Wait_Ack();6 A9 g4 J1 z1 M* ^4 ]6 o3 ^
- for(int i=0;i<Num;i++)1 x- q+ W! s6 b2 D9 n2 d) L
- {
; Y' c7 o U" q0 z4 K K G - IIC_Send_Byte(Wdata); //发送字节
) A7 w$ p' \( F& ?- c+ ~/ D( Y - IIC_Wait_Ack();
0 O( a$ D, G( _) h$ T - } 5 }& J% d0 j( m1 H
- IIC_Stop(); //产生一个停止条件 + I( @) G/ Z' {! t( _
- delay_ms(10); //每写一页都需要延时10ms后再写入下一页, w9 [8 h9 _- ~3 C7 P1 G
- }
复制代码 9 P# O. E. Y6 \) d) J+ n6 h5 |
AT24C256 写入多个数据6 k7 I* ^" M$ [
具体程序如下:
3 K6 A' C$ t4 i! z; E& u1 |8 G0 A' }' p* s: k$ ~
- void AT24C256_WriteData(u16 WriteAddr,u8* Wdata,u16 Num)3 l" G- V$ B1 G6 H
- {
$ D, [* Q( m6 f. w# _- k0 _4 D - u16 Addr_mod=WriteAddr%64; //起始地址在本页的位置" z, `& K( r( S _' v" _ y
- u16 Num1=64-Addr_mod; //起始地址那一页数据个数" v! q/ k1 q# P ]+ `
- u16 PageNum = WriteAddr/64+1; //起始地址在第几页
" m. |5 {: ^2 O- ]4 i% i - if(Addr_mod+Num<=64); x! ]& |1 e* U7 r. h: [) W* C# {
- {
. R5 r0 T5 e1 v - AT24C256_PageWriteData(WriteAddr,Wdata,Num);
3 ]/ {+ `8 F. J - }
4 I( _% G4 p) }9 X' t - else
4 ?' |( W( q; k4 P( o5 p, u& s - {
% D* g7 i. C, j - AT24C256_PageWriteData(WriteAddr,Wdata,Num1);//写入起始地址的那一页数据
1 U. M$ r$ m% `+ v# i; h. @ - for(int i=0;i<((Num+Addr_mod)/64);i++)7 B! O v# _8 E: x- N8 z9 N: @2 Y- @
- {! ]# X4 k. p! Q& U: ~& C
- if((Num-(i*64+Num1))>64) //判断这页是不是最后一页8 Y5 M8 O1 @0 G8 \4 i) q+ N% c
- {) J9 B/ b) ?* K4 w- L
- AT24C256_PageWriteData((PageNum+i)*64,&Wdata[i*64+Num1],64);//中间整页写入
; v# o+ n8 ^/ B2 M! ^. z5 \$ C" e - }1 n9 @$ F9 S5 _
- else" T5 W0 M. ^; t7 q. j. U
- {* u9 z+ s7 x4 ~ u. G$ x9 v& G8 O
- AT24C256_PageWriteData((PageNum+i)*64,&Wdata[i*64+Num1],Num-(i*64+Num1));//最后一页写入# v' D( S' L) |. Y4 I! O
- }& b- O% g+ B: N/ F
- }
( h8 u! f$ h n4 n& J7 u) r - }
& p. w7 c( i# K, o - }" j! C7 g9 ~' P Y6 X( }
复制代码
! ^) c; o4 D) G: Z! v. j- Y————————————————
# Y5 l- Z4 }2 s- _版权声明:根号五" t( W/ c* o n A0 z% M& P9 c Q; d
2 ]) O- [* q$ d5 l4 S9 w
# I5 y5 J% v1 K3 t8 x; g
' h$ ~) z! m2 ]& T0 x! F
|