初出茅庐的小李博客之STM32F103C8T6的内部FLASH是如何划分的

STM32的内部FLASH是如何划分的?

因为STM32的内部FLASH大小不一,不同的大小划分是不一样的,但是大同小异这里是以STM32F103C8T6为例进行说明。

基础知识补充:

1 字节       = 8 位(bit)
1 千字节(KB)= 1024 字节
1 兆字节(MB)= 1024 千字节(KB)
1 吉字节(GB)= 1024 兆字节(MB)
1 太字节(TB)= 1024 吉字节(GB)

下面是关于STM32F103C8T6内部Flash划分的详细说明:

容量:

STM32F103C8T6的内部Flash容量为64KB,即64 * 1024字节,属于小容量产品。

以下是针对STM32F1系列芯片的常见型号,按照容量范围划分的示例:

容量范围芯片型号Flash大小容量大小
小容量STM32F103C8T664 KB64 * 1024 字节
STM32F103RCT6256 KB256 * 1024 字节
中容量STM32F103RBT6128 KB128 * 1024 字节
STM32F103RET6512 KB512 * 1024 字节
大容量STM32F103VET6512 KB512 * 1024 字节
STM32F103ZET61024 KB1024 * 1024 字节

扇区划分:

内部Flash存储器被划分为多个扇区,每个扇区的大小为2KB或4KB,具体划分取决于具体的芯片型号。

Flash大小为 64KB, 地址范围:0x08000000-0x08010000-1,单个扇区大小:1KB=0x400,最后一个扇区地址:0x0800FC00

Flash大小为 128KB,地址范围:0x08000000-0x08020000-1,单个扇区大小:1KB=0x400,最后一个扇区地址:0x0801FC00

Flash大小为 256KB,地址范围:0x08000000-0x08040000-1,单个扇区大小:2KB=0x800,最后一个扇区地址:0x0803F800

Flash大小为 512KB,地址范围:0x08000000-0x08080000-1,单个扇区大小:2KB=0x800,最后一个扇区地址:0x0807F800

STM32F103C8T6(64KB的扇区划分)

扇区编号起始地址结束地址大小
扇区00x080000000x080003FF1 KB
扇区10x080004000x080007FF1 KB
扇区20x080008000x08000BFF1 KB
扇区30x08000C000x08000FFF1 KB
扇区40x080010000x080013FF1 KB
扇区50x080014000x080017FF1 KB
扇区60x080018000x08001BFF1 KB
扇区70x08001C000x08001FFF1 KB
扇区80x080020000x080023FF1 KB
扇区90x080024000x080027FF1 KB
扇区100x080028000x08002BFF1 KB
扇区110x08002C000x08002FFF1 KB
扇区120x080030000x080033FF1 KB
扇区130x080034000x080037FF1 KB
扇区140x080038000x08003BFF1 KB
扇区150x08003C000x08003FFF1 KB
扇区160x080040000x080043FF1 KB
扇区170x080044000x080047FF1 KB
扇区180x080048000x08004BFF1 KB
扇区190x08004C000x08004FFF1 KB
扇区200x080050000x080053FF1 KB
扇区210x080054000x080057FF1 KB
扇区220x080058000x08005BFF1 KB
扇区230x08005C000x08005FFF1 KB
扇区240x080060000x080063FF1 KB
扇区250x080064000x080067FF1 KB
扇区260x080068000x08006BFF1 KB
扇区270x08006C000x08006FFF1 KB
扇区280x080070000x080073FF1 KB
扇区290x080074000x080077FF1 KB
扇区300x080078000x08007BFF1 KB
扇区310x08007C000x08007FFF1 KB
扇区320x080080000x080083FF1 KB
扇区330x080084000x080087FF1 KB
扇区340x080088000x08008BFF1 KB
扇区350x08008C000x08008FFF1 KB
扇区360x080090000x080093FF1 KB
扇区370x080094000x080097FF1 KB
扇区380x080098000x08009BFF1 KB
扇区390x08009C000x08009FFF1 KB
扇区400x0800A0000x0800A3FF1 KB
扇区410x0800A4000x0800A7FF1 KB
扇区420x0800A8000x0800ABFF1 KB
扇区430x0800AC000x0800AFFF1 KB
扇区440x0800B0000x0800B3FF1 KB
扇区450x0800B4000x0800B7FF1 KB
扇区460x0800B8000x0800BBFF1 KB
扇区470x0800BC000x0800BFFF1 KB
扇区480x0800C0000x0800C3FF1 KB
扇区490x0800C4000x0800C7FF1 KB
扇区500x0800C8000x0800CBFF1 KB
扇区510x0800CC000x0800CFFF1 KB
扇区520x0800D0000x0800D3FF1 KB
扇区530x0800D4000x0800D7FF1 KB
扇区540x0800D8000x0800DBFF1 KB
扇区550x0800DC000x0800DFFF1 KB
扇区560x0800E0000x0800E3FF1 KB
扇区570x0800E4000x0800E7FF1 KB
扇区580x0800E8000x0800EBFF1 KB
扇区590x0800EC000x0800EFFF1 KB
扇区600x0800F0000x0800F3FF1 KB
扇区610x0800F4000x0800F7FF1 KB
扇区620x0800F8000x0800FBFF1 KB
扇区630x0800FC000x0800FFFF1 KB

