STM官方关于stm32F103系列的芯片有一个专门介绍flash读写的手册。STM32F100xx超值型产品闪存编程手册
通过J-Link查看自己的芯片内部的flash大小。我的大小为512k 是high-density
手册中对应的内存表为:
在stm32f10x_flash.c文件中官方为我们定义好的很多关于内部flash操作的函数。
/**
* @brief Clears the FLASH's pending flags.
* @note This function can be used for all STM32F10x devices.
* - For STM32F10X_XL devices, this function clears Bank1 or Bank2’s pending flags
* - For other devices, it clears Bank1’s pending flags.
* @param FLASH_FLAG: specifies the FLASH flags to clear.
* This parameter can be any combination of the following values:
* @arg FLASH_FLAG_PGERR: FLASH Program error flag
* @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
* @arg FLASH_FLAG_EOP: FLASH End of Operation flag
* @retval None
*/
void FLASH_ClearFlag(uint32_t FLASH_FLAG)
{
#ifdef STM32F10X_XL
/* Check the parameters */
assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;
if((FLASH_FLAG & 0x80000000) != 0x0)
{
/* Clear the flags */
FLASH->SR2 = FLASH_FLAG;
}
else
{
/* Clear the flags */
FLASH->SR = FLASH_FLAG;
}
#else
/* Check the parameters */
assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;
/* Clear the flags */
FLASH->SR = FLASH_FLAG;
#endif /* STM32F10X_XL */
}
/**
* @brief Erases a specified FLASH page.
* @note This function can be used for all STM32F10x devices.
* @param Page_Address: The page address to be erased.
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
{
FLASH_Status status = FLASH_COMPLETE;
/* Check the parameters */
assert_param(IS_FLASH_ADDRESS(Page_Address));
#ifdef STM32F10X_XL
if(Page_Address < FLASH_BANK1_END_ADDRESS)
{
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank1Operation(EraseTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to erase the page */
FLASH->CR|= CR_PER_Set;
FLASH->AR = Page_Address;
FLASH->CR|= CR_STRT_Set;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank1Operation(EraseTimeout);
/* Disable the PER Bit */
FLASH->CR &= CR_PER_Reset;
}
}
else
{
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank2Operation(EraseTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to erase the page */
FLASH->CR2|= CR_PER_Set;
FLASH->AR2 = Page_Address;
FLASH->CR2|= CR_STRT_Set;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank2Operation(EraseTimeout);
/* Disable the PER Bit */
FLASH->CR2 &= CR_PER_Reset;
}
}
#else
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to erase the page */
FLASH->CR|= CR_PER_Set; //PERÖÃ1£¬Ñ¡ÔñÒ³²Á³ý²Ù×÷
FLASH->AR = Page_Address; //Òª²Á³ýÒ³ËùÔÚµØÖ·
FLASH->CR|= CR_STRT_Set; // STRTλÖÃ1£¬Æô¶¯²Á³ý²Ù×÷
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
/* Disable the PER Bit */
FLASH->CR &= CR_PER_Reset;
}
#endif /* STM32F10X_XL */
/* Return the Erase Status */
return status;
}
/**
* @brief Programs a word at a specified address.
* @note This function can be used for all STM32F10x devices.
* @param Address: specifies the address to be programmed.
* @param Data: specifies the data to be programmed.
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
{
FLASH_Status status = FLASH_COMPLETE;
__IO uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_FLASH_ADDRESS(Address));
#ifdef STM32F10X_XL
if(Address < FLASH_BANK1_END_ADDRESS - 2)
{
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new first
half word */
FLASH->CR |= CR_PG_Set;
*(__IO uint16_t*)Address = (uint16_t)Data;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new second
half word */
tmp = Address + 2;
*(__IO uint16_t*) tmp = Data >> 16;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
/* Disable the PG Bit */
FLASH->CR &= CR_PG_Reset;
}
else
{
/* Disable the PG Bit */
FLASH->CR &= CR_PG_Reset;
}
}
}
else if(Address == (FLASH_BANK1_END_ADDRESS - 1))
{
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new first
half word */
FLASH->CR |= CR_PG_Set;
*(__IO uint16_t*)Address = (uint16_t)Data;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
/* Disable the PG Bit */
FLASH->CR &= CR_PG_Reset;
}
else
{
/* Disable the PG Bit */
FLASH->CR &= CR_PG_Reset;
}
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new second
half word */
FLASH->CR2 |= CR_PG_Set;
tmp = Address + 2;
*(__IO uint16_t*) tmp = Data >> 16;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
/* Disable the PG Bit */
FLASH->CR2 &= CR_PG_Reset;
}
else
{
/* Disable the PG Bit */
FLASH->CR2 &= CR_PG_Reset;
}
}
else
{
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new first
half word */
FLASH->CR2 |= CR_PG_Set;
*(__IO uint16_t*)Address = (uint16_t)Data;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new second
half word */
tmp = Address + 2;
*(__IO uint16_t*) tmp = Data >> 16;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
/* Disable the PG Bit */
FLASH->CR2 &= CR_PG_Reset;
}
else
{
/* Disable the PG Bit */
FLASH->CR2 &= CR_PG_Reset;
}
}
}
#else
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new first
half word */
FLASH->CR |= CR_PG_Set;
*(__IO uint16_t*)Address = (uint16_t)Data;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new second
half word */
tmp = Address + 2;
*(__IO uint16_t*) tmp = Data >> 16;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
/* Disable the PG Bit */
FLASH->CR &= CR_PG_Reset;
}
else
{
/* Disable the PG Bit */
FLASH->CR &= CR_PG_Reset;
}
}
#endif /* STM32F10X_XL */
/* Return the Program Status */
return status;
}
这里用的基地址为0x0807 F800
#include "stm32f10x_flash.h"
#define START_ADDR 0x0807F800
void FLASH_WriteByte(u32 addr,uint32_t Data)
{
FLASH_Status FLASHstatus = FLASH_COMPLETE;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
FLASHstatus=FLASH_ErasePage(START_ADDR);
if(FLASHstatus == FLASH_COMPLETE)
{
FLASHstatus = FLASH_ProgramWord(START_ADDR+addr*2, Data);
}
FLASH_Lock();
}
uint32_t FlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
{
memcpy(buffer, (void *)(START_ADDR + addr*2), length);
return length;
}