STM32F0-internes EEPROM-Lese- und Schreiblimit für eine Variable

Ich verwende die ST EEPROM-Emulationsbibliothek, um meine Variablen zu speichern. Ich möchte die Variable erhöhen, wenn ich die Taste drücke und im Eeprom speichern. Es funktioniert gut bis 256, aber nach 256 funktioniert der Mikrocontroller nicht mehr. Es scheint, dass es 256 Mal funktioniert und ich kann 256 Mal auf einer Seite schreiben, aber ich möchte mehr als das lesen und schreiben. Wo ist das Problem? Dies ist die .h-Bibliothek

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __EEPROM_H
#define __EEPROM_H

/* Includes ----------------------------------------------------------------- 
-*/ #include "stm32f0xx.h"

  /* Exported constants ----------------------------------------------------- 
 ---*/

 /* Base address of the Flash sectors */
 #define ADDR_FLASH_PAGE_0     ((uint32_t)0x08000800) /* Base @ of Page 0, 1 
 Kbytes *///0x08000000
 #define ADDR_FLASH_PAGE_1     ((uint32_t)0x08001000) /* Base @ of Page 1, 1 
 Kbytes *///0x08000400
 #define ADDR_FLASH_PAGE_2     ((uint32_t)0x08001800) /* Base @ of Page 2, 1 
 Kbytes *///0x08000800
 #define ADDR_FLASH_PAGE_3     ((uint32_t)0x08002000) /* Base @ of Page 3, 1 
 Kbytes *///0x08000C00
 #define ADDR_FLASH_PAGE_4     ((uint32_t)0x08002800) /* Base @ of Page 4, 1 
 Kbytes *///0x08001000
 #define ADDR_FLASH_PAGE_5     ((uint32_t)0x08003000) /* Base @ of Page 5, 1 
 Kbytes *///0x08001400
 #define ADDR_FLASH_PAGE_6     ((uint32_t)0x08003800) /* Base @ of Page 6, 1 
 Kbytes *///0x08001800
 #define ADDR_FLASH_PAGE_7     ((uint32_t)0x08004000) /* Base @ of Page 7, 1 
 Kbytes *///0x08001C00
 #define ADDR_FLASH_PAGE_8     ((uint32_t)0x08004800) /* Base @ of Page 8, 1 
 Kbytes *///0x08002000
 #define ADDR_FLASH_PAGE_9     ((uint32_t)0x08005000) /* Base @ of Page 9, 1 
 Kbytes *///0x08002400
 #define ADDR_FLASH_PAGE_10    ((uint32_t)0x08005800) /* Base @ of Page 10, 1 
 Kbytes *///0x08002800
 #define ADDR_FLASH_PAGE_11    ((uint32_t)0x08006000) /* Base @ of Page 11, 1 
 Kbytes *///0x08002C00
 #define ADDR_FLASH_PAGE_12    ((uint32_t)0x08006800) /* Base @ of Page 12, 1 
 Kbytes *///0x08003000
 #define ADDR_FLASH_PAGE_13    ((uint32_t)0x08007000) /* Base @ of Page 13, 1 
 Kbytes *///0x08003400
 #define ADDR_FLASH_PAGE_14    ((uint32_t)0x08007800) /* Base @ of Page 14, 1 
 Kbytes *///0x08003800
 #define ADDR_FLASH_PAGE_15    ((uint32_t)0x08008000) /* Base @ of Page 15, 1 
 Kbytes *///0x08003C00
 #define ADDR_FLASH_PAGE_16    ((uint32_t)0x08008800) /* Base @ of Page 16, 1 
 Kbytes *///0x08004000
 #define ADDR_FLASH_PAGE_17    ((uint32_t)0x08009000) /* Base @ of Page 17, 1 
 Kbytes *///0x08004400
 #define ADDR_FLASH_PAGE_18    ((uint32_t)0x08009800) /* Base @ of Page 18, 1 
 Kbytes *///0x08004800
 #define ADDR_FLASH_PAGE_19    ((uint32_t)0x0800A000) /* Base @ of Page 19, 1 
 Kbytes *///0x08004C00
 #define ADDR_FLASH_PAGE_20    ((uint32_t)0x0800A800) /* Base @ of Page 20, 1 
 Kbytes *///0x08005000
 #define ADDR_FLASH_PAGE_21    ((uint32_t)0x0800B000) /* Base @ of Page 21, 1 
 Kbytes *///0x08005400
 #define ADDR_FLASH_PAGE_22    ((uint32_t)0x0800B800) /* Base @ of Page 22, 1 

 /* Define the size of the sectors to be used */
 //#define PAGE_SIZE               (uint32_t)FLASH_PAGE_SIZE  /* Page size */
 #define PAGE_SIZE             ((uint32_t)0x0800)
 /* EEPROM start address in Flash */
 /* Change this if you need more EEPROM space and require less programming 
 space */
 #define EEPROM_START_ADDRESS  ((uint32_t)ADDR_FLASH_PAGE_30) /* EEPROM 
 emulation start address */

 /* Pages 0 and 1 base and end addresses */
  #define PAGE0_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
  #define PAGE0_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE 
  - 1)))

  #define PAGE1_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x400))
  #define PAGE1_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + PAGE_SIZE 
  - 1))

   /* Used Flash pages for EEPROM emulation */
   #define PAGE1                 ((uint16_t)1) /* Page nb between 
   PAGE0_BASE_ADDRESS & PAGE1_BASE_ADDRESS*/

     /* No valid page define */
   #define NO_VALID_PAGE         ((uint16_t)0x00AB)

    /* Page status definitions */
    #define ERASED                ((uint16_t)0xFFFF)     /* Page is empty */
    #define RECEIVE_DATA          ((uint16_t)0xEEEE)     /* Page is marked to 
    receive data */
    #define VALID_PAGE            ((uint16_t)0x0000)     /* Page containing 
    valid data */

    /* Valid pages in read and write defines */
    #define READ_FROM_VALID_PAGE  ((uint8_t)0x00)
    #define WRITE_IN_VALID_PAGE   ((uint8_t)0x01)

     /* Page full define */
     #define PAGE_FULL             ((uint8_t)0x80)

    /* Variables' number */
     #define NB_OF_VAR             ((uint8_t)0x04)

     /* Exported types ------------------------------------------------------------*/
     /* Exported macro ------------------------------------------------------------*/
     /* Exported functions ------------------------------------------------------- */
      uint16_t EE_Init(void);
      uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
      uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);


      #endif /* __EEPROM_H */