请注意,以上表格中的地址是以十六进制表示。每个扇区的大小为1KB(0x400字节)。最后一个扇区地址为0x0800FC00,范围为0x0800FC00-0x0800FFFF,大小为1KB。

STM32的内部FLASH是干什么用的?

STM32的内部Flash主要用于存储程序代码(固件)和只读数据。

  1. 程序代码(固件):内部Flash是存储微控制器的程序代码的主要地方。它包含了应用程序的指令集,包括启动代码、中断处理程序、函数和其他执行代码。这些代码定义了系统的功能和行为。通常是编译生成的HEX文件或者BIN文件。

  2. 只读数据:内部Flash还可以用于存储只读数据,如常量、配置信息和校准数据等。这些数据在程序执行期间是只读的,不会被修改。

  3. Bootloader:一些STM32芯片内置了Bootloader,它是一个特殊的程序,用于在启动时加载和更新应用程序的固件。Bootloader通常存储在内部Flash的特定区域,并负责固件的升级和管理。

STM32的内部FLASH该如何读写数据呢?

读写内部FLASH的一般步骤

在STM32微控制器中,内部Flash的读写操作通常通过以下步骤进行:

  1. 启用Flash访问:
    在进行Flash读写之前,需要先启用对Flash的访问权限。这可以通过设置Flash控制寄存器(FLASH_CR)中的特定位来实现。例如,将FLASH_CR的PG位设置为1,表示启用对Flash的编程访问。

  2. 解锁Flash:
    在进行Flash编程之前,需要解锁Flash以允许对其进行写操作。通过向FLASH_KEYR寄存器写入特定值来解锁Flash。要解锁Flash,首先写入0x45670123,然后立即写入0xCDEF89AB到FLASH_KEYR寄存器。

  3. 检查Flash状态:
    在进行Flash编程之前,需要检查Flash是否处于忙碌状态。可以通过读取FLASH_SR寄存器中的BSY位来判断Flash是否处于忙碌状态。如果BSY位为1,表示Flash正在执行操作,需要等待。

  4. 执行Flash编程:
    Flash编程可以通过直接写入特定地址处的数据来实现。要编程Flash,将要写入的数据写入Flash目标地址。请注意,写入操作是按字进行的,即每次写入4个字节。可以使用特定的函数或指针访问要编程的Flash地址。

  5. 等待Flash操作完成:
    在执行Flash编程后,需要等待编程操作完成。可以通过轮询FLASH_SR寄存器中的BSY位来检查Flash是否仍处于忙碌状态。当BSY位为0时,表示Flash操作已完成。

  6. 锁定Flash:
    完成Flash编程后,应该锁定Flash以防止意外修改。通过将FLASH_CR寄存器中的LOCK位设置为1,可以锁定Flash。

请注意,进行Flash编程时需要小心,因为不正确的操作可能会导致Flash数据的损坏。建议在编程Flash之前仔细阅读相关的芯片参考手册,并按照手册中提供的准确步骤和注意事项进行操作。需要注意的是可以使用官方提供的库和API函数来简化Flash读写的操作。

