因为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大小 | 容量大小 |
---|---|---|---|
小容量 | STM32F103C8T6 | 64 KB | 64 * 1024 字节 |
STM32F103RCT6 | 256 KB | 256 * 1024 字节 | |
中容量 | STM32F103RBT6 | 128 KB | 128 * 1024 字节 |
STM32F103RET6 | 512 KB | 512 * 1024 字节 | |
大容量 | STM32F103VET6 | 512 KB | 512 * 1024 字节 |
STM32F103ZET6 | 1024 KB | 1024 * 1024 字节 |
扇区划分
内部Flash存储器被划分为多个扇区,每个扇区的大小为2KB或4KB,具体划分取决于具体的芯片型号。
Flash大小 | 地址范围 | 扇区大小 | 最后扇区地址 |
---|---|---|---|
64KB | 0x08000000~0x08010000-1 | 1KB=0x400 | 0x0800FC00 |
128K | 0x08000000~0x08020000-1 | 1KB=0x400 | 0x0801FC00 |
256K | 0x08000000~0x08040000-1 | 2KB=0x800 | 0x0803F800 |
512K | 0x08000000~0x08080000-1 | 2KB=0x800 | 0x0807F800 |
STM32F103C8T6(64KB的扇区划分)
扇区编号 | 起始地址 | 结束地址 | 大小 |
---|---|---|---|
扇区0 | 0x08000000 | 0x080003FF | 1 KB |
扇区1 | 0x08000400 | 0x080007FF | 1 KB |
扇区2 | 0x08000800 | 0x08000BFF | 1 KB |
扇区3 | 0x08000C00 | 0x08000FFF | 1 KB |
扇区4 | 0x08001000 | 0x080013FF | 1 KB |
扇区5 | 0x08001400 | 0x080017FF | 1 KB |
扇区6 | 0x08001800 | 0x08001BFF | 1 KB |
扇区7 | 0x08001C00 | 0x08001FFF | 1 KB |
扇区8 | 0x08002000 | 0x080023FF | 1 KB |
扇区9 | 0x08002400 | 0x080027FF | 1 KB |
扇区10 | 0x08002800 | 0x08002BFF | 1 KB |
扇区11 | 0x08002C00 | 0x08002FFF | 1 KB |
扇区12 | 0x08003000 | 0x080033FF | 1 KB |
扇区13 | 0x08003400 | 0x080037FF | 1 KB |
扇区14 | 0x08003800 | 0x08003BFF | 1 KB |
扇区15 | 0x08003C00 | 0x08003FFF | 1 KB |
扇区16 | 0x08004000 | 0x080043FF | 1 KB |
扇区17 | 0x08004400 | 0x080047FF | 1 KB |
扇区18 | 0x08004800 | 0x08004BFF | 1 KB |
扇区19 | 0x08004C00 | 0x08004FFF | 1 KB |
扇区20 | 0x08005000 | 0x080053FF | 1 KB |
扇区21 | 0x08005400 | 0x080057FF | 1 KB |
扇区22 | 0x08005800 | 0x08005BFF | 1 KB |
扇区23 | 0x08005C00 | 0x08005FFF | 1 KB |
扇区24 | 0x08006000 | 0x080063FF | 1 KB |
扇区25 | 0x08006400 | 0x080067FF | 1 KB |
扇区26 | 0x08006800 | 0x08006BFF | 1 KB |
扇区27 | 0x08006C00 | 0x08006FFF | 1 KB |
扇区28 | 0x08007000 | 0x080073FF | 1 KB |
扇区29 | 0x08007400 | 0x080077FF | 1 KB |
扇区30 | 0x08007800 | 0x08007BFF | 1 KB |
扇区31 | 0x08007C00 | 0x08007FFF | 1 KB |
扇区32 | 0x08008000 | 0x080083FF | 1 KB |
扇区33 | 0x08008400 | 0x080087FF | 1 KB |
扇区34 | 0x08008800 | 0x08008BFF | 1 KB |
扇区35 | 0x08008C00 | 0x08008FFF | 1 KB |
扇区36 | 0x08009000 | 0x080093FF | 1 KB |
扇区37 | 0x08009400 | 0x080097FF | 1 KB |
扇区38 | 0x08009800 | 0x08009BFF | 1 KB |
扇区39 | 0x08009C00 | 0x08009FFF | 1 KB |
扇区40 | 0x0800A000 | 0x0800A3FF | 1 KB |
扇区41 | 0x0800A400 | 0x0800A7FF | 1 KB |
扇区42 | 0x0800A800 | 0x0800ABFF | 1 KB |
扇区43 | 0x0800AC00 | 0x0800AFFF | 1 KB |
扇区44 | 0x0800B000 | 0x0800B3FF | 1 KB |
扇区45 | 0x0800B400 | 0x0800B7FF | 1 KB |
扇区46 | 0x0800B800 | 0x0800BBFF | 1 KB |
扇区47 | 0x0800BC00 | 0x0800BFFF | 1 KB |
扇区48 | 0x0800C000 | 0x0800C3FF | 1 KB |
扇区49 | 0x0800C400 | 0x0800C7FF | 1 KB |
扇区50 | 0x0800C800 | 0x0800CBFF | 1 KB |
扇区51 | 0x0800CC00 | 0x0800CFFF | 1 KB |
扇区52 | 0x0800D000 | 0x0800D3FF | 1 KB |
扇区53 | 0x0800D400 | 0x0800D7FF | 1 KB |
扇区54 | 0x0800D800 | 0x0800DBFF | 1 KB |
扇区55 | 0x0800DC00 | 0x0800DFFF | 1 KB |
扇区56 | 0x0800E000 | 0x0800E3FF | 1 KB |
扇区57 | 0x0800E400 | 0x0800E7FF | 1 KB |
扇区58 | 0x0800E800 | 0x0800EBFF | 1 KB |
扇区59 | 0x0800EC00 | 0x0800EFFF | 1 KB |
扇区60 | 0x0800F000 | 0x0800F3FF | 1 KB |
扇区61 | 0x0800F400 | 0x0800F7FF | 1 KB |
扇区62 | 0x0800F800 | 0x0800FBFF | 1 KB |
扇区63 | 0x0800FC00 | 0x0800FFFF | 1 KB |
请注意,以上表格中的地址是以十六进制表示。每个扇区的大小为1KB(0x400字节)。最后一个扇区地址为0x0800FC00,范围为0x0800FC00-0x0800FFFF,大小为1KB。
STM32的内部FLASH是干什么用的?
STM32的内部Flash主要用于存储程序代码(固件)和只读数据。
- 程序代码(固件):内部Flash是存储微控制器的程序代码的主要地方。它包含了应用程序的指令集,包括启动代码、中断处理程序、函数和其他执行代码。这些代码定义了系统的功能和行为。通常是编译生成的HEX文件或者BIN文件。
- 只读数据:内部Flash还可以用于存储只读数据,如常量、配置信息和校准数据等。这些数据在程序执行期间是只读的,不会被修改。
- Bootloader:一些STM32芯片内置了Bootloader,它是一个特殊的程序,用于在启动时加载和更新应用程序的固件。Bootloader通常存储在内部Flash的特定区域,并负责固件的升级和管理。
STM32的内部FLASH该如何读写数据呢?
读写内部FLASH的一般步骤
在STM32微控制器中,内部Flash的读写操作通常通过以下步骤进行:
- 启用Flash访问:在进行Flash读写之前,需要先启用对Flash的访问权限。这可以通过设置Flash控制寄存器(FLASH_CR)中的特定位来实现。例如,将FLASH_CR的PG位设置为1,表示启用对Flash的编程访问。
- 解锁Flash:在进行Flash编程之前,需要解锁Flash以允许对其进行写操作。通过向FLASH_KEYR寄存器写入特定值来解锁Flash。要解锁Flash,首先写入0x45670123,然后立即写入0xCDEF89AB到FLASH_KEYR寄存器。
- 检查Flash状态:在进行Flash编程之前,需要检查Flash是否处于忙碌状态。可以通过读取FLASH_SR寄存器中的BSY位来判断Flash是否处于忙碌状态。如果BSY位为1,表示Flash正在执行操作,需要等待。
- 执行Flash编程:Flash编程可以通过直接写入特定地址处的数据来实现。要编程Flash,将要写入的数据写入Flash目标地址。请注意,写入操作是按字进行的,即每次写入4个字节。可以使用特定的函数或指针访问要编程的Flash地址。
- 等待Flash操作完成:在执行Flash编程后,需要等待编程操作完成。可以通过轮询FLASH_SR寄存器中的BSY位来检查Flash是否仍处于忙碌状态。当BSY位为0时,表示Flash操作已完成。
- 锁定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)
- RDP_Key:
这是用于设置读保护(RDP)级别的密钥。读保护是一种保护机制,用于防止未授权的读取对Flash的访问。通过将RDP_Key写入特定的Flash寄存器,可以设置读保护级别。0x00A5是预定义的RDP_Key值。- 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)。以下是这些位掩码的解释:
- CR_PG_Set和CR_PG_Reset:
用于编程Flash的位掩码。CR_PG_Set将FLASH->CR寄存器的PG位设置为1,表示启用Flash编程访问。CR_PG_Reset将FLASH->CR寄存器的PG位复位为0,表示禁用Flash编程访问。- CR_PER_Set和CR_PER_Reset:
用于擦除Flash扇区的位掩码。CR_PER_Set将FLASH->CR寄存器的PER位设置为1,表示启用Flash扇区擦除。CR_PER_Reset将FLASH->CR寄存器的PER位复位为0,表示禁用Flash扇区擦除。- CR_MER_Set和CR_MER_Reset:
用于擦除整个Flash存储器的位掩码。CR_MER_Set将FLASH->CR寄存器的MER位设置为1,表示启用Flash全片擦除。CR_MER_Reset将FLASH->CR寄存器的MER位复位为0,表示禁用Flash全片擦除。- CR_OPTPG_Set和CR_OPTPG_Reset:
用于编程Flash选项字节的位掩码。CR_OPTPG_Set将FLASH->CR寄存器的OPTPG位设置为1,表示启用Flash选项字节编程。CR_OPTPG_Reset将FLASH->CR寄存器的OPTPG位复位为0,表示禁用Flash选项字节编程。- CR_OPTER_Set和CR_OPTER_Reset:
用于擦除Flash选项字节的位掩码。CR_OPTER_Set将FLASH->CR寄存器的OPTER位设置为1,表示启用Flash选项字节擦除。CR_OPTER_Reset将FLASH->CR寄存器的OPTER位复位为0,表示禁用Flash选项字节擦除。- CR_STRT_Set:
用于启动Flash操作的位掩码。CR_STRT_Set将FLASH->CR寄存器的STRT位设置为1,表示启动Flash编程或擦除操作。- 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存储器中的页面和选项字节。以下是这些函数的解释:
- FLASH_Status FLASH_ErasePage(uint32_t Page_Address):
该函数用于擦除指定地址的Flash存储器页面。Page_Address参数表示要擦除的页面的起始地址。函数返回一个FLASH_Status类型的值,表示擦除操作的状态。可能的返回值包括:
- FLASH_COMPLETE:擦除操作成功完成。
- FLASH_BUSY:擦除操作正在进行中。
- FLASH_ERROR_WRP:擦除操作失败,由于写保护设置导致的错误。
- FLASH_ERROR_PG:擦除操作失败,由于编程错误导致的错误。
- FLASH_Status FLASH_EraseAllPages(void):
该函数用于擦除Flash存储器中的所有页面。函数返回一个FLASH_Status类型的值,表示擦除操作的状态。- 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存储器中。以下是这些函数的解释:
- FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data):
该函数用于将一个32位的数据(Data)编程到指定地址(Address)的Flash存储器中。函数返回一个FLASH_Status类型的值,表示编程操作的状态。- FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data):
该函数用于将一个16位的数据(Data)编程到指定地址(Address)的Flash存储器中。函数返回一个FLASH_Status类型的值,表示编程操作的状态。- FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data):
该函数用于将一个8位的数据(Data)编程到指定地址(Address)的Flash存储器的选项字节中。选项字节是一些用于配置Flash存储器和设备行为的特殊字节。函数返回一个FLASH_Status类型的值,表示编程操作的状态。
这些函数可以在运行时使用,将数据编程到Flash存储器中。在调用这些函数之前,请确保已经解锁Flash的访问权限(通过调用FLASH_Unlock函数)。在编程之前,请确保已经擦除了要写入的Flash页面。
STM32库函数中FLASH写保护、读出保护、配置选项字节操作相关函数解析
LASH_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);
以下是这些函数的解释:
- FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages):
该函数用于启用Flash存储器中指定页面(FLASH_Pages)的写保护。写保护功能可以防止对特定页面的数据写入操作。函数返回一个FLASH_Status类型的值,表示操作的状态。- FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState):
该函数用于配置Flash存储器的读出保护功能。NewState参数用于启用或禁用读出保护功能。函数返回一个FLASH_Status类型的值,表示操作的状态。- 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);
以下是这些函数的解释:
- uint32_t FLASH_GetUserOptionByte(void):
该函数用于获取用户选项字节(User Option Bytes)的值。用户选项字节是用于设置设备的特定选项的字节。- uint32_t FLASH_GetWriteProtectionOptionByte(void):
该函数用于获取写保护选项字节的值。写保护选项字节用于配置Flash存储器中的写保护功能。- FlagStatus FLASH_GetReadOutProtectionStatus(void):
该函数用于获取Flash存储器的读出保护状态。返回的FlagStatus类型值表示读出保护是否已启用。- 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);
以下是这些函数的解释:
- void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState):
该函数用于配置Flash存储器的中断功能。FLASH_IT参数用于指定要配置的中断类型,NewState参数用于启用或禁用中断功能。- FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG):
该函数用于获取指定Flash标志位的状态。FLASH_FLAG参数用于指定要查询的标志位,返回的FlagStatus类型值表示标志位的状态。- void FLASH_ClearFlag(uint32_t FLASH_FLAG):
该函数用于清除指定的Flash标志位。FLASH_FLAG参数用于指定要清除的标志位。- 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存储器访问性能和优化选项。以下是这些函数的解释:
- void FLASH_SetLatency(uint32_t FLASH_Latency):
该函数用于设置Flash存储器的访问延迟(Latency)。Flash存储器的访问延迟是指在访问Flash数据时需要的等待周期数。FLASH_Latency参数是一个表示访问延迟的值,具体取决于系统时钟频率和Flash存储器的性能特性。- void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess):
该函数用于配置Flash存储器的半周期访问。FLASH_HalfCycleAccess参数用于启用或禁用Flash存储器的半周期访问模式。在半周期访问模式下,访问Flash存储器的时钟周期被减半,可以提高Flash存储器的访问速度。参数FLASH_HalfCycleAccess可以是以下值之一:
- FLASH_HalfCycleAccess_Enable:启用半周期访问模式。
- FLASH_HalfCycleAccess_Disable:禁用半周期访问模式。
- 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的擦除、编程和数据验证操作。以下是对每个步骤的解释:
- 对系统进行初始化:在main函数之前,通过调用SystemInit()函数来配置微控制器的时钟设置和其他系统初始化。可以在system_stm32f10x.c文件中重新配置SystemInit()函数的默认设置。
- 解锁Flash Bank1:调用FLASH_UnlockBank1()函数来解锁Flash Bank1的编程和擦除控制器,允许对其进行操作。
- 计算需要擦除的页数:通过计算Flash可编程区域的起始地址和结束地址之间的页数,得到需要擦除的页数。每页的大小由FLASH_PAGE_SIZE定义。
- 清除标志位:调用FLASH_ClearFlag()函数来清除Flash的待处理标志位,包括操作结束标志位(EOP)、编程错误标志位(PGERR)和写保护错误标志位(WRPRTERR)。
- 擦除Flash页:使用循环结构,调用FLASH_ErasePage()函数来逐页擦除Flash。循环会检查擦除操作的状态,并在满足条件时继续进行下一页的擦除。
- 编程Flash:使用循环结构,调用FLASH_ProgramWord()函数来逐字编程Flash。循环会检查编程操作的状态,并在满足条件时继续进行下一个地址的编程。
- 加锁Flash Bank1:调用FLASH_LockBank1()函数来锁定Flash Bank1,防止进一步的编程和擦除操作。
- 验证数据的正确性:使用循环结构,通过读取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)
return0;
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();
return0;
}
//读数据从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)
return0;
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)
{
return1;
}
return0;
}
总结
FLASH的读写在IAP或者OTA以及fatfs上有很重要的应用,这篇文章就先记录这么多,后面会考虑实现一个单片机给(F407)给另外一个单片机(F103)进行程序升级。对这一块儿感兴趣的朋友可以关注,最近关注我的朋友越来越多,我定期更新的动力也越来越足,争取尽快更新~