1)以STM32F407为开发平台,通过模拟SPI对W25Q128进行读写操作:
硬件原理图,与《STM32的SPI通信(1)——硬件SPI》中的一样,在这里重复一下:
这次,不再使用引脚复用功能了,将PB3、PB4、PB5当做普通IO口使用,所以刚开始需要初始化SPI的4个IO口:
注意,DO——PB14,对于芯片W25Q128来说是输出,但对于单片机是输入的,所以这个引脚需要配置为输入上拉模式。最后一条语句W25Q128_CS=1,意思是将片选信号PB14置为高电平,不选中芯片(W25Q128是低电平有效的)。
接下来就是这篇文章的关键点,读写函数。我们先来看一下SPI的时序。由W25Q128的datasheet可知,W25Q128支持SPI标准通信:模式0(CPOL=0,CPHA=0)与模式3(CPOL=1,CPHA=1)。这个在小秋的前一篇文章《STM32的SPI通信(1)——硬件SPI》中有过介绍,这里不再描述。我们以模式3为例:
标准SPI通信模式3的时序图
这里需要说明一点,时钟SCK先置为0,再置为1,delay_us(1),延时1us,这个是根据芯片datasheet来设置延迟时间的,datasheet中介绍的需要延迟时间都是纳秒级别的,所以延迟1us足够了。还有就是4个引脚的定义(这里采用位带操作进行定义):
W25Q128的datasheet中,有关于读取芯片ID的介绍:
在主函数中运行以下程序,我们就可以验证读写函数是否正确。毫无疑问,LED1灯亮,说明程序已经正确读取了W25Q128的ID(datasheet中有介绍W25Q128的ID为0xEF17)。
2)以上都是在STMF407平台上实现的,现在在STM32F103平台上运行一下,看两者程序有什么不同。因为在STM32F103上硬件有所不同,使用的是W25X16,原理图如下:
首先我们使用引脚复用,硬件SPI实现对芯片ID的读取(W25X16与W25Q128类似,读写时序一样,具体见两者的datasheet,这里不作详细分析):
主函数运行:
下载程序之后,我们可以发现LED1灯亮。以上程序不作详细分析了,芯片ID、读取ID时序,在W25X16的datasheet中都有详细介绍。
下面看一下模拟SPI:
在主函数中运行:
毫无疑问,LED1灯亮。
比较STM32F407与STM32F103的程序,我们可以发现,除了IO口的配置有所不同外(STM32F407与STM32F103的IO口配置本来就不太一样),其余的都完全相同。所以说,掌握了硬件SPI和模拟SPI之后,不管在哪个平台上运行,移植过去就行。
OK,SPI通信就写到这里了。在这里小秋想问一下,看懂了以上程序,自认为学会了硬件SPI和模拟SPI,如果在实际工作中给你一块SPI通信的芯片,你真的会使用吗?如果在这块芯片的datasheet中,没有介绍这块芯片适用标准SPI通信的4种模式,而是画出了类似SPI通信的时序图,这样你能够上手吗?还有,如果这块芯片datasheet中没有写出芯片的ID呢?有机会的话小秋再写一篇文章,介绍自己在实际工作中应用到的SPI芯片。