库函数接口操作内部FLASH接口解析

解锁Flash代码解析

/**
  * @brief  Unlocks the FLASH Bank1 Program Erase Controller.
  * @note   This function can be used for all STM32F10x devices.
  *         - For STM32F10X_XL devices this function unlocks Bank1.
  *         - For all other devices it unlocks Bank1 and it is 
  *           equivalent to FLASH_Unlock function.
  * @param  None
  * @retval None
  */
void FLASH_UnlockBank1(void)
{
  /* Authorize the FPEC of Bank1 Access */
  FLASH->KEYR = FLASH_KEY1;
  FLASH->KEYR = FLASH_KEY2;
}

这段代码是用于解锁STM32的Bank1程序擦除控制器(Program Erase Controller)。以下是该代码的解释:

该函数用于解锁STM32的Bank1程序擦除控制器,适用于所有STM32F10x系列的设备。对于STM32F10X_XL系列的设备,该函数解锁Bank1。对于其他设备,它解锁Bank1并等效于FLASH_Unlock函数。

该函数没有参数。

函数的返回值为None。

函数内部的操作是通过向FLASH->KEYR寄存器写入特定值来实现解锁。具体来说,两次写入FLASH_KEY1(宏定义的值)到FLASH->KEYR寄存器,以解锁Bank1的访问权限。
    
/**
  * @brief  Unlocks the FLASH Bank2 Program Erase Controller.
  * @note   This function can be used only for STM32F10X_XL density devices.
  * @param  None
  * @retval None
  */
void FLASH_UnlockBank2(void)
{
  /* Authorize the FPEC of Bank2 Access */
  FLASH->KEYR2 = FLASH_KEY1;
  FLASH->KEYR2 = FLASH_KEY2;

}

/**
  * @brief  Unlocks the FLASH Program Erase Controller.
  * @note   This function can be used for all STM32F10x devices.
  *         - For STM32F10X_XL devices this function unlocks Bank1 and Bank2.
  *         - For all other devices it unlocks Bank1 and it is equivalent 
  *           to FLASH_UnlockBank1 function.. 
  * @param  None
  * @retval None
  */
void FLASH_Unlock(void)
{
  /* Authorize the FPEC of Bank1 Access */
  FLASH->KEYR = FLASH_KEY1;
  FLASH->KEYR = FLASH_KEY2;

#ifdef STM32F10X_XL
  /* Authorize the FPEC of Bank2 Access */
  FLASH->KEYR2 = FLASH_KEY1;
  FLASH->KEYR2 = FLASH_KEY2;
#endif /* STM32F10X_XL */
}

总结: FLASH_Unlock包括 FLASH_UnlockBank1和 FLASH_UnlockBank2取决于芯片类型

/* FLASH Keys */
#define RDP_Key                  ((uint16_t)0x00A5)
#define FLASH_KEY1               ((uint32_t)0x45670123)
#define FLASH_KEY2               ((uint32_t)0xCDEF89AB)

1. RDP_Key:
   这是用于设置读保护(RDP)级别的密钥。读保护是一种保护机制,用于防止未授权的读取对Flash的访问。通过将RDP_Key写入特定的Flash寄存器,可以设置读保护级别。0x00A5是预定义的RDP_Key值。

2. FLASH_KEY1和FLASH_KEY2:
   这两个密钥是用于解锁Flash的访问权限的。当需要对Flash进行编程、擦除等操作时,需要先解锁Flash。FLASH_KEY1和FLASH_KEY2是两个32位的特定值,通过连续写入这两个值到FLASH->KEYR寄存器,可以解锁Flash的访问权限。FLASH_KEY1的值为0x45670123,FLASH_KEY2的值为0xCDEF89AB。

上锁Flash代码解析

/**
  * @brief  Locks the FLASH Bank1 Program Erase Controller.
  * @note   this function can be used for all STM32F10x devices.
  *         - For STM32F10X_XL devices this function Locks Bank1.
  *         - For all other devices it Locks Bank1 and it is equivalent 
  *           to FLASH_Lock function.
  * @param  None
  * @retval None
  */
