STM32 learning - FLASH operation and use

Publisher:温暖的微风Latest update time:2017-11-04 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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--;

}

 

}



Keywords:STM32 Reference address:STM32 learning - FLASH operation and use

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

STM32 KEY
The RCC in Windows 7 is always wrong, but it is normal in XP. I still don't understand the reason. Include Files   (1) Main C language:  Code#14612 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Experimental platform: ST official 3-in-1 kit  + Hardware: STM32F103
[Microcontroller]
STM32 KEY
STM32 input capture mode
Input capture mode can be used to measure pulse width or frequency. Except for TIM6 and TIM7, all other STM32 timers have input capture function. Simply put, STM32 input capture detects the edge signal on TIMx_CHx. When the edge signal changes (such as rising edge/falling edge), the current timer value (TIMx_CNT) is st
[Microcontroller]
The relationship between stream and channel of DMA in stm32
Question: What is the relationship and difference between stream and channel in STM32 (ST) DMA? Answer: Take DMA1 of stm32 as an example. There are 8 streams in DMA1, and each stream can be configured with different transmission sources and destination addresses, which is a channel. A different source and destination
[Microcontroller]
The relationship between stream and channel of DMA in stm32
How to port the CoreMark program to STM32
Speaking of CoreMark, it may be familiar to many people. People often mention the COREMARK of some CPUs when talking about them. It is actually a benchmark code used to test the performance of various CPUs. The code is written in C language and includes enumeration, mathematical matrix operations, status and CRC calcul
[Microcontroller]
How to port the CoreMark program to STM32
About STM32GPIO port configuration commands
The following code is taken from the Atomic STM32 Development Guide //Initialize PB5 and PE5 as output ports and enable the clocks of these two ports        void LED_Init(void)   {   GPIO_InitTypeDef GPIO_InitStructure;   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //Enable PB, PE
[Microcontroller]
Solutions to the problem of using hardware IIC of STM32
Recently, our company has started using STM32, and we are not very familiar with new things. We started directly, and the platform configuration went smoothly, after all, the 8-bit platform stuff is there. But when it came to the hardware IIC, a big problem occurred. I was lazy and used the official library provided b
[Microcontroller]
Design of embedded Ethernet access control system based on STM32
  introduction   At present, many companies use work badges to complete access control management, and they still use traditional manual methods. Not only is it easy for people to sneak in, but there are no records and various human errors. At the same time, the access control system on the market has problems such
[Microcontroller]
Design of embedded Ethernet access control system based on STM32
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号