古人说的一句,方法总比问题多,真的一点儿也不假
( U4 f. C7 E" B/ H
8 S9 x5 N: C+ h% S4 S) `硬件有问题,怕啥,大神来支招,就算是先天性bug,一样搞定
# q( e/ E' [$ t8 t最近看到一个硬件I2C bug解决的方案,特来与大家分享
* `: b9 m% y0 S; q大神从芯片底层分析了为啥会有这样的bug,真大神也
7 d, X: r2 A& e0 Dhttp://racede.me/talk_about_stm32_i2c_peripheral.html- t2 f( n/ }, e3 s3 R; F
后面给出的解决方案如下:
$ {1 M+ m" f! _! E2 p( [3 u3 v+ [发送时:
4 R- Y2 [4 H1 K- P/ d. f" h4 G7 g, w
开始,发送写地址,器件应答,清ADDR,一字节数据到写DR,硬件把DR数据写入到DSR,当DSR传输完毕时,DR也为空,BTF置位,这时我们再写一字节数据到DR,如此循环,最后一次BTF置位的时候发送P或者重起始(R)。这样操作,“硬件把DR数据写入到DSR”执行的时间是我们可以预料的,不存在上面提及的冲突问题。2 ]; j) J) J1 S2 p9 x
, S/ K0 R& Q. M; ?8 ]0 I" f接收时:
' |$ E3 A* k, M6 I
8 B& B7 X9 V( r. l2 m1、接收一个字节:按照ST给的方法。开始,发送读地址,器件应答,清ADDR前软件下拉SCL,写完NACK、STOP和DR后软件再释放SCL。RxNE时读DR。
9 B G- u8 z( y% V: e9 P* ]. z, k. n' y1 k
2、接收两个字节:也是按照ST的方法。开始,发送读地址,器件应答,设置POS和ACK,下拉SCL,清ADDR,设置NACK,释放SCL。BTF时,软件拉低SCL,发送STOP,读DR,释放SCL,再读DR。
' [% R$ y; }" S6 Q8 a2 d! g# S
/ t0 L& u* z {3、接收两个以上字节:开始,发送读地址,器件应答,直接清ADDR。BTF时,读DR一次。再BTF,再读DR一次,如此循环。倒数第二次BTF时设置NACK(注意DR和DSR各有一字节的数据),读DR一次。再等到最后一次BTF时,软件拉低SCL,发送STOP,读DR,释放SCL,再读DR。 具体的,还是靠大家自己去参悟啦
, ]9 G; R2 X7 r* e |
斑斑见笑了
不考虑多主机的时候,模拟也是不错的选择。
确实啊,模拟的,可移植性很强。硬件I2C,想规避bug的话,确实很蛋疼,不知道ST怎么想的,哈哈
之前看过一个帖子,不知道是不是真的,说的是ST不愿意花钱买NXP的专利,于是自己做了这么一套。不知道是不是真的。9 }# q0 c% D! X( Z5 ]% P
如果不想买专利的话,像ATMEL那样换一个名字不就好了
坑。。。还好有大神支招,哈哈
另起一个名字,就叫什么ST-LINK,哈哈哈
全都是Link,也凌乱了,哈哈