STM32F407-SPI-flash存储-02
本节主要实现FLASH的擦除、读、写操作;
flash在擦除和写操作时都需要进行 write enable;
在擦除和写结束后,需要等待flash状态;非busy时,才能再进行操作
/*SPI 指令*/
#define FLASH_ORDER_ReleasePowerDown 0xAB
#define FLASH_ORDER_WriteEnable 0x06
#define FLASH_ORDER_Sector_Erase 0x20
#define FLASH_ORDER_Read_States_Register 0x05
#define FLASH_ORDER_ReadData 0x03
#define FLASH_ORDER_Page_Program 0x02
#define DUMMY 0xFF
擦除一个flash扇区
//擦除输入的扇区
void My_FLASH_Erase_Sector(uint32_t addr)
{
SPI_FLASH_Write_Enable(); //写使能
FLASH_SPI_CS_LOW();
SPI_FLASH_ByteWrite(FLASH_ORDER_Sector_Erase);
SPI_FLASH_ByteWrite((addr >> 16) & 0xFF);
SPI_FLASH_ByteWrite((addr >> 8) & 0xFF);
SPI_FLASH_ByteWrite(addr & 0xFF);
FLASH_SPI_CS_HIGH();
SPI_FLASH_Wait_For_Standby(); //等待内部时序完成
}
static void SPI_FLASH_Write_Enable(void)
{
FLASH_SPI_CS_LOW();
SPI_FLASH_ByteWrite(FLASH_ORDER_WriteEnable); //写使能指令
FLASH_SPI_CS_HIGH();
}
static void SPI_FLASH_Wait_For_Standby(void)
{
uint8_t status = 0u;
uint16_t SPITimeout = SPIT_FLAG_TIMEOUT;
//控制片选引脚
FLASH_SPI_CS_LOW();
//指令代码
SPI_FLASH_ByteWrite(FLASH_ORDER_Read_States_Register); //获取寄存器状态
while(1)
{
status = SPI_FLASH_ByteWrite(DUMMY); //一直发送数据,则flash一直返回 read_states_register 寄存器状态
//如果条件成立,说明为空闲状态
if((status & 0x01) == 0u) //最后一位表示是否busy
break;
//若SPITimeout为0,表示已检测SPITimeout次都仍为busy,跳出循环
if((SPITimeout--) == 0u)
{
SPI_TIMEOUT_UserCallback(3);
break;
}
}
FLASH_SPI_CS_HIGH();
}
从flash中读取数据
//读取输入的地址数据
void My_FLASH_Read_Buff(uint32_t addr, uint8_t *buf, uint32_t size)
{
//控制片选引脚
FLASH_SPI_CS_LOW();
//指令代码
SPI_FLASH_ByteWrite(FLASH_ORDER_ReadData);
//发送要读取的地址
SPI_FLASH_ByteWrite((addr>>16) & 0xFF);
SPI_FLASH_ByteWrite((addr>>8) & 0xFF);
SPI_FLASH_ByteWrite(addr & 0xFF);
while(size--)
{
*buf = SPI_FLASH_ByteWrite(DUMMY);
buf++;
}
FLASH_SPI_CS_HIGH();
}
向flash中写入数据
//写入数据
void My_FLASH_Write_Buff(uint32_t addr, uint8_t *buf, uint32_t size)
{
uint32_t count=0;
while(size--)
{
count++;
//第一次执行,addr对齐到4096时;地址对齐到256时
if( count == 1 || (addr % 4096)==0 || (addr % 256)==0)
{
//结束上一次的页写入指令
FLASH_SPI_CS_HIGH();
//等待上一次页写入的完成
SPI_FLASH_Wait_For_Standby();
//写使能
SPI_FLASH_Write_Enable();
//控制片选引脚
FLASH_SPI_CS_LOW();
//指令代码
SPI_FLASH_ByteWrite(FLASH_ORDER_Page_Program);
//发送要写入的地址
SPI_FLASH_ByteWrite((addr>>16) & 0xFF);
SPI_FLASH_ByteWrite((addr>>8) & 0xFF);
SPI_FLASH_ByteWrite(addr & 0xFF);
}
SPI_FLASH_ByteWrite(*buf);
buf++;
addr++;
}
FLASH_SPI_CS_HIGH();
//等待内部时序完成
SPI_FLASH_Wait_For_Standby();
}