原创:茶杯的杂物屋 文章来源:
http://racede.me/talk_about_stm32_i2c_peripheral.html
这篇文章有些历史了,但很经典,可以参考学习!
引子
STM32的硬件I2C很多人都对它望而却步。因为很多电工都说,STM32 硬件 I2C有BUG、不稳定、死机等等……最后都使用GPIO模拟I2C。
的确,模拟I2C好用。但是在我看来在一个72M的Cortex-M3的MCU上这样做非常不妥。一般来说I2C是一种慢速总线,就算工作在400kHz的快速模式上,I2C传送每个字节仍需要至少23us——还没有计算地址、起始信号和结束信号的发送。如果使用GPIO模拟的I2C,这23us的CPU时间都在空转中浪费了,而这23us已经可以做不少的事情了,所以在STM32上I2C还是使用硬件为佳——虽然它多多少少有点缺陷。
这篇文章不是给完全没有接触过STM32 硬件I2C的新手看的,看这篇文章之前至少先阅读STM32的参考手册(RM0008)。
概览
我们先来看一下STM32 I2C硬件的结构
我们可以看见STM32的硬件I2C有两个和数据有关的寄存器“数据寄存器(Data register)”(DR)和“数据移位寄存器(Data shift register)”(DSR),我们的软件写入的是DR, DSR用于I2C数据的移位发送和接收,DR和DSR的数据交换由硬件控制——发送时DSR为空,DR不为空时,硬件自动把DR的数据写进DSR;接收时DR为空,DSR不为空,硬件自动把DSR数据写进DR。连续数据传输时,这样两个寄存器的数据交换使得软件读出和写入DR不会影响I2C总线中的数据接收和发送,使I2C的效率更高,这看起来十分美好,但是正是这个特点在某些情况下会变成电工们的噩梦。原因有二。
1、硬件上,DR和DSR的交换机制存在缺陷。
2、软件上,因为DR和DSR一共能容纳两个字节的数据,导致接收时候NACK的设置有一定的不可预料性。
硬件
硬件I2C上的缺陷,新版英文ErrSheet已经写得很清楚,就不引用了,这