闪存是扩展存储容量的器件之一,厂家为便于用户学习也提供一个GD25LQ128的使用框架,可读取该存储器的ID标识。
该程序的内容如下:
from machine import SPI
from machine import FPIOA
a = FPIOA()
a.help(14)
a.set_function(14,a.QSPI0_CS0)
a.help(14)
a.help(15)
a.set_function(15,a.QSPI0_CLK)
a.help(15)
a.help(16)
a.set_function(16,a.QSPI0_D0)
a.help(16)
a.help(17)
a.set_function(17,a.QSPI0_D1)
a.help(17)
spi=SPI(1,baudrate=5000000, polarity=0, phase=0, bits=8) # spi init clock 5MHz, polarity 0, phase 0, data bitwide 8bits
spi.write(bytes([0x66])) # enable gd25lq128 reset
spi.write(bytes([0x99])) # gd25lq128 reset
a=bytes([0x9f]) # send buff
b=bytearray(3) # receive buf
print(b) # bytearray(b'\xc8`\x18')
a=bytes([0x90,0,0,0]) # send buff
b=bytearray(2) # receive buf
spi.write_readinto(a,b) # read gd25lq128 id
print(b) # bytearray(b'\xc8\x17')
由此可知,其引脚的连接关系为:
CS0----GPIO14
CLK----GPIO15
DO---GPIO16
DI----GPIO17

在对引脚及工作参数进行定义后,对芯片执行了复位操作,即发送数据0x66和0x99,这从该芯片的手册中可得到验证,见图2所示。

图2 软件复位
随后是读取该芯片的ID标识,即发送指令0X9F,见图3所示的说明。
对于不同的厂商,其ID是有所差异的,对于华邦的闪存,其厂商的ID是0xEF,其设备ID则是0x17。
按程序的注释,对于GD的闪存,其厂商的ID应是0xC8,其设备ID则是0x18。

图3 读取ID
至于数据的读写,则需要依据该程序框架自行补充完成。
仍以读取芯片ID为例,通常的C语言程序为:
u32 SPI_FLASH_ReadID(void)
{
u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(0X9F);
Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
在具有C语言读写程序的情况下,可通过对比可实现程序的改写和使用。
在通常情况下,W25Q64与W25Q128应是同系列的产品,在程序上会有一定的共用性,就用手头的W25Q64进行了一下测试,其连接如图4所示。

图4 模块连接
起初会有报错现象,经排除其测试结果如图5所示,说明2种芯片还是有差别的读取ID不成功。

图5 测试结果