Flash operation:
The large-capacity flash of stm32 is not only used to store program code, but also to store some data and system user parameters. The program code is generally saved in the area starting from the flash, and the remaining area space can be used to store user data (the size depends on the size of the flash and the size of the code space). If the stored data is small, the last page can be used to store user data specifically, so as to prevent conflicts with the program code space.
1. The STM32 Flash has a limit on the number of read and write times and lifespan, so do not repeatedly perform read and write operations in a loop.
2. Both reading and writing FLASH requires time. Setting the waiting period is to ensure correct reading and writing. Because the CPU speed is much faster than the FLASH operation speed, use the library function FLASH_SetLatency (FLASH_Latency_2) to set it.
3. Enable the FLASH pre-read buffer function to speed up the reading of FLASH. Required
usage in all programs: FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
4. Turn on the internal oscillator RCC_HSICmd (ENABLE);
5. STM32's operation on Flash must follow certain steps. It must be erased before writing. Erasing must be done in PAGE (page) bit units, and writing (programming) must be done in Word (two bytes) units.
6. About read protection and write protection :
After configuring read protection, the code and data in the Flash cannot be read out through the JTAG and RAM programs, which plays the role of encryption. Write protection is based on pages (or multiple pages). After configuration, it cannot be erased or modified, which strengthens the reliability of the code. Both read protection and write protection are configured in your own program. You can configure the relevant option words when running the program for the first time.
The program starts writing 2 half-words of data from 0x0800f800, and then returns it via the serial port in the MAIN function:
void flash_write()
{u16 cnt = 0;
u16 data[2]={0x1234,0x5678};
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(0x0800f800);
for(cnt=0;cnt<2;cnt++)
FLASH_ProgramHalfWord((0x0800f800 +cnt*2),data[cnt]);
FLASH_Lock();
}
The code of the MAIN function about Flash operation:
uint8_t i;
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
flash_write();
i = *(uint32_t *)(0x0800f802); //Read the data of the changed address and assign value to i
send_byte(i); //The serial port returns the data at address 0x0800f802
Because I always got an error when I tried to write a byte before, I looked up the manual and found that I couldn't write 1 byte of data. I also found that an error would occur when the flash write address was an odd number. So in this code
The address to write to the flash can only be an even number. During the browsing process, I also found that the manual said that writing and erasing the flash will affect the operating speed of the CPU, but I didn't read it carefully (I really don't want to read it).
1. -DataFlash.c----------------------------------
2.
3. #include "DataFlash.h"
4 uint16_t Flash_Write_Without_check(uint32_t iAddress, uint8_t *buf, uint16_t iNumByteToWrite) {
9. uint16_t i;
10. volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
11. i = 0;
12.
13.// FLASH_UnlockBank1();
14. while((i < iNumByteToWrite) && (FLASHStatus == FLASH_COMPLETE))
15. {
16. FLASHStatus = FLASH_ProgramHalfWord(iAddress, *(uint16_t*)buf);
17. i = i+2;
18. iAddress = iAddress + 2;
19. buf = buf + 2;
20. }
twenty one.
22. return iNumByteToWrite;
twenty three.}
twenty four.//
33.int Flash_Write(uint32_t iAddress, uint8_t *buf, uint32_t iNbrToWrite) {
34. /
35. uint32_t secpos;
36. uint32_t iNumByteToWrite = iNbrToWrite;
37.uint16_t secoff;
38.uint16_t secremain;
39. uint16_t i = 0;
40. uint8_t tmp[FLASH_PAGE_SIZE];
41.
42. FLASH_UnlockBank1();
43.secpos=iAddress & (~(FLASH_PAGE_SIZE -1 )) ;//sector address
44.secoff=iAddress & (FLASH_PAGE_SIZE -1); //Offset within the sector
45.secremain=FLASH_PAGE_SIZE-secoff; //Sector remaining space size
46. volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
47.
48. if (iNumByteToWrite<=secremain) secremain = iNumByteToWrite; // not more than 4096 bytes
49.
50. while( 1 ) {
51. Flash_Read(secpos, tmp, FLASH_PAGE_SIZE); //Read the entire sector
52. for(i=0;i//check data
53. if(tmp[secoff+i]!=0XFF)break; //need to erase
54. }
55. if(i //need to erase
56. FLASHStatus = FLASH_ErasePage(secpos); // Erase this sector
57. if(FLASHStatus != FLASH_COMPLETE)
58. return -1;
59. for(i=0;i//copy
60. tmp[i+secoff]=buf[i];
61. }
62. Flash_Write_Without_check(secpos, tmp, FLASH_PAGE_SIZE); //Write the entire sector
63. } else {
64. Flash_Write_Without_check(iAddress,buf,secremain); //Write the erased content directly to the remaining area of the sector.
65. }
66.
67. if(iNumByteToWrite==secremain) //Writing is finished
68. break;
69. else {
70. secpos += FLASH_PAGE_SIZE;
71. secoff = 0; //Offset position is 0
72. buf += secremain; // pointer offset
73. iAddress += secremain; //write address offset
74. iNumByteToWrite -= secremain; //Decrement the number of bytes
75. if(iNumByteToWrite>FLASH_PAGE_SIZE) secremain=FLASH_PAGE_SIZE; //The next sector cannot be written completely
76. else secremain = iNumByteToWrite; //The next sector can be written
77. }
78.
79. }
80.
81. FLASH_LockBank1();
82. return iNbrToWrite;
83.}
90.
99.int Flash_Read(uint32_t iAddress, uint8_t *buf, int32_t iNbrToRead) {
100. int i = 0;
101. while(i < iNbrToRead ) {
102. *(buf + i) = *(__IO uint8_t*) iAddress++;
103. i++;
104. }
105. return i;
106.}
110.------------------DataFlash.h-------------------------- --------
111.
112.#ifndef __DATAFLASH_H__
113.#define __DATAFLASH_H__
114.
115.
116.#include "stm32f10x.h"
117.#include "stm32f10x_flash.h"
#if defined (STM32F10X_HD) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) || defined (STM32F10X_XL)
123. #define FLASH_PAGE_SIZE ((uint16_t)0x800)
124.
125.#else
126. #define FLASH_PAGE_SIZE ((uint16_t)0x400)
127.#endif
132.int Flash_Read(uint32_t iAddress, uint8_t *buf, int32_t iNbrToRead);
133.int Flash_Write(uint32_t iAddress, uint8_t *buf, uint32_t iNbrToWrite);
134.
135.
136.#endif
///////////////////////////////////////////////////// /////////////////////////////////////
Practiced code:
void SetSysClockFromHSI(void) //Set high-speed internal clock
{
// SYSCLK, HCLK, PCLK2 and PCLK1 configuration ----------------------------*/
//RCC system reset(for debug purpose) */
RCC_DeInit();
// Enable HSI */
RCC_HSICmd(ENABLE); //Turn on the internal oscillator RCC_HSICmd(ENABLE);
// Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // Enable the FLASH pre-read buffer function to speed up the reading of FLASH
// 0 wait state from 0 to 24 MHz
// 1 wait state from 24 to 48 MHz
// 2 wait states above.
// Flash wait state */
if(RCC_PLLMul_Config <= RCC_PLLMul_6)// <=24 MHz
//#define FLASH_Latency_0 ((uint32_t)0x00000000) //< FLASH Zero Latency cycle */
FLASH_SetLatency(FLASH_Latency_0); //Set code delay value
else if(RCC_PLLMul_Config <= RCC_PLLMul_12)// <=48 MHz
//#define FLASH_Latency_1 ((uint32_t)0x00000001) //< FLASH One Latency cycle */
FLASH_SetLatency(FLASH_Latency_1);
else
//#define FLASH_Latency_2 ((uint32_t)0x00000002) //< FLASH Two Latency cycles */ FLASH two latency cycles
FLASH_SetLatency(FLASH_Latency_2);
//HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
// PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
//PCLK1 = HCLK */
RCC_PCLK1Config(RCC_HCLK_Div1);
// PLLCLK = 4MHz * RCC_PLLMul_Config */
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_Config);
//Enable PLL */
RCC_PLLCmd(ENABLE);
// Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}
//Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// Wait till PLL is used as system clock source */
/
while(RCC_GetSYSCLKSource() != 0x08){}
}
/
u8 FLASH_WriteNByte(u32 addr, s16 *dat_buf, u8 no)
{
//Unlock the Flash Program Erase controller */
FLASH_Unlock(); // FLASH unlock
if(FLASH_GetFlagStatus(FLASH_FLAG_BSY) == SET) return FALSE; // To confirm that there is no other programming operation in progress, return an error to exit
// Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); // Clear flag bit
while(FLASH_GetFlagStatus(FLASH_FLAG_BSY) == SET);
FLASHStatus = FLASH_ErasePage(addr);
while(FLASH_GetFlagStatus(FLASH_FLAG_BSY) == SET);
while(no && (FLASHStatus == FLASH_COMPLETE))
{
FLASHStatus = FLASH_ProgramHalfWord(addr, *dat_buf); // Write with 16-bit width, including the step of setting the PG bit of the FLASH_CR register to 1
addr += 2; //Flash write address will also fail if it is an odd number
dat_buf++;
no--;
while(FLASH_GetFlagStatus(FLASH_FLAG_BSY) == SET); // Wait for writing to end
}
FLASH_Lock(); // FLASH locked
while(FLASH_GetFlagStatus(FLASH_FLAG_BSY) == SET);
if(no == 0) return TRUE;
else return FALSE;
}
/
void FLASH_ReadNByte(u32 addr, s16 *dat_buf, u8 no)
{
u8 HalfWordN = 0;
while(no)
{
dat_buf[HalfWordN] = *(vs16*)(addr + HalfWordN * 2); //Offset FLASH is an even address
HalfWordN++;
no--;
}
}
Previous article:The process of establishing a simple stm32 program
Next article:Introduction to STM32 clock library function RCC_DeInit
Recommended ReadingLatest update time:2024-11-15 17:29
- 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
- Keysight Technologies Helps Samsung Electronics Successfully Validate FiRa® 2.0 Safe Distance Measurement Test Case
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- 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)
- The mobile station adds a new board, the STM32F723 Discovery Kit
- [Teardown of the car wireless charger] - Disassembling the Deli wireless car charger
- TTP250-S001 dimming solution and capacitive touch switch chip
- [Fudan Micro FM33LG0 Series Development Board Review] A Preliminary Study on the Rubik's Cube Development Environment
- BOOST Circuit Simulation
- Bluetooth (cc2540) protocol stack learning 1
- XMC4800 Review (Part 4) - Data Sharing
- 【DIY Creative LED】WS2812 Effect Display File
- One watt of GaN is less than one yuan, and it is free shipping by SF Express? Lenovo has launched a price war on GaN.
- B-U585I-IOT02A uses WIFI function