void FLASH_LockBank1(void)
{
  /* Set the Lock Bit to lock the FPEC and the CR of  Bank1 */
  FLASH->CR |= CR_LOCK_Set;
}
这段代码是用于锁定STM32的Bank1程序擦除控制器(Program Erase Controller)。以下是该代码的解释:

该函数用于锁定STM32的Bank1程序擦除控制器,适用于所有STM32F10x系列的设备。对于STM32F10X_XL系列的设备,该函数锁定Bank1。对于其他设备,它锁定Bank1并等效于FLASH_Lock函数。

该函数没有参数。

函数的返回值为None。

函数内部的操作是通过将CR_LOCK_Set(宏定义的值)设置到FLASH->CR寄存器的LOCK位,从而锁定Bank1的访问权限。具体来说,使用按位或操作符将CR_LOCK_Set设置到FLASH->CR寄存器的LOCK位,以锁定Flash的访问权限。
/**
  * @brief  Locks the FLASH Bank2 Program Erase Controller.
  * @note   This function can be used only for STM32F10X_XL density devices.
  * @param  None
  * @retval None
  */
void FLASH_LockBank2(void)
{
  /* Set the Lock Bit to lock the FPEC and the CR of  Bank2 */
  FLASH->CR2 |= CR_LOCK_Set;
}

/**
  * @brief  Locks the FLASH Program Erase Controller.
  * @note   This function can be used for all STM32F10x devices.
  *         - For STM32F10X_XL devices this function Locks Bank1 and Bank2.
  *         - For all other devices it Locks Bank1 and it is equivalent 
  *           to FLASH_LockBank1 function.
  * @param  None
  * @retval None
  */

void FLASH_Lock(void)
{
  /* Set the Lock Bit to lock the FPEC and the CR of  Bank1 */
  FLASH->CR |= CR_LOCK_Set;

#ifdef STM32F10X_XL
  /* Set the Lock Bit to lock the FPEC and the CR of  Bank2 */
  FLASH->CR2 |= CR_LOCK_Set;
#endif /* STM32F10X_XL */
}
    

总结: FLASH_Lock包括 FLASH_LockBank1和 FLASH_LockBank2取决于芯片类型

/* Flash Control Register bits */
#define CR_PG_Set                ((uint32_t)0x00000001)
#define CR_PG_Reset              ((uint32_t)0x00001FFE) 
#define CR_PER_Set               ((uint32_t)0x00000002)
#define CR_PER_Reset             ((uint32_t)0x00001FFD)
#define CR_MER_Set               ((uint32_t)0x00000004)
#define CR_MER_Reset             ((uint32_t)0x00001FFB)
#define CR_OPTPG_Set             ((uint32_t)0x00000010)
#define CR_OPTPG_Reset           ((uint32_t)0x00001FEF)
#define CR_OPTER_Set             ((uint32_t)0x00000020)
#define CR_OPTER_Reset           ((uint32_t)0x00001FDF)
#define CR_STRT_Set              ((uint32_t)0x00000040)
#define CR_LOCK_Set              ((uint32_t)0x00000080)

这段代码定义了一些与Flash控制寄存器(Control Register)相关的位掩码(bits)。以下是这些位掩码的解释:

1. CR_PG_Set和CR_PG_Reset:
   用于编程Flash的位掩码。CR_PG_Set将FLASH->CR寄存器的PG位设置为1,表示启用Flash编程访问。CR_PG_Reset将FLASH->CR寄存器的PG位复位为0,表示禁用Flash编程访问。

2. CR_PER_Set和CR_PER_Reset:
   用于擦除Flash扇区的位掩码。CR_PER_Set将FLASH->CR寄存器的PER位设置为1,表示启用Flash扇区擦除。CR_PER_Reset将FLASH->CR寄存器的PER位复位为0,表示禁用Flash扇区擦除。

3. CR_MER_Set和CR_MER_Reset:
   用于擦除整个Flash存储器的位掩码。CR_MER_Set将FLASH->CR寄存器的MER位设置为1,表示启用Flash全片擦除。CR_MER_Reset将FLASH->CR寄存器的MER位复位为0,表示禁用Flash全片擦除。

