网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
1、STM32L051内部存储模块地址范围
开始找到F103的FLASH图复习了一遍,然后L051C8T6,64KB的flash, 然后我惊奇的发现还有2KB的EEPROM。
发现L051系列的地址与F103完全不同,F103的flash每页的长度有1KB(小容量<=64KB)和2KB(大容量128KB起)查看各种资料,
查了2个小时,
还是不知道L051的flash 每页长度是 128Byte 还是256Byte????????????????????????
还是请教了一下大佬,发现直接在J-Flash中可以找到答案,先上个F103的图:
然后来看个L051的图:
图中64KB 的flash 和2KB的EEPROM都能都明显的看出地址,flash 512页,每页128bytes,EEPROM只有4页,每页512bytes.知道了基本的地址,就可以操作起来了。
最后还需要确定的一点事,最小擦除单元是128bytes,还是256bytes,按以前的认知,删除是按照一个Sector擦除的,也就是128bytes,但是我查看了一些网上的例子和资料,有的是说256bytes,所以后面需要自己确定一下。
其实在HAL库的 stm32l0xx_hal_flash.h 文件中有过 FLASH_PAGE_SIZE 的定义,就是128bytes :
#define FLASH\_SIZE (uint32\_t)((\*((uint32\_t \*)FLASHSIZE\_BASE)&0xFFFF) \* 1024U)
#define FLASH\_PAGE\_SIZE ((uint32\_t)128U) /\*!< FLASH Page Size in bytes \*/
对于flash的操作,有一些基础知识补充一下:
Read interface organized by word, half-word or byte in every area
• Programming in the Flash memory performed by word or half-page
• Programming in the Option bytes area performed by word
• Programming in the data EEPROM performed by word, half-word or byte
• Erase operation performed by page (in Flash memory, data EEPROM and Option
bytes)
STM32L051写Flash必须字,读 字节、半字、字都支持。(这句话也是错误的,这是以前哪里看到的,实际测试写可以根据字,半字,字节来写)。
一些基本概念:
定义字是根据处理器的特性决定的。
首先ARM是32bit处理器,所以它的字是32bit的。半字自然就是16bit;
字节不论在哪个CPU上都是8bit。
1 Byte = 8 bits(即 1B=8b)
1 KB = 1024 Bytes
Bit意为“位”或“比特”,是计算机运算的基础,属于二进制的范畴;
Byte意为“字节”,是计算机文件大小的基本计算单位;
2、读写函数的设计
HAL库中肯定是有对flash和EEPROM进行操作的函数,我们这里新建一个stml0_flash.c 和stml0_flash.h 函数分别放在对应位置,进行自己的函数设计。
库中Flash与EEPROM的函数看样子是分别放在
stm32l0xx_hal_flash.c
和 stm32l0xx_hal_flash_ex.c
中的,我们先使用EEPROM,因为提供EEPROM,就是让用户可以保存一些掉电后的数据的嘛。
测试完EEPROM,再去测试下flash,因为怕有时候数据不够放……
2.1 读取函数
//读取指定地址的半字(16位数据)
uint16\_t FLASH\_ReadHalfWord(uint32\_t address)
{
return \*(__IO uint16\_t\*)address;
}
//读取指定地址的全字(32位数据)
uint32\_t FLASH\_ReadWord(uint32\_t address)
{
return \*(__IO uint32\_t\*)address;
}
简单测试一下:
u32 read_data1=0XFFFFFFFF;
u32 read_data2=0XFFFFFFFF;
...
read_data1 = FLASH\_ReadWord(DATA_EEPROM_START_ADDR);
printf("the DATA\_EEPROM\_START\_ADDR is: 0x %x \r\n",read_data1);
read_data2 = FLASH\_ReadWord(DATA_EEPROM_START_ADDR + EEPROM_PAGE_SIZE);
printf("the EEPROM sceond page test data is: 0x %x \r\n",read_data2);
没有写入数据读取的值应该都是0。
2.2 EEPROM写函数
对EEPROM的写函数:
stm32l0xx_hal_flash_ex.h中函数如下:
HAL_StatusTypeDef HAL\_FLASHEx\_DATAEEPROM\_Unlock(void);
HAL_StatusTypeDef HAL\_FLASHEx\_DATAEEPROM\_Lock(void);
HAL_StatusTypeDef HAL\_FLASHEx\_DATAEEPROM\_Erase(uint32\_t Address);
HAL_StatusTypeDef HAL\_FLASHEx\_DATAEEPROM\_Program(uint32\_t TypeProgram, uint32\_t Address, uint32\_t Data);
通过函数看来,可以直接用,但是这里有一个问题
需要测试一下,擦除是否会擦除整个扇区