從芯片手冊中可以得到w25q128單個扇區的寫入次數約為10萬次。項目中有些數據需要經常的進行讀寫,如果這些數據只是寫在一個扇區,那么到達10W次后,可能就會面臨使用扇區損壞的風險,我的解決方案就是更換數據的存儲位置。
我這次的代碼是基於自己項目寫的,只有參考價值,不一定符合你的使用要求。
我的需求:
在機器工作過程中,每次動作都會記錄一次數據到flash芯片,然后將當前數據的最高地址寫入到特定的某個ADDR,供次寫入時,讀取出來,作為這條數據的起始地址。
這個位置的需要經常的讀寫,容易損壞,如果損壞了,那么以后歷史數據都無法正常寫入了。
解決方案:使用若干個相鄰的扇區,數據存儲到達一定的條數后,更換扇區繼續,開機后先判斷數據歷史數據位置的ADDR在哪個扇區。
判斷條數:(最高位地址-起始地址)/每條數據的位數=條數
u32 addr_highest=0x010000; //寫入歷史數據最高位的地址的位置
u32 StartAddrToWrite_init(u32 addr_to_read) //這里將addr_highest傳入 { u8 i = 0; u8 sector=1; u32 addr; u32 start_addr; u8 tmp_buffer[4]={0}; for(sector=1;sector<4;sector++) //從第一個扇區開始,讀取每個扇區 { W25QXX_Read(tmp_buffer, addr_to_read, sizeof(tmp_buffer)); //讀取addr_to_read這個位置存的值,如果從來沒寫入過,是FFFFFFFF,寫入過就是這個扇區保存的的最高地址 addr=((tmp_buffer[0]<<24)&0xFF000000)+((tmp_buffer[1]<<16)&0x00FF0000) +((tmp_buffer[2]<<8)&0x0000FF00)+(tmp_buffer[3]&0x000000FF); if(addr==0XFFFFFFFF) //沒寫過 { if(sector==1) //第一次 { start_addr=BASEADDRESS; //歷史數據寫入開始地址是自己設置的BASEADDRESS } else { start_addr=ReadStartAddrToWrite(addr_to_read-0x001000); //讀取上個扇區保存的地址的值,每個扇區相差0x001000位 } UpdateHighestDataAddr(start_addr,addr_to_read); //賦值給后一個扇區 break; } else //如果寫過了 { addr = ReadStartAddrToWrite(addr_to_read); //讀取最高位地址 if((addr-BASEADDRESS)/(32*10)>=sector) //判斷條數(一條32個字節),測試是使用10條,大於本扇區設定能存的最大條數 { addr_to_read+=0x001000; //換到下個扇區繼續讀取,判斷 } else //沒有超過本扇區最大能存的條數,繼續在本扇區使用,跳出for()循環 { addr_to_read=addr_to_read; break; } } } return (addr_to_read); }
大概的思路就是這樣,如果你直接復制,因為里面嵌套了別的函數,那肯定不能用的了。
