编译环境:我用的是(Keil)MDK4.7.2
stm32库版别:我用的是3.5.0
一、本文不对FLASH的基础知识做具体的介绍,不懂得当地请查阅有关材料。
对STM32 内部FLASH进行编程操作,需求遵从以下流程:
FLASH解锁
铲除相关标志位
擦除FLASH(先擦除后写入的原因是为了工业上制造便利,即物理完结便利)
写入FLASH
确定FLASH
实例:
#define FLASH_PAGE_SIZE ((uint16_t)0x400) //假如一页为1K巨细
#define WRITE_START_ADDR ((uint32_t)0x08008000)//写入的开端地址
#define WRITE_END_ADDR ((uint32_t)0x0800C000)//完毕地址
uint32_t EraseCounter = 0x00, Address = 0x00;//擦除计数,写入地址
uint32_t Data = 0x3210ABCD;//要写入的数据
uint32_t NbrOfPage = 0x00;//记载要擦除的页数
volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;/*FLASH擦除完结标志*/
void main()
{
/*解锁FLASH*/
FLASH_Unlock();
/*核算需求擦除FLASH页的个数 */
NbrOfPage = (WRITE_END_ADDR – WRITE_START_ADDR) / FLASH_PAGE_SIZE;
/* 铲除一切挂起标志位 */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
/* 擦除FLASH 页*/
for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
}
/* 写入FLASH*/
Address = WRITE_START_ADDR;
while((Address < WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))
{
FLASHStatus = FLASH_ProgramWord(Address, Data);
Address = Address + 4;
}
/* 确定FLASH*/
FLASH_Lock();
}
二、FLASH 擦除(以及避免误擦除程序代码)
1、擦除函数
FLASH_Status FLASH_ErasePage(u32 Page_Address)只需()里边的数是flash第xx页中对应的任何一个地址!便是擦除xx页全部内容!
避免误擦除有用程序代码的办法
办法一:首先要核算程序代码有多少,把FLASH存取地址设置在程序代码以外的当地,这样就不会损坏用户程序。原则上从0x0800 0000 + 0x1000 今后的FLASH空间都能够作为存储运用。假如代码量占了 0x3000, 那么存储在 0x0800 0000+ 0x4000 今后的空间就不会损坏程序了。
办法二:先在程序中界说一个const 类型的常量数组,并指定其存储方位(便利找到写入、读取方位),这样编译器就会分配你指定的空间将常量数组存入FLASH中。当你做擦除。读写操作时,只需在这个常量数组地点的地址规模就好。
const uint8_t table[10]__at(0x08010000)= {0x55} ;
MDK3.03A开端就支撑关键字 __at() 。
需求加#include
办法三:在程序中界说一个const 类型的常量数组,无需指定其存储方位。只需界说一个32位的变量存储这个数组的FLASH区地址就行。
uint32_t address;//STM32的地址是32位的
const uint8_t imageBuffer[1024] = {0,1,2,3,4,5,6,7};
address = (uint32_t) imageBuffer;/*用强制类型转化的办法,能够把FLASH中存储的imageBuffer[1024]的地址读到RAM中的变量address 里,便利找到写入、读取方位*/
办法四:使用写保护的办法(没研讨理解)