The STM32L series MCU provides an EEPROM storage area, but in fact, its FLASH is also an EEPROM type, but there is an area that is opened up for EEPROM operation. The STM32L EEPROM service life is designed to be more than 100,000 erase and write times, and the capacity is 2K-4K, which is ideal for parameter storage of general equipment. However, from the perspective of EEPROM usage, it is not suitable for data storage that is repeatedly modified. Generally, as a configuration parameter, the number of modifications is often relatively small.
The EEPROM and FLASH of STM32L are uniformly addressed and share the same read-write circuit. Therefore, when reading and writing EEPROM, all access and operations of STM32L core to FLASH will be suspended. Only when the operation of EEPROM is completed, the subsequent code will continue to be executed. During this period, only the read-write circuit of EEPROM works and the CPU is in a suspended state.
Read operation, like FLASH and memory, EEPROM data can be read directly using the bus read cycle, without the need for additional operations and settings.
#define EEPROM_BASE_ADDR 0x08080000
#define EEPROM_BYTE_SIZE 0x0FFF
The above defines the starting position and size of the EEPROM area. After the offset is given, it can be read out in byte/halfword/word/doubleword mode. However, it should be noted that the offset address is preferably aligned to four bytes to avoid bus access errors or incorrect access:
/*------------------------------------------------------------
Func: EEPROM data is read out byte by byte
Note:
-------------------------------------------------------------*/
void EEPROM_ReadBytes(uint16 Addr,uint8 *Buffer,uint16 Length)
{
uint8 *wAddr;
wAddr=(uint8 *)(EEPROM_BASE_ADDR+Addr);
while(Length--){
*Buffer++=*wAddr++;
}
}
/*------------------------------------------------------------
Func: EEPROM data read
Note:
-------------------------------------------------------------*/
void EEPROM_ReadWords(uint16 Addr,uint16 *Buffer,uint16 Length)
{
uint32 *wAddr;
wAddr=(uint32 *)(EEPROM_BASE_ADDR+Addr);
while(Length--){
*Buffer++=*wAddr++;
}
}
The above method uses byte and word mode to read out. In the latter method, only 16 bits are used in the storage space of a word, and the other 16 bits are not used to avoid alignment problems.
Programming EEPROM is much more complicated than reading. In essence, the erase operation is the same as the write operation. Erasing is just writing 0x00000000 in the corresponding place. However, in the implementation of STM32L, according to its manual, it seems that this erase and write are distinguished. When writing 0x00 or 0x0000 or 0x00000000, an erase operation is automatically performed. When the value is non-0, a so-called write operation is performed. The data writing process must first unlock the EEPROM, which is achieved by writing a special sequence to a special register, and then perform an erase operation before writing. The erase is performed by word/double word/page. It is recommended to use the page erase method. First read the parameters into the memory, modify them, then perform page erase, and finally write the parameters back. This method is more common, otherwise it is easy to cause address alignment or length problems. After the data is erased, it can be written. Each time a byte/half word/double word is written, it is necessary to determine whether it is written. This is related to the internal high-voltage erase circuit. It is meaningful to perform other operations only after the last operation is completed. Finally, the EEPROM is locked to protect the data.
The following is the unlock command code given in the manual:
#define PEKEY1 0x89ABCDEF //FLASH_PEKEYR
#define PEKEY2 0x02030405 //FLASH_PEKEYR
The following implements writing in byte and word mode respectively:
/*------------------------------------------------------------
Func: EEPROM data is written byte by byte
Note:
-------------------------------------------------------------*/
void EEPROM_WriteBytes(uint16 Addr,uint8 *Buffer,uint16 Length)
{
uint8 *wAddr;
wAddr=(uint8 *)(EEPROM_BASE_ADDR+Addr);
DIS_INT
FLASH->PEKEYR=PEKEY1; //unlock
FLASH->PEKEYR=PEKEY2;
while(FLASH->PECR&FLASH_PECR_PELOCK);
FLASH->PECR|=FLASH_PECR_FTDW; //not fast write
while(Length--){
*wAddr++=*Buffer++;
while(FLASH->SR&FLASH_SR_BSY);
}
FLASH->PECR|=FLASH_PECR_PELOCK;
IN_INT
}
/*------------------------------------------------------------
Func: EEPROM data is written word by word
Note: Use a word as a half word
-------------------------------------------------------------*/
void EEPROM_WriteWords(uint16 Addr,uint16 *Buffer,uint16 Length)
{
uint32 *wAddr;
wAddr=(uint32 *)(EEPROM_BASE_ADDR+Addr);
DIS_INT
FLASH->PEKEYR=PEKEY1; //unlock
FLASH->PEKEYR=PEKEY2;
while(FLASH->PECR&FLASH_PECR_PELOCK);
FLASH->PECR|=FLASH_PECR_FTDW; //not fast write
while(Length--){
*wAddr++=*Buffer++;
while(FLASH->SR&FLASH_SR_BSY);
}
FLASH->PECR|=FLASH_PECR_PELOCK;
IN_INT
}
In the above code, the system interrupt DIS_INT is disabled before writing data, and the system interrupt EN_INT is enabled after writing is completed. This prevents the interrupt process from interrupting the write operation, causing CPU abnormality or lockup. Be sure to pay attention to this when using it. In the MDK environment, the two can be defined as follows:
#define EN_INT __enable_irq(); //System enables global interrupt
#define DIS_INT __disable_irq(); //System turns off global interrupts
Previous article:STM32 system learning - I2C (read and write EEPROM)
Next article:STM32 on-chip flash is used as EEPROM (power-off preservation)
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- Long press and short press based on MSP430F5529 buttons
- Solution to the problem of NAND write to offset xxxx failed -12 when burning NAND FLASH on ZYNQ
- 5. EV_HC32F460_Timer Quadrature Encoder Debugging
- 【TI recommended course】#Lecture on basic knowledge of electronic circuits#
- Capacitor Basics - Chip Multilayer Ceramic Capacitors
- 【LoRa】LoRa development common problems 2
- Interpretation of the power amplifier circuit principle! Hand-drawn circuit diagram
- EEWORLD University Hall----Teacher Tang talks about operational amplifiers
- AD8629 input square wave abnormality
- Tiny Raspberry Pi Pico Keyboard