之前用的eeprom做一些数据的临时存储,新产品上数据存储变多变长就用了flash,但是flash擦写次数短,有些参数需要经常更新,看论坛里有人提到了在一个扇区里循环存的方法,觉得可行,就在程序上试了下,测试通过,把代码贴出来大家相互学习,同时也希望多多指点void W25Q64_Dev_Par_Write()
{
u8 temp[4];
u32 used_bit;
u32 shift_addr=0;
u8 i;
SPI1_Flash_WAKEUP();
SPI1_FLASH_WriteEnable();
SPI1_FLASH_BufferRead(temp,Dev_Par_Shift_Addr,4);//读出当前偏移信息
used_bit = (u32)(temp[0]<<24| temp[1]<<16|temp[2]<<8|temp[3]);
printf("used_bit:%x,%x,%x,%x,%x\r\n",used_bit,temp[0],temp[1],temp[2],temp[3]);
for(i=0;i<32;i++)//查找已经更新到的bit
{
if((used_bit & (0x80000000>>i)) != 0)//找到待写入的区域索引:i (!=的优先级大于&的优先级)
{
printf("\r\ni:%d,结果:%x",i,used_bit & (0x80000000>>i));
break;
}
}
if(i==32)//所有bit都已经被使用完,初始化后从头写入
{
i = 0;
used_bit = 0xffffffff;
SPI1_Flash_WAKEUP();
SPI1_FLASH_WriteEnable();
//擦除当前扇区
printf("\r\n擦写之前SPI状态寄存器值:%d\r\n",SPI1_FLASH_ReadDeviceSTATU());
SPI1_FLASH_SectorErase(Dev_Unusual_Pwr_Down_Addr);//对新扇区进行擦除
SPI1_FLASH_WriteEnable();
printf("\r\n擦写之后SPI状态寄存器值:%d\r\n",SPI1_FLASH_ReadDeviceSTATU());
}
used_bit = used_bit & (~(0x80000000>>i));//更新已经使用的bit
temp[0] = used_bit>>24;
temp[1] = used_bit>>16;
temp[2] = used_bit>>8;
temp[3] = used_bit;
shift_addr = i*W25Q64_Dev_Par_LEN;//根据待写入的区域索引(i)算出偏移地址
printf("本次flash偏移地址:%d,used_bit:0x%x\r\n",shift_addr,used_bit);
SPI1_Flash_WAKEUP();
SPI1_FLASH_WriteEnable();
SPI1_FLASH_BufferWrite(temp,Dev_Par_Shift_Addr,4);//在flash中更新已使用的bit
SPI1_FLASH_BufferWrite(&Dev_Unusual_Pwr_Down_Flag,shift_addr+Dev_Unusual_Pwr_Down_Addr,1);//异常关机
SPI1_FLASH_BufWrite_4(Storge_Cnt_Index,shift_addr+Storge_Cnt_Index_Addr);//离线数据索引
SPI1_FLASH_BufWrite_4(Sent_Data_Num,shift_addr+Sent_Data_Num_Addr);//已发送数据索引
SPI1_FLASH_BufWrite_4(Data_Record_Num,shift_addr+Data_Record_Num_Addr);//记录数据条数
SPI1_FLASH_BufWrite_4(Data_Record_Index,shift_addr+Data_Record_Index_Addr);//记录数据索引
SPI1_FLASH_BufferWrite(&Record_Overflow_Flag,shift_addr+Record_Overflow_Flag_Addr,1);//记录数据是否溢出
SPI1_Flash_PowerDown();
}
|