Ich schreibe zwei Funktionen für Lese- und Schreibspeicher.

FLASH_Unlock();

EE_Init();

EE_ReadVariable( ++i , &alarm_counter );

FLASH_Lock();   

Und

FLASH_Unlock(); 

EE_Init();


EE_WriteVariable( ++i , alarm_counter ); 

FLASH_Lock();   

Ich habe meinen Code so geändert:

uint16_t VirtAddVarTab[10] = {0,1,2,3,4,5,6,7,8,9};

 uint16_t VirtdataTab[10] = {0,0,0,0,0,0,0,0,0,0};

 uint16_t alarm_counter = 0; 
 
 ......

 FLASH_Unlock();

 EE_Init();

 EE_ReadVariable(VirtAddVarTab[0], &VirtdataTab[0]);

 alarm_counter = VirtdataTab[0] + 1;

 EE_WriteVariable( VirtAddVarTab[0] , alarm_counter ); 

 FLASH_Lock();  

Muss ich eine Adresse wie 0x0100 verwenden oder ist es richtig, diese in meinem Code zu verwenden?

Ist 0x0100 diese Adresse in der .h-Datei? #define ADDR_FLASH_PAGE_0 ((uint32_t)0x08000800)

Ich habe diese Bibliothek nie benutzt, aber ich habe ihre Dokumentation gelesen. Normalerweise sollte es zu einer anderen Seite wechseln und die alte löschen. Aufgrund des Seitenmigrationsprozesses kann es zu kurzen Verzögerungen kommen, aber es sollte kontinuierliche Schreibvorgänge nach der Migration ermöglichen. Vielleicht hast du Fehler in deiner Konfiguration. Bitte teilen Sie Ihren Code mit.
@Tagli: Ich habe den Beitrag aktualisiert und den Code eingefügt
In Ihrem neuen Code verstehe ich den Zweck von VirtdataTab. Wofür ist das? Warum ein Array?

Antworten (3)

Ich sehe so aus, als hätten Sie die EEPROM-API missverstanden (wahrscheinlich aufgrund ihrer schlechten Dokumentation). Ihr Code ändert den Schlüssel anstelle des Werts und sobald die Seite voll ist, werden die korrekten Werte nicht auf die neue Seite migriert, da er nur für einen festen Satz von Schlüsseln funktioniert.

Angenommen, alarm_counter ist tatsächlich der Wert, den Sie erhöhen möchten, wenn die Schaltfläche gedrückt wird, sollte Ihr Code so aussehen:

#define NB_OF_VAR 1

...

#define EE_KEY_ALARM_COUNTER 0x0100

uint16_t VirtAddVarTab[NB_OF_VAR] = { EE_KEY_ALARM_COUNTER };

uint16_t alarm_counter;

...

FLASH_Unlock();
EE_Init();
EE_ReadVariable(EE_KEY_ALARM_COUNTER, &alarm_counter);

alarm_counter++;

EE_WriteVariable(EE_KEY_ALARM_COUNTER, alarm_counter); 
FLASH_Lock();
Ich füge meinen modifizierten Code unten hinzu. Aber ich kann nur 256 Mal schreiben
In Ihrem neuen Code verstehe ich den Zweck von VirtdataTab. Wofür ist das? Warum ein Array? Beachten Sie, dass NB_OF_VAR und VirtAddVarTabnicht nur zufällige Namen sind. Sie müssen so deklariert werden, damit die EEPROM-Emulationsbibliothek funktioniert.

Ich möchte die Variable erhöhen, wenn ich die Taste drücke und im Eeprom speichern.

Sie erhöhen die Adresse (i), sodass Sie den Wert von alarm_counter über eine ganze Flash-Seite schreiben.

Wie kann ich es reparieren? Wie viele Variablen kann ich auf einer Seite speichern?
Hören Sie auf, i zu erhöhen, und erhöhen Sie stattdessen vielleicht alarm_counter?
EE_WriteVariable( i , alarm_counter++ ); so was?

Ich habe das Problem gefunden. Es gibt eine Definition in der Datei eeprom.h für die Seitengröße. Es war:

#define PAGE_SIZE ((uint32_t)0x0800)

Ich habe es geändert zu:

#define PAGE_SIZE             0x400U

Und alles funktioniert ohne Probleme