EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 EDA365_PCB 于 2024-1-22 17:54 编辑 6 `1 p3 S! y$ g% t& ^ W
* u- J* l* k# J' s! g, R
I2C七宗罪之第五罪——没有ACK怎么办?
S5 L6 q4 c8 @3 r/ ], Y- Z( M" M9 V7 CEDA365原创 作者:John
1 T% T( p- {& D5 d0 m每一笔I2C的访问都是随着设备互相之间的ACK后结束的,这就好像你和别人商量个事情,要等到别人答应了,这次对话才算结束;又或者你给别人寄一个包裹,一般要等到收件人收到东西后,给你回了电话,你才会认为东西送到了。 这里的“答应”和“回电话”就等于I2C里面的ACK,这一点在前面都已经反复叙述了,这里不再展开说明(可以戳文段开头的链接回顾哦)。7 h( W% j% @* M/ ?" C! g$ b
我们先来看看下面这张图:
! k8 V. l3 @% f0 n
做几点说明,让大家明白讨论内容。
+ O D7 B4 e" r9 z1 v9 V1 D4 ]1.系统串口打印信息如下,表示I2C访问失败:
4 F5 F" y7 h7 w8 N0 n
8 |8 Z$ S" |5 D& a+ d! {' zI2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed.
$ f6 ]/ i, ]' L7 Q ?I2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed.
6 [( l5 {5 l+ R" _$ H* r( k, c) F0 c# n2 q2 K% v1 z! C
2.上图中我在ACK的位置坐了标注,细心的读者只要和下面这张正常的图一比较,就可以看出差别,在ACK的位置,SCL为High/SDA为Low,但是上图确刚刚好相反; 3.我们现在知道在第一个ACK的位置, Slave设备本来应该给出SDA=Low,为了更加清楚的分析问题,我们再来一张说明更多的图。 由前面的说明,我知道是Slave设备出了问题,那么到底出了什么问题呢? # E; L: B$ i6 N0 S! Q9 Z
我们先把最前面那张图的案例分析一下,可能有人已经注意到了图中有一个@-40C,对了,没错!就是我们的交换机放在温箱里面做高低温时,在零下-40C的时候发现的问题。% a6 J8 z2 m& J6 i! B
# P; v5 D$ c& W$ o# r7 S有人问-40度下,这波形怎么量到的啊? 这明显问到了关键点上, 硬件工程师的辛苦就体现出来。首先要把I2C信号线和串口线分别从板子上焊接出来,再分别连到外面的示波器和电脑上,然后就苦逼地守着温箱,运气好的话很快就能复现问题,运气不好要折腾很久才能trigger到这个issue,真的是一把辛酸泪啊。 O& D. h8 T2 b8 p: C
解决的问题过程更加复杂,而且并没有什么技术含量可言——说服Supply Chain的人认为是vendor的器件问题,让他们在芯片生产线做Screen的时候,从原来的泡-40/5分钟改为-45/20分钟,把没有margin的芯片筛选掉。这个和Supply chain以及vendor沟通的过程是痛苦的,大公司嘛,不说了,你们懂的……
- \" F/ O0 s' _! x0 ]! F9 ^8 K B# H) S6 N
现在我们知道了器件受环境影响会产生I2C不ACK的问题,下面这张图是另外一种情况,先故设迷局,一起看看下图中有什么问题?
! K8 [- W6 d/ t9 o& w3 ?2 B; B
我承认,这个真的不好发现,以前团队中的某工程师在调试一个Sony的IMX291 Sensor时,CPU通过I2C死活访问不了,最后把波形一点一点在示波器上触发下来看,还是看不出来,这就难怪,没有经验确实很难找。 t* S; q6 z2 K: v
; Q4 t; I1 H. H6 x我们先来看单次写操作:
# F+ r2 P, v* h8 S: B) V1.Start
. v0 l5 y$ s$ t6 _5 d6 I5 m! T2.Master发device address
' g# K! V5 Q9 j- T, M9 B! j( J3.Master发 R/W为Write . }# ~/ G7 t8 I5 L% c @
4.Slave 回ACK
+ B& L! p! G' U h( \) c3 p5.Master发寄存器地址,也叫Word Address
~$ P- n3 y- g6 h' r6.Slave 再回ACK ) S" h2 {% x( U/ Y( | Z' K+ i9 o
7.Master发要写的数据给Slave 1 W3 T4 G1 g+ _. S7 p3 Q. b9 j
8.Slave收到数据后回ACK $ ^7 Q" y* R% T# Q$ R5 j( F. `6 t
9.Master看到ACK后发Stop结束本次操作 * v' \1 B0 j y" ]' T; P
" S" S. m8 ]$ g我们再来看单次多操作: 7 r. W. d( m; T$ H% u( ^
1.Start ( h" `5 @/ g4 r
2.Master发device address ' }& v5 N# N1 A" x/ s, p
3.Master发 R/W为Write
9 T# d. E/ G& ?' y4.Slave 回ACK 5 w8 s- n8 W) c4 F4 {2 k1 A
5.Master发寄存器地址,也叫Word Address
I+ B6 C" z9 o7 c+ ]9 d( P' E6.Slave收到后再回ACK 2 W6 x9 v! P! t
7.此时Slave内部的寄存器指针已经知道对应的寄存器地址 7 j" L9 {+ X2 L: d' C
8.Master发start
# e- Z4 B# \7 c+ v, u9.Master再次发device address
L, ?' M8 ~7 v# ]" F6 I% [10.Master 发R/W为Read # M/ S7 M6 u0 k/ O F, f" T
11.Slave发出ACK 6 u. }" b. T+ _
12.Slave发数据给Slave
" G3 @% L( B# c4 C6 I o13.Master收到数据后发NAK给Slave 3
% S- C( I0 J, s8 A14.Master发stop结束本次读操作 * ^ a: T2 L' ^: ^2 \
: v' ?! R4 [3 P' V
所以上图的读操作一共有两个错误,为了防止读者烧脑,我直接标注出来吧: $ t3 z8 R) w. h+ Z* n% |
不知道大家在前面阅读的时候有没有看出来呢? 特别是第一个Start很容易漏掉,不是老司机一下子真心发现不了。
, I. f' t! X6 o; X! B添加了这里漏掉的START和ACK后,我们的Sony Sensor终于可以访问了,所以时刻要注意ACK是否少了。
$ M. e/ t, S+ k% X( q: |4 B
6 ?0 u$ n. Z: w2 ~为了让大家清晰理解,这里给出一张完整的逻辑图,大家在理解时要注意和写操作做对比,然后一定要独立思考弄清楚为什么会有这样的差别?一直到自己彻底想明白了,以后独立解决问题的速度也就会变快。 6 \/ q# z/ q5 c. [8 r
最后我再给大家看一张图,请大家自行研究错在哪里? 答案我们将在“第六宗罪”里面揭晓。 ! ]1 y/ U# P) n8 }( E0 h
注:本文为EDA365电子论坛原创文章,未经允许,不得转载。
8 E4 j+ D/ U- D# I/ v: T |