STM32CubeMX 下载和安装 详细教程
【HAL库】STM32CubeMX开发----STM32F407----目录
一、W25N04KV 简介
W25N04KV 是 NAND Flash系列的,具有高存储密度,并且写入和擦除的速度也很快。W25N04KV 内存为:4G(bit)/512M(byte)
特点
芯片封装和引脚分配
内存框图和寻址方式
W25N04KV 的寻址方式:页地址+列地址(Page Address + Column Address)
W25N04KV 整个 Flash 共有4096块(Block),每块包含64页(Page),每页大小为 2048(字节)。(一共4096x64x2048=512M)
寄存器
W25N04KV 提供三个寄存器,分别是:保护寄存器(SR1),配置寄存器(SR2) 和 状态寄存器(SR3)。
保护寄存器(SR1)
配置寄存器(SR2)
状态寄存器(SR3)
二、W25N04KV 程序实现命令
1. SPI 底层驱动读写程序
具体代码如下:
uint8_t SPI_ReadWriteByte(uint8_t TxData)
{
uint8_t Rxdata;
HAL_SPI_TransmitReceive(&hspi1,&TxData,&Rxdata,1, 1000);
return Rxdata;
}
2. 常用命令表
3. 读 W25N04KV 设备ID
读 W25N04KV 设备ID的命令如下:
具体程序如下:
uint32_t Flash_ReadID(void)
{
uint32_t ID = 0;
Flash_CS(0);
SPI_ReadWriteByte(0x9F);
SPI_ReadWriteByte(0x00);
ID|&#61;SPI_ReadWriteByte(0xFF)<<16;
ID|&#61;SPI_ReadWriteByte(0xFF)<<8;
ID|&#61;SPI_ReadWriteByte(0xFF);
Flash_CS(1);
return ID;
}
W25N04KV 设备ID 如下&#xff1a;
4. 写使能和写禁止
写使能
具体代码如下&#xff1a;
void Flash_Write_Enable(void)
{
Flash_CS(0);
SPI_ReadWriteByte(0x06);
Flash_CS(1);
}
写禁止
具体代码如下&#xff1a;
void Flash_Write_Disable(void)
{
Flash_CS(0);
SPI_ReadWriteByte(0x04);
Flash_CS(1);
}
5. 读写状态寄存器
读状态寄存器
具体代码如下&#xff1a;
uint8_t Flash_ReadSR1(void)
{
uint8_t SR &#61; 0;
Flash_CS(0);
SPI_ReadWriteByte(0x05);
SPI_ReadWriteByte(0xA0);
SR &#61; SPI_ReadWriteByte(0xFF);
Flash_CS(1);
return SR;
}
uint8_t Flash_ReadSR2(void)
{
uint8_t SR &#61; 0;
Flash_CS(0);
SPI_ReadWriteByte(0x05);
SPI_ReadWriteByte(0xB0);
SR &#61; SPI_ReadWriteByte(0xFF);
Flash_CS(1);
return SR;
}
uint8_t Flash_ReadSR3(void)
{
uint8_t SR &#61; 0;
Flash_CS(0);
SPI_ReadWriteByte(0x05);
SPI_ReadWriteByte(0xC0);
SR &#61; SPI_ReadWriteByte(0xFF);
Flash_CS(1);
return SR;
}
写状态寄存器
具体代码如下&#xff1a;
void Flash_WriteSR1(uint8_t Sdata)
{
Flash_CS(0);
SPI_ReadWriteByte(0x01);
SPI_ReadWriteByte(0xA0);
SPI_ReadWriteByte(Sdata);
Flash_CS(1);
}
void Flash_WriteSR2(uint8_t Sdata)
{
Flash_CS(0);
SPI_ReadWriteByte(0x01);
SPI_ReadWriteByte(0xB0);
SPI_ReadWriteByte(Sdata);
Flash_CS(1);
}
等待空闲
具体代码如下&#xff1a;
void Flash_Wait_Busy(void)
{
while((Flash_ReadSR3()&0x01)&#61;&#61;0x01);
}
6. 块擦除
在执行擦除命令前&#xff0c;需要先清除写保护&#xff0c;然后使能写入&#xff0c;方可擦除成功。
具体代码如下&#xff1a;
void Flash_Block_Erase(uint32_t BlockAddr)
{
Flash_WriteSR1(0x00);
Flash_Write_Enable();
Flash_CS(0);
SPI_ReadWriteByte(0xD8);
SPI_ReadWriteByte((uint8_t)((BlockAddr)>>16));
SPI_ReadWriteByte((uint8_t)((BlockAddr)>>8));
SPI_ReadWriteByte((uint8_t)BlockAddr);
Flash_CS(1);
Flash_Wait_Busy();
Flash_Write_Disable();
}
7. 读数据
W25N04KV 的读数据主要分两步&#xff1a;
&#xff08;1&#xff09;读Flash数据到缓存区&#xff0c;一次读一页&#xff0c;2k字节。
&#xff08;2&#xff09;读取缓存区的数据
具体代码如下&#xff1a;
void Flash_Read(uint8_t* pBuffer,uint32_t PageAddr,uint16_t ColumnAddr,uint16_t NumByteToRead)
{
Flash_CS(0);
SPI_ReadWriteByte(0x13);
SPI_ReadWriteByte((uint8_t)((PageAddr)>>16));
SPI_ReadWriteByte((uint8_t)((PageAddr)>>8));
SPI_ReadWriteByte((uint8_t)PageAddr);
Flash_CS(1);
delay_us(50);
Flash_CS(0);
SPI_ReadWriteByte(0x03);
SPI_ReadWriteByte((uint8_t)((ColumnAddr)>>8));
SPI_ReadWriteByte((uint8_t)ColumnAddr);
SPI_ReadWriteByte(0x00);
for(uint16_t i&#61;0;i<NumByteToRead;i&#43;&#43;)
{
pBuffer[i]&#61;SPI_ReadWriteByte(0xFF);
}
Flash_CS(1);
}
8. 写数据
在执行写命令前&#xff0c;需要先清除写保护&#xff0c;然后使能写入&#xff0c;方可写成功。
W25N04KV 的写数据主要分两步&#xff1a;
&#xff08;1&#xff09;先把数据写入缓存页
- 0x02 指令&#xff1a;先清除缓存区然后写入数据。
- 0x84 指令&#xff1a;不会清除缓存区的数据&#xff0c;直接写入数据。
&#xff08;2&#xff09;然后把缓存页中的数据写入Flash
具体代码如下&#xff1a;
void Flash_Write_Page(uint8_t* pBuffer,uint32_t PageAddr,uint16_t ColumnAddr,uint16_t NumByteToWrite)
{
Flash_WriteSR1(0x00);
Flash_Write_Enable();
Flash_CS(0);
SPI_ReadWriteByte(0x02);
SPI_ReadWriteByte((uint8_t)((ColumnAddr)>>8));
SPI_ReadWriteByte((uint8_t)ColumnAddr);
for(uint16_t i&#61;0;i<NumByteToWrite;i&#43;&#43;)
{
SPI_ReadWriteByte(pBuffer[i]);
}
Flash_CS(1);
delay_us(50);
Flash_CS(0);
SPI_ReadWriteByte(0x10);
SPI_ReadWriteByte((uint8_t)((PageAddr)>>16));
SPI_ReadWriteByte((uint8_t)((PageAddr)>>8));
SPI_ReadWriteByte((uint8_t)PageAddr);
Flash_CS(1);
Flash_Wait_Busy();
Flash_Write_Disable();
}