赞
踩
之前的文章中介绍过STM32F0列的内部Flash读写《STM32CubeMX之内部Flash读写》,F1系列的也是一样的。而F4系列的单片机与F0和F1略有不同,HAL库对应的函数也不同,今天来简单介绍一下。
以TM32F429IGT6单片机为例,其内部Flash起始地址是:0x08000000,大小是0x00100000。
先看一下其内部Flash的Sector划分:
我们需要关心的只有Main memory。可以看到,每个Sector的大小不一样,前128K被分为了4个16K和1个64K,后面每个Sector都是128K。而F1系列的每个Sector大小相同都是1K或2K。
我们知道,Flash在写的时候必须先整块Sector擦除才能写入。F0/F1系列的直接调用函数擦除指定地址的Sector就行,比如我们需要擦除0x08000000起始地址的Sector,程序如下:
- FLASH_EraseInitTypeDef f;
-
-
- f.TypeErase = FLASH_TYPEERASE_PAGES;
- f.PageAddress = 0x08000000;
- f.NbPages = 1;
- PageError = 0;
-
-
- HAL_FLASH_Unlock();
- HAL_FLASHEx_Erase(&f, &PageError);
而F4系列HAL库的Flash擦除函数,其形参为Sector的编号而非实际地址。比如我们需要擦除0x08000000起始地址的Sector,需要先获取Sector的编号0,作为函数的形参再调用擦除函数,程序如下:
- Sect = 0;
- FLASH_Erase_Sector(sect,FLASH_VOLTAGE_RANGE_3);
因此,我们需要编写一个函数用于获取Sector的编号,程序如下:
- uint32_t sectStartAddr[13]=
- {
- 0x08000000,//0
- 0x08004000,//1
- 0x08008000,//2
- 0x0800c000,//3
- 0x08010000,//4
- 0x08020000,//5
- 0x08040000,//6
- 0x08060000,//7
- 0x08080000,//8
- 0x080a0000,//9
- 0x080c0000,//10
- 0x080e0000,//11
- 0x08100000
- };
- //获取Sector的编号
- int GetSectorFromAddress(uint32_t address)
- {
- int sect;
-
-
- if( address < 0x08000000 || address > 0x080FFFFF )
- return -1;
-
-
- for( int i=0; i<12; i++ )
- {
- if( address >= sectStartAddr[i] && address < sectStartAddr[i+1] )
- {
- sect = i;
- break;
- }
- }
- return sect;
- }

则擦除0x08000000地址Sector的程序如下:
- sect = GetSectorFromAddress(0x08000000);
- FLASH_Erase_Sector(sect,FLASH_VOLTAGE_RANGE_3);
写入函数与F0/F1系列的一样,直接调用HAL库函数即可,函数形参的地址为绝对地址:
- startAddr = 0x08000000;
- endAddr = 0x08000020;
- for(i = startAddr; i < endAddr; i += 4)
- {
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, i, *data++);
- }
读取函数也是一样的,直接读取指定地址即可:
uint32_t data = *(uint32_t *)(0x08000000);
当然,擦除写入之前不要忘了解锁和上锁的操作:
- HAL_FLASH_Unlock();//解锁flash
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
- //......擦除写入操作
- HAL_FLASH_Lock();
内部Flash读写可以用于存储一些参数,也是实现IAP程序升级的关键,下一篇文章将介绍通过U盘实现单片机程序升级。
推荐阅读:
欢迎关注公众号"嵌入式技术开发",大家可以后台给我留言沟通交流。如果觉得该公众号对你有所帮助,也欢迎推荐分享给其他人。
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。