久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1938|回復: 13
收起左側

C語言算法求助,關于保留最新的N次數據

[復制鏈接]
回帖獎勵 30 黑幣 回復本帖可獲得 3 黑幣獎勵! 每人限 1 次
ID:1104941 發表于 2024-6-17 16:40 | 顯示全部樓層 |閱讀模式
使用場景:需要在外接FLASH存儲最新的10次數據,每次存儲的數據有點大(4Kbyte),按照更新的時間排序,次數越小,時間越新。
比如,昨天存完10次后,今天又需要存一次數據了,昨天的次數10舍棄,全部次數往后挪一個單位,今天的次數存在次數1位置。

我能想到的是使用鏈表,但是搞單片機好久沒碰過鏈表方面的知識了,還有其它方法嗎?
回復

使用道具 舉報

ID:1104941 發表于 2024-6-17 16:45 | 顯示全部樓層
之前簡單的排序可以在數組實現,但是這個邏輯感覺不適合在FLASH中操作,因為又要讀,擦寫,既花時間,又要一直擦除會影響壽命。
回復

使用道具 舉報

ID:1080935 發表于 2024-6-18 08:25 | 顯示全部樓層
鏈表和索引表都可以,隊列也可以,控制頭尾,不在頭尾的都是空閑空間。
回復

使用道具 舉報

ID:401564 發表于 2024-6-18 09:40 | 顯示全部樓層
增加一個斷電檢測或者寫入動作,如果沒有斷電,最新的數據是保留在單片機上的,不用寫入FLASH
把寫入FLASH地址的記錄單獨放到一個頁面,每次寫入的時候,把已經寫入的地址寫到這個頁面中
數據存放在其它的頁面,頁面是循環使用的,比如先寫1頁面,然后是2頁面
這樣的話,每次寫入就只要擦寫地址頁面就可以了
FLASH不是普通存儲器,一個地址只能寫入一次,你想再寫入第二次就擦寫整個頁面了
回復

使用道具 舉報

ID:277550 發表于 2024-6-18 10:08 | 顯示全部樓層
使用這樣的方法
固定的第1個位置是保存索引,每次保存完索引+1到第10、復位。表示一下個該寫入的索引。
固定的第2個位置是保存是開始索引。表示從該索引開始讀、到第10回0、讀夠10個。
后面是數據。
這樣讀寫最少。
回復

使用道具 舉報

ID:1104941 發表于 2024-6-18 18:14 | 顯示全部樓層
devcang 發表于 2024-6-18 10:08
使用這樣的方法
固定的第1個位置是保存索引,每次保存完索引+1到第10、復位。表示一下個該寫入的索引。
...

好的,我也有這個思路,在索引里面更改FLASH的地址偏移,指向不同地址,好像指針啊
回復

使用道具 舉報

ID:1104941 發表于 2024-6-18 18:21 | 顯示全部樓層
Y_G_G 發表于 2024-6-18 09:40
增加一個斷電檢測或者寫入動作,如果沒有斷電,最新的數據是保留在單片機上的,不用寫入FLASH
把寫入FLASH地 ...

謝謝,我打算做個外部超級電容了,掉電檢測再保存FLASH,平時保存RAM。目前是舊數據的刪除和新數據的插入有點想不通,還有就是加了電容,上電緩慢又怕出問題,感覺要加復位芯片啊
回復

使用道具 舉報

ID:1104941 發表于 2024-6-18 18:23 | 顯示全部樓層
LaoYuTou 發表于 2024-6-18 08:25
鏈表和索引表都可以,隊列也可以,控制頭尾,不在頭尾的都是空閑空間。

目前計劃是打算使用索引表,索引保存FLASH的偏移地址,每次刪除或者增加數據,舊偏移索引里面的地址,這樣可以實現吧
回復

使用道具 舉報

ID:1080935 發表于 2024-6-19 08:41 | 顯示全部樓層
是的,但是flash是按扇區操作的,一次寫一個扇區,而且讀寫不快,影響壽命,不建議頻繁讀寫。
回復

使用道具 舉報

