SPI程序参考了某宝购买的STM32开发板附带的程序包,基本上能工作,但是时间长了发现偶尔会出现读写数据错误。一开始怀疑问题的重点是读写外围设备的时序不对,后来反复调整,还是偶尔出错。最后发现是SPI的管脚初始化错误。开发板的程序如下:
代码把Pin5,Pin6,Pin7(MISO,MOSI,SCK)全部配置成GPIO_Mode_AF_PP模式,全是PP(push&pull推挽)输出模式,这是错误的。第二功能的输入管脚应该配置为输入模式,即GPIO_Mode_IN_FLOATING或GPIO_Mode_IPD或GPIO_Mode_IPU。第二功能的输出管脚配置成GPIO_Mode_AF_PP是没错的。
上图是ST的参考手册,上面写明了第二功能输入必须(must )配置成输入模式,第二功能输出必须配置成AF输出模式,第二功能的双向端口也是配置成AF输出模式。那为什么把输入管脚配置成AF输出模式还能工作,只是不稳定呢?下面看一下第二功能管脚的电路图。
上图中,如果把管脚配置成Input Mode,图中Output Driver模块内部的P-MOS和N-MOS两个MOS管就会完全关断,对电路就没有影响了。或者关断后使能上拉或下拉,由于上拉电阻和下拉电阻都比较大,外部电路可以驱动这个电阻,不会对电路造成影响。
但是如果配置成Output Mode,图中Output Driver模块内部的P-MOS和N-MOS仍在工作,两个MOS管有一个会导通,一个会截止,这两个MOS管的输出与外部驱动会产生竞争,那个驱动能力强,最后产生的电平就是哪个的驱动强的输出。或者是两者驱动能力差不多,最后得到的电平就是一个不稳定的中间电平。
所以最后的结果是,由于外部驱动和内部驱动竞争,使得最终该引脚AF输入得到的值不稳定。解决办法就是把第二功能输入引脚初始化为Input Mode就可以了。