andi
发表于 2004-12-16 01:25:00
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?快速注册
x
24C256是具有I2C接口的512x64存储器,在数据的存储过程中遵循I2C协议必须的逻辑。/ U' S7 a+ J3 ]9 D3 P5 ~* u8 ]: _$ {
24C256是32K字节,32*8=256K位。(之前一直把这个搞错)" c$ c, b" g( j( [
存储地址问题:
" I% i+ n( K' x+ I24C256的数据容量是32768,即可以存储的有效字节数。所以它的地址是16位整型数,有效范围是0~32768,数据字节为单位存储,在16位地址其中有效数据只有15位,低6(0~5)位地址表示的容量是0~63,然后连续的9(6~14)位地址表示页码的范围是0~511,在数据连续存储过程中,相同听页面内,存储地址自动完成累加过程;数据将从本页开始的地址重新开始覆盖已经存在的数据。例如,地址是63(二进制码111111)表示的是第0页的最后一个存储空间,地址64(二进制码1,000000)表示第1页最开始的存储空间。在当前存储地址是63时如果该器件处于连续存储模式下,数据将出错。
! T& f: B; a0 q0 U原因是什么呢?24C256支持数据的连续存储,最大的存贮数量是64即一页的内容,如果在地址选择上超过了这个限制,数据将会覆盖本页开始的位置重新存储,这就造成数据的错误,在使用上,虽然数据是分页存储的,但在形式上是连续数据,所以存储中不需要特意区分页地址和页内地址。
, [8 E9 U5 |, J5 [在连续存储中,尽管数据每次存储的数量小于64,数据也可能出错,例如每次存储数量为11,地址的变化是0,11,22,33,44,55,66-----,看上去没有什么问题,地址是按照每次11递增的,然而存储的结果还是出错了,原因是什么呢?在地址55开始的空间无法提供连续11个页内存储空间,当地址增加到63以后数据又从该页0地址重新开始,从而导致数据储存的错误。有效的解决办法是如果使用连续存储模式,地址的安排上要使存储块的大小为64,32,16,8,4,2此外都不能使用连续地址存储。如果数据采集的有效数据位小于64,比如每次结果是30字节,在连续存储模式下要按照32为单位存储,不足的字节补零处理。
( ]& j G5 \, O* G: {# [) z7 R* S对于I2C的存储一般情况下,先保留前面1个字节来保存一些界面、ID号、总音量等等,然后再从0x0400开始存储数据。* v7 @! m0 v$ @8 M/ ^5 f3 J
; U8 H; u( L( V' H3 \一):I2C必须知道的术语:
V6 K# J5 s1 qTransmitter :The device which sends data to the bus。
# B7 Z3 z" L. p4 v5 y发送端:该设备发送数据到总线上
" p% i8 d) I# Z( ]Receiver: The device which receives data from the bus
7 |, }' O5 p& w) D. g接收端:该设备从总线上接收数据 * |9 i+ Z# X; w5 n1 ^
Master :The device which initiates a transfer,generates clock signals and terminates a transfer 9 X6 b3 \ |7 D, _ z. V& H
主设备:该设备开始一个传输,生成时钟信号和终止一个传输。
+ {- Q. F8 L4 T; w; n- ]Slave :The device addressed by a master
]; g8 {9 }) v- ?从设备:被主设备寻址的器件。 ! r# q' v7 M; p9 V7 G
(单主设备只要知道上面的就行了,注:一个CPU外挂一个I2C的RTC,和一个I2C的EEPROM的系统也是一个单主设备。标准I2C允许多主机器件在总线上达成,连接多于一个微控制器到I2C 总线,可能性意味着超过一个主机可以同时尝试初始化传输数据。为了避免由此产生混乱,发展出一个仲裁过程。就有下面的名词) ' N0 O- M: X- A8 w
Multi-master: More than one master can attempt to control the bus at the same time without corrupting the message。
% g) @3 ^1 J8 K* }/ iArbitration : Procedure to ensure that, if more than one master simultaneously tries to control the bus, only one is allowed to do so and the winning message is not corrupted。 ! ?/ |" z- E8 o; a4 g& J! u
Synchronization :Procedure to synchronize the clock signals of two or more devices。
. E7 `1 ]8 D; Y二)I2C的数据传输速率(由芯唐科技提供的NUC系列资料得知):
( ^1 ~7 B; s6 C) g总线上数据的传输速率在标准模式下可达100kbit/s 在快速模式下可达400kbit/s 在高速模式,直至 1.0 Mbit/s 的增强高速模式。 2 a. R+ F3 U8 d3 f4 ^
三)明白I2C总线何时可以传输,如何启动一次数据传输:
/ i% D/ Z. }" a6 D% ~% u) a! `
. g3 `7 j7 r% z6 ~当I2C总线处于空闲状态下,说明没有主机对总线发起传输请求(SCL 和SDA线同时为高),主机可以对总线发出起始信号。起始信号,通常表示为S-bit, 当SCL线为高时,SDA线上信号由高至低,标示总线上产生起始信号,新的传输开始。(注:当SCL为低电平时,SDA上的状态可以改变,当SCL为高电平时,SDA上的状态必须保持。如果改变,则对应了一个起始和结束状) ; {+ G+ R- c' k
重复起始信号 (Sr) 。如果产生重复起始Sr 条件而不产生停止条件,总线会一直处于忙的状态。此时的起始条件S和重复起始Sr 条件在功能上是一样的.
, y/ ?/ F/ v) A" e# O# D2 e2 `6 O四)标准I2C传输协议(就是CPU读或写一次I2C器件数据传输过程): $ l+ x( A; d. n K, V d. C
通常标准I2C传输协议包含四个部分 . ^ h0 |+ ]* q& l. B; Y
1) 起始信号或重复起始信号 * m: ~) b! }2 F' a6 t/ G
2) 从机地址传输 + {2 ^1 d+ p, f4 C3 B9 B- S' A3 ]5 \
3) 数据传输
^' P/ L& V6 O n4) 停止信号
3 X D% |; r9 [4 b# x+ p; x
) W3 r K5 Z0 P. E- `1 g(注意上图总共的Sr表示:重复起始信号,MSB在起始位后面表示是高位先发送,MSB:最高位) $ T: D$ ]; \3 N$ N5 i! [! `0 l
知道了I2C传输协议的4大部分,下面先单独介绍其中第2部分(数据传输):
' k" R9 r& i3 JA)主机向从机“写”数据,过程是这样的:主机先向从机发送地址,然后写数据,这个过程传输方向未改变。
% l. o' u! ^+ M: X4 u ( {+ @4 }7 _$ M1 }
(注:由上图得出要明白以下信息: - F2 y. e. M ` O% f4 {
上图的灰色和白色表示含义; & x" P' I \3 r
其中“acknowledge”表示应答信号; # L( o1 V( @0 ?; m% w
masterA = acknowledge (SDA low) “低电平”表示有应答; /A = not acknowledge (SDA high)“高电平”表示无应答)
5 ~+ ^) c% ]1 B! J* rB)主机从从机“读”数据,过程是这样的:主机先向从机发送地址,然后从从机中读数据,这个过程传输方向发生改变。
+ k9 v, M/ [# ~# R ; ~8 o4 A6 I2 i; ?; Y
(有上面两个图要明白以下信息:2 R. p5 {6 Y4 K
地址传输:第一个字节的头7 位组成了从机地址,当发送了一个地址后,系统中的每个器件都在起始条件后将头7 位与它自己的地址比较,如果一样器件会认为它被主机寻址,从而当SCL第9个时钟沿时,在SDA上发出低信号作为应答。至于是从机接收还是从机发送,由RW位决定。
7 }( _' P: U9 l% L数据传输:当从机地址被成功识别,就可以根据RW所决定的方向,开始一字节以字节的数据传输,每字节最后带一个响应信号,如果从机上产生无响应信号(NACK), 主机产生停止信号,或者产生重复起始信号开始新一轮的数据传输。当主机作为接收器件时,发生无响应信号(NACK) ,从机释放SDA线,使主机产停止信号或重复起始信号. 5 V+ [% Z! s% r- g S, E# z
)
1 o7 T% h& }5 C五)I2C程序控制:下面主要通过模拟I2C方式控制,(因为很多cpu都有I2C内部控制模块,传输操作也都是对寄存器的读写操作,不方便理解I2C传输过程,这里特用模拟的方式控制更容易理解I2C通讯过程)
8 ~" ?! N! q, r/ L. |$ e' z. d6 x; u7 |
1)如果要启动I2C总线,当SCL为高电平时使SDA产生一个负跳变,可以利用下面的类似函数:
% B* I! E9 P5 vvoid I2C_Start(void)
! Q" d |( u# s+ x{ ! k; i- }, q- L% z3 E
SDA=1;
, Q1 C' ]! I! @" T" G8 | SCL=1;
. t# ]. r4 |8 B* e( O9 }! c! ? DELAY(DELAY_TIME);
2 s$ p+ h4 R" v6 w6 _, U, b SDA=0; 5 Z% i8 K0 n! @5 }' Y
DELAY(DELAY_TIME); 6 R" H! l$ A \9 y) F( A- G. c
SCL=0;
6 F2 t% o" t/ L; h0 b DELAY(DELAY_TIME);
# b( E% J! Z4 N1 Y* U7 z: _} - d! ^& d8 e5 F
2)如果要终止I2C总线,当SCL为高电平时使SDA产生一个正跳变,可以利用下面的类似函数
2 I+ Z5 @% E1 o$ I# u% ? P2 evoid I2C_Stop(void)
; K& R$ A6 {( B: S' W/ n4 y{ z4 s% g1 T" O/ A) E
# P; ]. Z. U, B- j SDA=0;
0 ]; a# l- n( u' ], { SCL=1; % j9 R2 t% N' k2 Q* t1 V
DELAY(DELAY_TIME); 1 n7 d! [8 I2 A( f6 |
SDA=1;
R; r( t& P) ?) k DELAY(DELAY_TIME);
% C, ?$ q3 s: X$ i SCL=0;
/ P" t& I1 k0 I, b V/ h: j v DELAY(DELAY_TIME); / c" ?) L* I6 j" R" R6 \
} - V) G5 L# k! C* s* ^' }
3)如果要传输一个bit位:注意下图
0 i. b( \9 n, g! @9 @7 t
( i! c! J, m$ M$ J" _$ V9 m(注:当SCL为低电平时,SDA上的状态可以改变,当SCL为高电平时,SDA上的状态必须保持。如果改变,则对应了一个起始和结束状)
- U+ u: z( g. p( J W$ G(低位时)发送0,在SCL为高电平时使SDA信号为低 7 t1 F8 p b$ J P/ k6 _$ @; W
void SEND_0(void) : q- q$ j6 i% V( k3 r0 }
{ 3 I$ X) u2 c3 o) @2 H* M) A/ j! Y, W
SDA=0; 7 D+ H, B- t; C: l( X
SCL=1; ' M! ], U2 Z' B0 l% v0 c
DELAY(DELAY_TIME);
+ K, B/ u( {/ }' l SCL=0;
4 x' ] _7 e7 y, u5 a DELAY(DELAY_TIME); % `6 d1 {, [" d( S. x
}
4 w. l6 e; m) a" [6 n/ _ d6 T1 C; G(高位时)发送1,在SCL为高电平时使SDA信号为高 q# W% m0 s+ O/ S" o7 e, h
void SEND_1(void)
8 G$ T g* h, q" r C3 m F{
0 |" r5 k3 a0 b& p" r: N& ` SDA=1; 4 Q. Z q) C) s" c8 Z Z* ?. F2 G
SCL=1;
% t3 A* A, a, s4 i2 S7 Q DELAY(DELAY_TIME);
8 l% `* I' b* f% c SCL=0;
7 Q) F; r4 C9 y7 w DELAY(DELAY_TIME); |
|
|
|
|