ID:1125920 發表于 2024-6-19 12:07 | 顯示全部樓層
對于在外接FLASH上存儲最新的10次數據,可以采用循環緩沖區(環形隊列)的方式,這種方法比鏈表更加簡單高效,非常適合在單片機上使用。下面是實現這一方案的步驟:  ### 1. 設計存儲結構 假設每次數據的大小為4Kbyte,需要存儲10次數據,因此需要的存儲空間為40Kbyte。  ### 2. 初始化環形緩沖區 環形緩沖區的概念是使用一個固定大小的數組,通過一個指針來跟蹤最新的數據位置,并循環使用數組空間。  ### 3. 寫入數據 每次寫入新的數據時,將指針移動到下一個位置。如果指針超出數組范圍,則回到數組的起點。  ### 4. 讀取數據 讀取數據時,根據指針和偏移量來獲取最新的數據。  ### 具體實現 下面是一個示例代碼,假設使用C語言來實現這一功能:  ```c #define DATA_SIZE 4096       // 每次數據大小為4Kbyte #define BUFFER_SIZE 10       // 環形緩沖區大小為10 #define FLASH_START_ADDRESS 0x00000000  // 外接FLASH起始地址,根據具體情況修改  // 環形緩沖區的當前索引 unsigned int currentIndex = 0;  // 寫入數據到FLASH的函數 void writeDataToFlash(unsigned int index, const char* data) {     unsigned int address = FLASH_START_ADDRESS + (index * DATA_SIZE);     // 寫入數據到指定地址,具體的FLASH寫入函數根據芯片手冊實現     Flash_Write(address, data, DATA_SIZE); }  // 讀取FLASH中的數據到內存 void readDataFromFlash(unsigned int index, char* data) {     unsigned int address = FLASH_START_ADDRESS + (index * DATA_SIZE);     // 從指定地址讀取數據,具體的FLASH讀取函數根據芯片手冊實現     Flash_Read(address, data, DATA_SIZE); }  // 存儲新數據 void storeNewData(const char* newData) {     // 寫入新數據到當前索引位置     writeDataToFlash(currentIndex, newData);          // 更新索引,循環使用緩沖區     currentIndex = (currentIndex + 1) % BUFFER_SIZE; }  // 獲取最新的n次數據,n從1到10 void getLatestData(unsigned int n, char* data) {     if (n == 0 || n > BUFFER_SIZE) {         return; // 無效參數     }          int index = (currentIndex + BUFFER_SIZE - n) % BUFFER_SIZE;     readDataFromFlash(index, data); }  void Flash_Write(unsigned int address, const char* data, unsigned int size) {     // 具體的FLASH寫入實現 }  void Flash_Read(unsigned int address, char* data, unsigned int size) {     // 具體的FLASH讀取實現 } ```  ### 代碼解釋 - `currentIndex`:記錄當前最新數據在緩沖區中的位置。 - `writeDataToFlash`:將數據寫入FLASH的指定位置。 - `readDataFromFlash`:從FLASH的指定位置讀取數據。 - `storeNewData`:存儲新數據到環形緩沖區,并更新索引。 - `getLatestData`:獲取最新的n次數據。  這種方法避免了復雜的鏈表操作,使用一個固定大小的數組來存儲數據,通過簡單的索引操作實現數據的循環存儲和讀取,適合單片機環境下的使用。
回復

使用道具 舉報

ID:401564 發表于 2024-6-19 12:41 | 顯示全部樓層
bstljq 發表于 2024-6-18 18:21
謝謝,我打算做個外部超級電容了,掉電檢測再保存FLASH,平時保存RAM。目前是舊數據的刪除和新數據的插入 ...

單片機本身工作電流并不大,超級電容可以串聯一個100歐的電阻或者是另外加一個LDO給超級電容充電
充電的電壓不要超過超級電容的耐壓
回復

使用道具 舉報

ID:688692 發表于 2024-6-19 19:31 | 顯示全部樓層
每次存儲扇區往后移動,用到最后一個扇區再擦除前面的扇區,可以節約FLASH壽命。循環滾動,只要記得上次是從哪里存起的就行了。
回復

使用道具 舉報

ID:384109 發表于 2024-6-19 21:05 | 顯示全部樓層
應該不是數據存儲區的操作問題吧,單獨加個EEPROM用來存儲指針或鏈表什么的都可以
回復

使用道具 舉報

ID:1126074 發表于 2024-6-23 22:51 | 顯示全部樓層
在單片機環境下,由于資源有限,使用鏈表可能不是最理想的解決方案,因為它需要額外的內存空間來存儲節點?紤]到數據量較大(4Kbyte)且需要頻繁操作,可以考慮以下幾種方法:  1.  **循環數組(Circular Buffer)**:          *   使用一個固定大小的數組(例如,10個元素,每個元素4Kbyte),數組的最后一個元素和第一個元素相連,形成循環。     *   當新的數據到來時,替換數組的第一個元素(次數為1),然后更新次數(例如,使用一個寄存器記錄當前次數)。     *   當需要訪問數據時,根據次數索引到數組的相應位置。 2.  **堆棧(Stack)**:          *   如果單片機支持堆棧操作,可以使用堆棧來存儲數據和次數。每次新數據到來,將數據壓入堆棧,同時更新堆棧頂部的次數(如果堆棧已滿,可能需要先彈出最舊的數據)。     *   訪問數據時,從堆棧頂部獲取。 3.  **帶計數的順序存儲**:          *   如果內存空間允許,可以將數據和次數連續存儲,每個數據塊后面緊跟著一個表示次數的字節。當新數據到來時,直接插入到數據末尾,次數加1。需要訪問時,根據次數找到對應的數據。 4.  **文件系統(如SD卡)**:          *   如果你的應用支持外部存儲,可以使用文件系統(如FatFS或YottaDB)將數據存儲為文件,每個文件代表一次數據,文件名或文件屬性可以包含次數信息。每次新數據寫入一個新文件,舊文件保持,次數遞增。  在選擇方法時,要考慮單片機的內存限制、操作速度和數據持久性等因素。循環數組和順序存儲通常更適用于資源有限的情況,而堆棧和文件系統則需要更高級的硬件支持。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久一| 黄色毛片一级 | 夜夜草天天草 | 精精国产xxxx视频在线播放 | 中文字幕免费 | 成人在线免费视频 | 在线国产欧美 | 免费污视频 | 夜夜操操操 | 97国产精品 | 午夜a区 | 免费观看av网站 | 亚洲国产精品区 | 亚洲一区 | 成人免费视频观看视频 | 九九久久久 | 精品av | 一区免费观看 | 超碰国产在线 | 超碰人人艹 | xxxxx免费视频| aaaa网站 | 欧美视频一区二区三区 | 久久久久久久久蜜桃 | 成人免费观看男女羞羞视频 | 综合欧美亚洲 | 国产一区二区在线免费观看 | 日韩久久综合网 | 四虎影院久久 | 羞羞的视频在线看 | 一级毛片视频在线 | 91视频大全| 亚洲一区二区三区视频免费观看 | 国产精品久久 | 日本色高清 | 久热爱 | 成人综合一区二区 | 99国产精品99久久久久久粉嫩 | 欧美精品一区二区三区蜜臀 | 成人一级片在线观看 | 天天草天天|