一:W25Q128芯片介绍
W25Q128FV(128M位)串行闪存为空间、引脚和功率有限的系统提供了存储解决方案。25Q系列提供的灵活性和性能远远超过普通的串行闪存设备。它们是将代码隐藏到RAM、直接从双/四 SPI(XIP)执行代码以及存储语音、文本和数据的理想选择。该设备使用单一2.7V至3.6V电源,电流消耗为4mA交流电和1uA电源。所有设备都采用节省空间的包装。
W25Q128FV阵列被划分为65,536个可编程页面,每个页面大小为256字节。最多可同时编程256字节。页面可以以16个一组(4KB扇区擦除)、128个一组(32KB块擦除)、256个一组(64KB块擦除)或整个芯片(芯片擦除)的方式进行擦除。W25Q128FV分别拥有4,096个可擦除扇区和256个可擦除块。较小的4KB扇区使得在需要存储数据和参数的应用中具备更大的灵活性。(参见图2。)W25Q128FV支持标准的串行外围接口(SPI)、双/四路I/O SPI以及2周期指令循环的四路外围接口(QPI):串行时钟、芯片选择、串行数据I/O0(DI)、1/O1(DO)、1/O2(WP)以及I/O3(/HOLD)。SPI频率最高可支持104MHz,从而在采用快速读取双/四路V/O及QPI指令时,可实现相当于208MHz(104MHz 2)的双路I/O和416MHz(104MHzx4)的四路I/O的时钟速率。这些传输速率的表现优于标准的异步8位和 16位并行闪存存储器。连续读取模式可实现高效的内存访问,仅需最多8个时钟指令开销即可读取一个24位地址,从而支持真正的XIP(就地执行)操作。
一个保持位、写保护位以及可编程的写保护功能,同时具备顶部或底部阵列控制功能,进一步增强了控制灵活性。此外,该设备还支持JEDEC标准制造商及设备标识符以及SFDP寄存器、一个64位唯一序列号以及三个256字节安全寄存器。
二:特点:
新型SpiFlash存储器系列
W25Q128FV:128兆位/16兆字节-标准SPI:CLK、/CS、DI、DO、MP、/Hold-双SPI:CLK、/CS、I0o、I01、MWP、/Hold四通道SPI:CLK、/CS、100、I01、102、103-QPI:CLK./CS,1O0,1O1,1O2,1O3软件与硬件重置
最高性能串行闪存-104MHz单通道、双通道/四通道SPI时钟等效于208/416MHz的双/四线SPI-50MB/s 连续数据传输速率超过10万次擦除/编程循环
超过20年数据保留
高效的"连续读取"和OPI模式支持8/16/32/64字节循环的连续读取最少仅需8个时钟周期即可访问内存-四通道外设接口(QP)减少指令开销
允许真正的xIP(原地执行)操作性能优于x16并行闪存
三:硬件设计:

四:软件代码:
4.1 : SPI初始化:
void SPI_init(void)
{
SSIG = 1; //忽略 SS 引脚功能,使用 MSTR 确定器件是主机还是从机
SPEN = 1; //使能 SPI 功能
DORD = 0; //先发送/接收数据的高位( MSB)
MSTR = 1; //设置主机模式
CPOL = 1; //SCLK 空闲时为高电平,SCLK 的前时钟沿为下降沿,后时钟沿为上升沿
CPHA = 1; //数据在 SCLK 前时钟沿驱动,后时钟沿采样
//采用漏极开路+上拉电阻方式驱动,需要调低SPI频率才能正常与Flash通信
SPCTL = (SPCTL & ~3) | 2; //SPI 时钟频率选择, 0: 4T, 1: 8T, 2: 16T, 3: 2T
SPI_S1 = 1; //00: P1.4 P1.5 P1.6 P1.7, 01: P2.4 P2.5 P2.6 P2.7, 10: P4.0 P4.1 P4.2 P4.3, 11: P3.5 P3.4 P3.3 P3.2
SPI_S0 = 0;
HSCLKDIV = 0x01; //高速时钟1分频,默认2分频
SPI_SCK = 0; // set clock to low initial state
SPI_SI = 1;
SPIF = 1; //清SPIF标志
WCOL = 1; //清WCOL标志
}4.2 SPI发送字节
void SPI_WriteByte(u8 out)
{
SPDAT = out;
while(SPIF == 0) ;
SPIF = 1; //清SPIF标志
WCOL = 1; //清WCOL标志
}4.3 SPI读取字节:
u8 SPI_ReadByte(void)
{
SPDAT = 0xff;
while(SPIF == 0) ;
SPIF = 1; //清SPIF标志
WCOL = 1; //清WCOL标志
return (SPDAT);
}4.4 检测芯片是否存在:
void FlashCheckID(void)
{
SPI_CE_Low();
SPI_WriteByte(SFC_RDID); //发送读取ID命令
SPI_WriteByte(0x00); //空读3个字节
SPI_WriteByte(0x00);
SPI_WriteByte(0x00);
PM25LV040_ID1 = SPI_ReadByte(); //读取制造商ID1
PM25LV040_ID = SPI_ReadByte(); //读取设备ID
PM25LV040_ID2 = SPI_ReadByte(); //读取制造商ID2
SPI_CE_High();
// printf("ID1=0x%02x,ID=0x%02x,ID2=0x%02x\r\n",PM25LV040_ID1,PM25LV040_ID,PM25LV040_ID2);
if((PM25LV040_ID1 == 0x9d) && (PM25LV040_ID2 == 0x7f)) B_FlashOK = 1; //检测是否为PM25LVxx系列的Flash
else if(PM25LV040_ID == 0x12) B_FlashOK = 2; //检测是否为W25X4x系列的Flash
else if(PM25LV040_ID == 0x13) B_FlashOK = 3; //检测是否为W25X8x系列的Flash
else if(PM25LV040_ID == 0x17) B_FlashOK = 4; //检测是否为W25X128系列的Flash
else B_FlashOK = 0;
}4.5 读取N个字节
void SPI_Read_Nbytes(u32 addr, u8 *buffer, u16 size)
{
if(size == 0) return;
if(!B_FlashOK) return;
while(CheckFlashBusy() > 0); //Flash忙检测
SPI_CE_Low(); //enable device
SPI_WriteByte(SFC_READ); //read command
SPI_WriteByte(((u8 *)&addr)[1]); //设置起始地址
SPI_WriteByte(((u8 *)&addr)[2]);
SPI_WriteByte(((u8 *)&addr)[3]);
do{
*buffer = SPI_ReadByte(); //receive byte and store at buffer
buffer++;
}while(--size); //read until no_bytes is reached
SPI_CE_High(); //disable device
}4.6 写入多个字节
void SPI_Write_Nbytes(u32 addr, u8 *buffer, u8 size)
{
if(size == 0) return;
if(!B_FlashOK) return;
while(CheckFlashBusy() > 0); //Flash忙检测
FlashWriteEnable(); //使能Flash写命令
SPI_CE_Low(); // enable device
SPI_WriteByte(SFC_PAGEPROG); // 发送页编程命令
SPI_WriteByte(((u8 *)&addr)[1]); //设置起始地址
SPI_WriteByte(((u8 *)&addr)[2]);
SPI_WriteByte(((u8 *)&addr)[3]);
do{
SPI_WriteByte(*buffer++); //连续页内写
addr++;
if ((addr & 0xff) == 0) break;
}while(--size);
SPI_CE_High(); // disable device
}
我要赚赏金