4. CR_OPTPG_Set和CR_OPTPG_Reset:
   用于编程Flash选项字节的位掩码。CR_OPTPG_Set将FLASH->CR寄存器的OPTPG位设置为1,表示启用Flash选项字节编程。CR_OPTPG_Reset将FLASH->CR寄存器的OPTPG位复位为0,表示禁用Flash选项字节编程。

5. CR_OPTER_Set和CR_OPTER_Reset:
   用于擦除Flash选项字节的位掩码。CR_OPTER_Set将FLASH->CR寄存器的OPTER位设置为1,表示启用Flash选项字节擦除。CR_OPTER_Reset将FLASH->CR寄存器的OPTER位复位为0,表示禁用Flash选项字节擦除。

6. CR_STRT_Set:
   用于启动Flash操作的位掩码。CR_STRT_Set将FLASH->CR寄存器的STRT位设置为1,表示启动Flash编程或擦除操作。

7. CR_LOCK_Set:
   用于锁定Flash的位掩码。CR_LOCK_Set将FLASH->CR寄存器的LOCK位设置为1,表示锁定Flash的访问权限。

这些位掩码用于在进行Flash编程、擦除和操作期间设置或复位Flash控制寄存器中的特定位。在实际应用中,可以根据需要使用这些位掩码来配置和控制Flash的操作。

STM32库函数中FLASH擦除操作相关函数解析

FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
FLASH_Status FLASH_EraseAllPages(void);
FLASH_Status FLASH_EraseOptionBytes(void);

这是三个函数用于擦除STM32的Flash存储器中的页面和选项字节。以下是这些函数的解释:

1. FLASH_Status FLASH_ErasePage(uint32_t Page_Address):
   该函数用于擦除指定地址的Flash存储器页面。Page_Address参数表示要擦除的页面的起始地址。函数返回一个FLASH_Status类型的值,表示擦除操作的状态。可能的返回值包括:
   - FLASH_COMPLETE:擦除操作成功完成。
   - FLASH_BUSY:擦除操作正在进行中。
   - FLASH_ERROR_WRP:擦除操作失败,由于写保护设置导致的错误。
   - FLASH_ERROR_PG:擦除操作失败,由于编程错误导致的错误。

2. FLASH_Status FLASH_EraseAllPages(void):
   该函数用于擦除Flash存储器中的所有页面。函数返回一个FLASH_Status类型的值,表示擦除操作的状态。

3. FLASH_Status FLASH_EraseOptionBytes(void):
   该函数用于擦除Flash存储器中的选项字节。选项字节是一些用于配置Flash存储器和设备行为的特殊字节。函数返回一个FLASH_Status类型的值,表示擦除操作的状态。

这些函数用于在运行时对Flash存储器进行擦除操作。在调用这些函数之前,请确保已经解锁Flash的访问权限(通过调用FLASH_Unlock函数)
    

STM32库函数中FLASH写操作相关函数解析

FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
这是三个函数用于将数据编程到STM32的Flash存储器中。以下是这些函数的解释:

1. FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data):
   该函数用于将一个32位的数据(Data)编程到指定地址(Address)的Flash存储器中。函数返回一个FLASH_Status类型的值,表示编程操作的状态。

2. FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data):
   该函数用于将一个16位的数据(Data)编程到指定地址(Address)的Flash存储器中。函数返回一个FLASH_Status类型的值,表示编程操作的状态。

3. FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data):
   该函数用于将一个8位的数据(Data)编程到指定地址(Address)的Flash存储器的选项字节中。选项字节是一些用于配置Flash存储器和设备行为的特殊字节。函数返回一个FLASH_Status类型的值,表示编程操作的状态。

这些函数可以在运行时使用,将数据编程到Flash存储器中。在调用这些函数之前,请确保已经解锁Flash的访问权限(通过调用FLASH_Unlock函数)。在编程之前,请确保已经擦除了要写入的Flash页面。

STM32库函数中FLASH写保护、读出保护、配置选项字节操作相关函数解析

FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);
FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY);
以下是这些函数的解释:

1. FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages):
   该函数用于启用Flash存储器中指定页面(FLASH_Pages)的写保护。写保护功能可以防止对特定页面的数据写入操作。函数返回一个FLASH_Status类型的值,表示操作的状态。

2. FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState):
   该函数用于配置Flash存储器的读出保护功能。NewState参数用于启用或禁用读出保护功能。函数返回一个FLASH_Status类型的值,表示操作的状态。

3. FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY):
   该函数用于配置用户选项字节(User Option Bytes),用于设置设备的特定选项。OB_IWDG、OB_STOP和OB_STDBY参数用于配置选项字节的不同选项。函数返回一个FLASH_Status类型的值,表示操作的状态。

这些函数用于在运行时对Flash存储器进行写保护、读出保护和配置选项字节的操作。在调用这些函数之前,请确保已经解锁Flash的访问权限(通过调用FLASH_Unlock函数)。

STM32库函数中FLASH获取相关设置结果的函数解析

uint32_t FLASH_GetUserOptionByte(void);
uint32_t FLASH_GetWriteProtectionOptionByte(void);
FlagStatus FLASH_GetReadOutProtectionStatus(void);
FlagStatus FLASH_GetPrefetchBufferStatus(void);

以下是这些函数的解释:
1. uint32_t FLASH_GetUserOptionByte(void):
   该函数用于获取用户选项字节(User Option Bytes)的值。用户选项字节是用于设置设备的特定选项的字节。

2. uint32_t FLASH_GetWriteProtectionOptionByte(void):
   该函数用于获取写保护选项字节的值。写保护选项字节用于配置Flash存储器中的写保护功能。

3. FlagStatus FLASH_GetReadOutProtectionStatus(void):
   该函数用于获取Flash存储器的读出保护状态。返回的FlagStatus类型值表示读出保护是否已启用。

4. FlagStatus FLASH_GetPrefetchBufferStatus(void):
   该函数用于获取预取缓存器(Prefetch Buffer)的状态。返回的FlagStatus类型值表示预取缓存器是否已启用。

这些函数用于获取Flash存储器的信息,跟上面的函数作用相反

STM32库函数中FLASH有关中断配置以及执行状态获取的函数解析

void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
FLASH_Status FLASH_GetStatus(void);
以下是这些函数的解释:

1. void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState):
   该函数用于配置Flash存储器的中断功能。FLASH_IT参数用于指定要配置的中断类型,NewState参数用于启用或禁用中断功能。

2. FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG):
   该函数用于获取指定Flash标志位的状态。FLASH_FLAG参数用于指定要查询的标志位,返回的FlagStatus类型值表示标志位的状态。

3. void FLASH_ClearFlag(uint32_t FLASH_FLAG):
   该函数用于清除指定的Flash标志位。FLASH_FLAG参数用于指定要清除的标志位。
    
4. FLASH_Status FLASH_GetStatus(void):
   该函数用于获取Flash存储器的状态。  
这些函数用于操作Flash存储器的中断和标志位。使用FLASH_ITConfig函数可以配置Flash存储器的中断功能,通过指定FLASH_IT参数来选择要配置的中断类型,通过NewState参数来启用或禁用中断。使用FLASH_GetFlagStatus函数可以获取指定标志位的状态,通过指定FLASH_FLAG参数来选择要查询的标志位,返回的FlagStatus类型值表示标志位的状态。使用FLASH_ClearFlag函数可以清除指定的标志位,通过指定FLASH_FLAG参数来选择要清除的标志位。

一般在进行FLASH之前会认为的清除对应标准确保FLASH处于未被操作的状态。也可以通过FLASH_GetStatus函数来获取Flash存储器的状态。
以便根据需要采取相应的处理措施。
返回值类型为 `FLASH_Status`,表示Flash存储器的操作状态。可能的返回值包括:
- FLASH_COMPLETE:上一次的Flash操作已完成。
- FLASH_TIMEOUT:Flash操作超时。
- FLASH_BUSY:Flash存储器正忙,无法执行新的操作。
- FLASH_ERROR_PG:Flash编程错误,写入数据失败。
- FLASH_ERROR_WRP:Flash写保护错误,无法写入数据。
    
    
 函数 `FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)` 用于等待Flash存储器上一次操作的完成。

 该函数的参数 Timeout是等待超时的时间,单位为毫秒。如果上一次的Flash操作在指定的超时时间内完成,函数将返回 FLASH_COMPLETE,表示操作已完成。如果超过了指定的超时时间,函数将返回 FLASH_TIMEOUT,表示操作超时。
