W25Q32JV是华邦推出的一款spi flash,32J表示32M-bit,相当于4M
关于型号命名如下
对于W25Q32JV:
page为最大编程单位,1page = 256bytes
sector为最小擦除单位,1sector = 16pages = 4KB = 4096bytes
还支持半块擦除(32KB block erase)、块擦除(64KB block erase)和整片擦除(chip erase)
PIN描述
- Chip Select(/CS):芯片使能和禁用引脚,当/CS为高时,禁用设备,串行数据输出(DO, IO0, IO1, IO2, IO3)引脚处于高阻抗状态,除非进行内部擦除,程序或写状态寄存器循环,否则设备处于待机状态,当/CS为低时,将使能设备,可以向设备写入指令并从设备读取数据。
- Serial Data Input, Output and IOs(DI, DO and IO0, IO1, IO2,IO3):串行数据输入,输出和IOs,支持standard SPI,DualSPI和QuadSPI操作,标准SPI,使用DI引脚写入指令、地址或数据,使用DO引脚读取数据或状态。当QE =1时,/WP引脚变为IO2,/HOLD引脚变为IO3。
- Write Protect(/WP):写保护引脚,用于防止状态寄存器被写入。与状态寄存器的块保护位和状态寄存器保护位一起使用。
- HOLD(/HOLD):当设备处于活动状态时,/HOLD引脚允许设备暂停。当/HOLE为低,/CS为低时,DO引脚出去高阻抗,此时,DI和CLK引脚上的信号将被忽略。当多个设备共享形同的SPI时,/HOLD引脚非常有用。
- Serial Clock(CLK):为串行输入和输出操作提供同步时钟。
状态和配置寄存器
W25Q32JV提供了三个状态和配置寄存器。
- Erase/Write in Progress(BUSY) - 只读,当设备执行页编程,四页编程,扇区擦除,块擦除,整擦除,写状态寄存器或删除/程序安全寄存器指令时,此位置为1,在此期间,除读取状态寄存器和擦除暂停指令外,将忽略其他指令。当操作完成后,busy位将被清为0,表示设备准备好接受下一步指令。
- Write Enable Latch(WEL) - 只读,状态寄存器(S1)中的一个只读位,在执行写使能指令后,被置为1,当写入被禁用时,WEL位被清为0。“写禁用”,“页编程”,“四页编程”,“扇区擦除”,“块擦除”,“整片擦除”,“写状态寄存器”,“擦除安全寄存器”和“程序安全寄存器”这些指令完成后,自动回到写禁用状态。
- Block Protect Bits(BP2, BP1, BP0) - 块保护位,是状态寄存器中提供写保护控制和状态的非易失读/写位,可以通过写状态寄存器指令来设置。
- Status Register Protect(SRP, SRL),这两个位 与 WP 引脚一起, 用于控制对状态寄存器的写
写操作
- 发送写使能指令(06h),
- 发送页编程指令(02h),如果要对整个256字节的页面进行编程,最后一个地址字节应该设置为0,可以对少于256字节进行编程,而不会对同一页的其他字节产生影响。如果发送到设备的字节数超过256,则将自动切换行道页面的开头并覆盖之间的数据。
void FLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
/*Set /CS bit low*/
GPIO_ResetBits(FLASH_CS_GPIO_PORT, FLASH_CS_PIN);
/*Send write enable*/
FLASH_SendByte(0x06);
/*Set /CS bit high */
GPIO_SetBits(FLASH_CS_GPIO_PORT, FLASH_CS_PIN);
/*Select the FLASH: Chip Select low */
GPIO_ResetBits(FLASH_CS_GPIO_PORT, sFLASH_CS_PIN)
/*Send page program*/
FLASH_SendByte(0x02);
/*Send WriteAddr high nibble address byte to write to */
FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
/*Send WriteAddr medium nibble address byte to write to */
FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
/*Send WriteAddr low nibble address byte to write to */
FLASH_SendByte(WriteAddr & 0xFF);
/*while there is data to be written on the FLASH */
while (NumByteToWrite--)
{
/*Send the current byte */
FLASH_SendByte(*pBuffer);
/*Point on the next byte to be written */
pBuffer++;
}
/*Deselect the FLASH: Chip Select high */
GPIO_SetBits(FLASH_CS_GPIO_PORT, FLASH_CS_PIN);
/*Wait the end of Flash writing */
FLASH_WaitForWriteEnd();
}
读操作
- 发送读数据指令(03h)。
void FLASH_ReadPage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
/*Set /CS bit low*/
GPIO_ResetBits(FLASH_CS_GPIO_PORT, FLASH_CS_PIN)
/*!Send read data */
FLASH_SendByte(0x03);
/*Send ReadAddr high nibble address byte to read from */
FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
/*Send ReadAddr medium nibble address byte to read from */
FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
/*Send ReadAddr low nibble address byte to read from */
FLASH_SendByte(ReadAddr & 0xFF);
/*! Read data */
while (NumByteToRead--)
{
/*Read a byte from the FLASH */
*pBuffer = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
/*Point to the next location where the byte read will be saved */
pBuffer++;
}
/*Set /CS bit high */
GPIO_SetBits(sFLASH_CS_GPIO_PORT, sFLASH_CS_PIN)
}
擦除操作
- 发送写使能指令(06h),
- 发送扇区擦除指令(20h)。
void FLASH_EraseSector(uint32_t SectorAddr)
{
/*Set /CS bit low*/
GPIO_ResetBits(FLASH_CS_GPIO_PORT, FLASH_CS_PIN);
/*Send write enable*/
FLASH_SendByte(0x06);
/*Set /CS bit high */
GPIO_SetBits(FLASH_CS_GPIO_PORT, FLASH_CS_PIN);
/*Select the FLASH: Chip Select low */
GPIO_ResetBits(FLASH_CS_GPIO_PORT, sFLASH_CS_PIN)
/*Send Sector Erase instruction */
FLASH_SendByte(0x20);
/*Send SectorAddr high nibble address byte */
FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
/*Send SectorAddr medium nibble address byte */
FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
/*Send SectorAddr low nibble address byte */
FLASH_SendByte(SectorAddr & 0xFF);
/*Deselect the FLASH: Chip Select high */
GPIO_SetBits(FLASH_CS_GPIO_PORT, FLASH_CS_PIN);
/*Wait the end of Flash writing */
FLASH_WaitForWriteEnd();
}
注:
Flash在写数据之前,先进行Erase操作,其实Erase操作就是往Flash中写FF,最小Erase单位为Sector,也支持32KB Block Erase(52h),64KB Block Erase(D8h)和Chip Erase(C7h/60h)。
如有不足,还望大家指正,互相学习,谢谢!