EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 EDA365_PCB 于 2024-1-22 17:54 编辑 ' N9 g- j, e3 z& X j. y7 N3 V
# I- b6 \9 _, _. nI2C七宗罪之第五罪——没有ACK怎么办? 2 t# d' S# u. R/ M. U' ^
EDA365原创 作者:John
0 [4 h$ k) d5 p* @每一笔I2C的访问都是随着设备互相之间的ACK后结束的,这就好像你和别人商量个事情,要等到别人答应了,这次对话才算结束;又或者你给别人寄一个包裹,一般要等到收件人收到东西后,给你回了电话,你才会认为东西送到了。 这里的“答应”和“回电话”就等于I2C里面的ACK,这一点在前面都已经反复叙述了,这里不再展开说明(可以戳文段开头的链接回顾哦)。" M7 {2 ]" x. f: w) @
我们先来看看下面这张图:
/ c" O5 A: a w/ S5 A
做几点说明,让大家明白讨论内容。
. T$ T; P% T, \+ I1 Y; X1.系统串口打印信息如下,表示I2C访问失败:
0 B( S3 B( g: Y `0 y7 E& Y' C, D9 Q$ K& v5 ] z$ R
I2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed. 8 A1 _* y3 N( F. m
I2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed.
2 O. H) l! T' ?: L. D
* t* o: A5 ?, d0 N( D2 _2.上图中我在ACK的位置坐了标注,细心的读者只要和下面这张正常的图一比较,就可以看出差别,在ACK的位置,SCL为High/SDA为Low,但是上图确刚刚好相反; 3.我们现在知道在第一个ACK的位置, Slave设备本来应该给出SDA=Low,为了更加清楚的分析问题,我们再来一张说明更多的图。 由前面的说明,我知道是Slave设备出了问题,那么到底出了什么问题呢?
8 Q3 b r9 \ b: O W3 e我们先把最前面那张图的案例分析一下,可能有人已经注意到了图中有一个@-40C,对了,没错!就是我们的交换机放在温箱里面做高低温时,在零下-40C的时候发现的问题。
/ p6 r4 t7 P3 U7 L; o% U) u i5 L5 D3 c6 ~, Z% p1 ^1 D
有人问-40度下,这波形怎么量到的啊? 这明显问到了关键点上, 硬件工程师的辛苦就体现出来。首先要把I2C信号线和串口线分别从板子上焊接出来,再分别连到外面的示波器和电脑上,然后就苦逼地守着温箱,运气好的话很快就能复现问题,运气不好要折腾很久才能trigger到这个issue,真的是一把辛酸泪啊。
/ G+ _) T$ j, t( b7 f5 B+ g3 J9 {解决的问题过程更加复杂,而且并没有什么技术含量可言——说服Supply Chain的人认为是vendor的器件问题,让他们在芯片生产线做Screen的时候,从原来的泡-40/5分钟改为-45/20分钟,把没有margin的芯片筛选掉。这个和Supply chain以及vendor沟通的过程是痛苦的,大公司嘛,不说了,你们懂的……
( r4 k w3 X" l2 v3 e% h) C8 y
9 \5 G3 d, c/ P( I) H1 E现在我们知道了器件受环境影响会产生I2C不ACK的问题,下面这张图是另外一种情况,先故设迷局,一起看看下图中有什么问题?
/ z" K3 E. p- l$ i/ N
我承认,这个真的不好发现,以前团队中的某工程师在调试一个Sony的IMX291 Sensor时,CPU通过I2C死活访问不了,最后把波形一点一点在示波器上触发下来看,还是看不出来,这就难怪,没有经验确实很难找。
5 c! h4 b: P" {* `( S/ w, e) ^) _, \6 b% {3 A! ^
我们先来看单次写操作:
: b4 [# o# Z! h9 y. ^+ o) B1.Start 2 S* W' h1 V; `2 |3 m
2.Master发device address
5 u, k2 F- B9 I6 b8 Q3.Master发 R/W为Write 2 y& c! ]: c$ Z8 B% [+ C
4.Slave 回ACK
5 N5 v# A4 g4 d$ `) v7 L5.Master发寄存器地址,也叫Word Address " y% d4 d% ~5 M- G5 U% K
6.Slave 再回ACK
7 X1 ?( y+ q2 |( f7.Master发要写的数据给Slave
( k$ |2 B/ i1 C$ f# p$ U0 W8.Slave收到数据后回ACK
. E2 `, |; J2 w9.Master看到ACK后发Stop结束本次操作 4 ]8 O# X" D7 s K+ v* i' E
3 h2 j* e! G, |* ~5 H! Y7 B
我们再来看单次多操作: 5 o% W. Z. ~- R) v1 Y
1.Start
) Y" o3 g# N' m, R8 c1 I# I2 h2.Master发device address
9 P+ e( {& f( A" e8 q% W0 P8 h3.Master发 R/W为Write W, \- K; `% L8 e; C4 g8 i V
4.Slave 回ACK
; ]+ ^$ ?; i! R2 v6 g5.Master发寄存器地址,也叫Word Address , a( h( c# q. ? x7 [
6.Slave收到后再回ACK
% e4 c! s% H# `7 C6 r7.此时Slave内部的寄存器指针已经知道对应的寄存器地址
: x$ h9 A2 H* s& A: h( j+ k8.Master发start ( q3 O) F0 h N4 O
9.Master再次发device address 3 F/ G5 K V A! P U+ w1 v8 }+ ^
10.Master 发R/W为Read
0 L( i9 X0 D* a) |! D11.Slave发出ACK
, F' a/ o/ Y9 ? A9 R12.Slave发数据给Slave
+ o6 _; X: N) u/ p: ]( f13.Master收到数据后发NAK给Slave 3. \/ v1 d% v8 F4 x0 }8 q
14.Master发stop结束本次读操作
' U) S: l: Z# A3 `9 C* B) c: Y, T1 ^. ?
所以上图的读操作一共有两个错误,为了防止读者烧脑,我直接标注出来吧: 2 ^/ t( i1 Z' b! ^$ \5 s% I
不知道大家在前面阅读的时候有没有看出来呢? 特别是第一个Start很容易漏掉,不是老司机一下子真心发现不了。5 ^" u1 ~" ~9 z9 j8 |
添加了这里漏掉的START和ACK后,我们的Sony Sensor终于可以访问了,所以时刻要注意ACK是否少了。
8 V6 K$ F/ N" e) l# M4 C' x, i- x/ N- |4 S
为了让大家清晰理解,这里给出一张完整的逻辑图,大家在理解时要注意和写操作做对比,然后一定要独立思考弄清楚为什么会有这样的差别?一直到自己彻底想明白了,以后独立解决问题的速度也就会变快。 0 [9 P. C, z5 C8 L# ~/ t
最后我再给大家看一张图,请大家自行研究错在哪里? 答案我们将在“第六宗罪”里面揭晓。
9 t" W+ c; b4 {( n- `5 y2 Q1 T注:本文为EDA365电子论坛原创文章,未经允许,不得转载。
1 a6 | z& s* w" l |