返回值类型为 `FLASH_Status`,表示Flash存储器的操作状态。可能的返回值包括:
- FLASH_COMPLETE:上一次的Flash操作已完成。
- FLASH_TIMEOUT:Flash操作超时。
- FLASH_BUSY:Flash存储器正忙,无法执行新的操作。
- FLASH_ERROR_PG:Flash编程错误,写入数据失败。
- FLASH_ERROR_WRP:Flash写保护错误,无法写入数据。

通过调用该函数,并传入适当的超时时间,可以等待Flash存储器上一次操作的完成,并根据返回值判断操作的状态。这样可以确保在进行下一次Flash操作之前,上一次操作已经完成。确保程序执行的正确性。

STM32库函数中有关FLASH性能配置的几个函数

void FLASH_SetLatency(uint32_t FLASH_Latency);
void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess);
void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer);
这三个函数用于配置STM32的Flash存储器访问性能和优化选项。以下是这些函数的解释:

1. void FLASH_SetLatency(uint32_t FLASH_Latency):
   该函数用于设置Flash存储器的访问延迟(Latency)。Flash存储器的访问延迟是指在访问Flash数据时需要的等待周期数。FLASH_Latency参数是一个表示访问延迟的值,具体取决于系统时钟频率和Flash存储器的性能特性。

2. void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess):
   该函数用于配置Flash存储器的半周期访问。FLASH_HalfCycleAccess参数用于启用或禁用Flash存储器的半周期访问模式。在半周期访问模式下,访问Flash存储器的时钟周期被减半,可以提高Flash存储器的访问速度。参数FLASH_HalfCycleAccess可以是以下值之一:
   - FLASH_HalfCycleAccess_Enable:启用半周期访问模式。
   - FLASH_HalfCycleAccess_Disable:禁用半周期访问模式。

3. void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer):
   该函数用于配置Flash存储器的预取缓冲区。预取缓冲区是用于提前读取Flash数据的缓冲区,可以加速Flash数据的访问。FLASH_PrefetchBuffer参数用于启用或禁用Flash存储器的预取缓冲区。参数FLASH_PrefetchBuffer可以是以下值之一:
   - FLASH_PrefetchBuffer_Enable:启用预取缓冲区。
   - FLASH_PrefetchBuffer_Disable:禁用预取缓冲区。

这些函数可以根据需要在初始化阶段或运行时阶段调用,以配置Flash存储器的访问性能和优化选项。具体使用哪些函数以及参数取决于系统要求和性能需求。

STM32的FLASH如何进行编程(库函数样例)

int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     

/* Porgram FLASH Bank1 ********************************************************/       
  /* Unlock the Flash Bank1 Program Erase controller */
  FLASH_UnlockBank1();

  /* Define the number of page to be erased */
  NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE;

  /* Clear All pending flags */
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	

  /* Erase the FLASH pages */
  for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  {
    FLASHStatus = FLASH_ErasePage(BANK1_WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
  }
  
  /* Program Flash Bank1 */
  Address = BANK1_WRITE_START_ADDR;

  while((Address < BANK1_WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))
  {
    FLASHStatus = FLASH_ProgramWord(Address, Data);
    Address = Address + 4;
  }

  FLASH_LockBank1();
  
  /* Check the correctness of written data */
  Address = BANK1_WRITE_START_ADDR;

  while((Address < BANK1_WRITE_END_ADDR) && (MemoryProgramStatus != FAILED))
  {
    if((*(__IO uint32_t*) Address) != Data)
    {
      MemoryProgramStatus = FAILED;
    }
    Address += 4;
  }
}

这段代码展示了一个主函数的示例,其中包含了对Flash的擦除、编程和数据验证操作。以下是对每个步骤的解释:

1. 对系统进行初始化:在main函数之前,通过调用SystemInit()函数来配置微控制器的时钟设置和其他系统初始化。可以在system_stm32f10x.c文件中重新配置SystemInit()函数的默认设置。

2. 解锁Flash Bank1:调用FLASH_UnlockBank1()函数来解锁Flash Bank1的编程和擦除控制器,允许对其进行操作。

