1.通过keil编译程序,得到自己代码需要单片机的flash和RAM大小
1、Code 是代码占用的空间,存在ROM(flash)里。
2、RO-data是 Read Only 只读常量的大小,如const型,存在ROM(flash)里。
3、RW-data是(Read Write) RW是可读可写变量,就是初始化时候就已经赋值了的,个存在两个地方,初始化量存在ROM/FLASH中,由于还要对其进行“写”操作 所以RAM中也要占用相应的空间。
4、ZI-data是(Zero Initialize) 没有初始化的可读写变量的大小,就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这个显然也是存在RAM中。给堆栈分配的内存也在这里。
所以本工程要求单片机
ROM(FLASH) > code+RO-data+RW-data
RAM > RW-data+ZI-data
2.在程序中调整堆栈的大小
对于堆栈大小的调整
在程序中调用堆栈,对堆栈大小的挑战才是有意义的,例如在程序中没有申请动态内存,那么不论给堆多大的内存,在程序编译时都不会占用单片机flash。可以尝试,分别在用/不用 动态内存时调整堆给堆分配的空间,编译后观察ZI-data大小的变化。栈区方法相同,可以尝试不定义任何形参和 局部变量观察ZI-data大小的变化。
3.单片机片内flash的使用
我们说的flash就是上图中程序的主存储快,stm32c8,有64kB,stm32cB,有128kB,在生产时原料相同生产方法相同,stm32cB中质量不好的按stm32c8来卖。在出售前厂家会测试stm32cB的128KB存储空间,只测试stm32c8的前64KB存储空间,所以大多数stm32c8单片机也可以和stm32cb一样使用128kb的flash,只是厂家只保证前64KB的存储空间不会出问题,后面的空间厂家也没测,能不能用都靠运气。但是生产工艺一直在进步,所以大多数stm32c8单片机后面没测试的存储空间也能使用。
FLASH擦除是按照扇区擦的,所以这个很重要,在工程中全局搜索 FLASH_PAGE_SIZE 宏就可以查看该芯片的页(扇区)大小,改宏在 stm32xxx_hal_flash.h中有定义
F1和F4系列的芯片FLASH在擦除后会是0xFFFFFFFF,而L1系列的芯片FLASH在擦除后是0x00000000!!!
L1芯片内部FLASH编程速度比F1慢50倍!!!所以在使用L1芯片写入数据时相对于F1慢是正常的
STM32闪存的编程每次必须写入16位,任何不是半字的操作都会造成错误。
#include "FLSH.h"
uint16_t EEPROM_data[20] = {0} ; //flash等待存储的数据
void WriteFlsh2B( uint16_t page, uint16_t * EEPROM_Data,uint16_t flash_byte)
{
uint32_t EEPROM_ADD = 0x08000000 + page * FLASH_PAGE_SIZE ;
//1、解锁FLASH
HAL_FLASH_Unlock();
//2、擦除FLASH
//初始化FLASH_EraseInitTypeDef
FLASH_EraseInitTypeDef f;
f.TypeErase = FLASH_TYPEERASE_PAGES;
f.PageAddress = EEPROM_ADD;
f.NbPages = 1;
//设置PageError
uint32_t PageError = 0;
//调用擦除函数
HAL_FLASHEx_Erase(&f, &PageError);
for(short fo_i = 0 ; fo_i < flash_byte/2 ; fo_i ++)
{
//3、对FLASH烧写
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, EEPROM_ADD+fo_i*2 , *(EEPROM_Data+fo_i ));
}
//4、锁住FLASH
HAL_FLASH_Lock();
}
//FLASH读取数据测试
void ReadFlash2B( uint16_t page, uint16_t * EEPROM_Data,uint16_t flash_byte)
{
uint32_t EEPROM_ADD = 0x08000000 + page * FLASH_PAGE_SIZE ;
for(short fo_i = 0 ; fo_i < flash_byte/2 ; fo_i ++)
{
//3、对FLASH烧写
*(EEPROM_Data+fo_i ) = *(__IO uint16_t*)(EEPROM_ADD+fo_i *2 );
}
}
链接:stm32单片机内部flash闪存源码 百度云提取码 1111
参考了以下两个PDF