3. 计算需要擦除的页数:通过计算Flash可编程区域的起始地址和结束地址之间的页数,得到需要擦除的页数。每页的大小由FLASH_PAGE_SIZE定义。

4. 清除标志位:调用FLASH_ClearFlag()函数来清除Flash的待处理标志位,包括操作结束标志位(EOP)、编程错误标志位(PGERR)和写保护错误标志位(WRPRTERR)5. 擦除Flash页:使用循环结构,调用FLASH_ErasePage()函数来逐页擦除Flash。循环会检查擦除操作的状态,并在满足条件时继续进行下一页的擦除。

6. 编程Flash:使用循环结构,调用FLASH_ProgramWord()函数来逐字编程Flash。循环会检查编程操作的状态,并在满足条件时继续进行下一个地址的编程。

7. 加锁Flash Bank1:调用FLASH_LockBank1()函数来锁定Flash Bank1,防止进一步的编程和擦除操作。

8. 验证数据的正确性:使用循环结构,通过读取Flash中的数据与预期的数据进行比较,来验证数据的正确性。如果发现不一致的数据,则将MemoryProgramStatus标记为FAILED。

这段代码展示了如何在主函数中执行Flash的擦除、编程和数据验证操作。在实际应用中,需要根据具体的需求和硬件配置进行相应的调整和错误处理。

在STM32F103C8T6上进行验证


#define STM32PAGESIZE 			1024  //	一个页的字节数是1K

//写数据到FLASH中并加上校验
uint8_t STM32Flash_SaveParm(uint32_t Addr,uint8_t *pdata,uint16_t len)
{
	uint16_t i=0,Page;
	uint32_t tmpAddr,tmplen,Sum=0;
	if(Addr%4)
		return 0;
	FLASH_Unlock();
	FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
	tmpAddr = Addr-Addr%STM32PAGESIZE;
	if(Addr%STM32PAGESIZE)
	{
		tmplen = len+Addr%STM32PAGESIZE-STM32PAGESIZE;
		Page   = 1;
	}
	else
	{
		tmplen = len;
		Page   = 0;
	}
	Page += tmplen/STM32PAGESIZE;
	if(tmplen%STM32PAGESIZE)
		Page++;
	for(i=0;i<Page;i++)	
		FLASH_ErasePage(tmpAddr+i*STM32PAGESIZE);
	for(i=0;i<len;i++)
		Sum+=pdata[i];
	for(i=0;i<len/4;i++)
	{
		FLASH_ProgramWord(Addr, *(uint32_t*)pdata);
		pdata +=4;
		Addr  +=4;
	}
	if(len%4)
	{
		uint8_t buf[4]={0},j;
		for(j=0;j<len%4;j++)         
			buf[j]=*pdata++;	
		FLASH_ProgramWord(Addr, *(uint32_t*)buf);
		Addr+=4;
	}
	FLASH_ProgramWord(Addr, Sum);
	FLASH_Lock();
	return 0;
}
//读数据从FLASH中并计算校验
uint8_t STM32Flash_ReadParm(uint32_t Addr,uint8_t *pdata,uint16_t len)
{
	uint16_t i;
	uint32_t Sum=0;
	uint8_t *qdata=pdata;
	if(Addr%4)
		return 0;
	for(i=0;i<len/4;i++)
	{
		*(uint32_t*)pdata=*(uint32_t*)Addr;
		Addr+=4;
		pdata+=4;
	}
	if(len%4)
	{
		uint8_t buf[4]={0};
		*(uint32_t*)buf=*(uint32_t*)Addr;
		Addr+=4;
		for(i=0;i<len%4;i++)
			*pdata++=buf[i];
	}
	for(i=0;i<len;i++)
		Sum+=(*qdata++);
	if(Sum!=*(uint32_t*)Addr)
	{
		return 1;
	}
	return 0;
}

总结:FLASH的读写在IAP或者OTA以及fatfs上有很重要的应用,这篇文章就先记录这么多,后面会考虑实现一个单片机给(F407)给另外一个单片机(F103)进行程序升级。对这一块儿感兴趣的朋友可以关注,不定期更新~

  • 0
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值