STM32L051 测试第 4 课,掉电数据保存的测试。
..修改文中以前的问题,增加后续问题说明(数据存储大小端模式)                       
..增加后续问题2.4.3(STM32L071RBT6 EEPROM读写全字问题)                           
..更新一下STM32L071 EEPROM读写全字问题最后解决说明                               
1、STM32L051内部存储模块地址范围
2、读写函数的设计
2.1 读取函数
2.2  EEPROM写函数
2.3  Flash写函数
2.4 读写EEPROM的后续问题
总结
本文测试 L051 flash的读写,用来处理以后应用中的掉电数据保存。
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 byt
es)
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);
stm32怎么使用printfprintf("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);
通过函数看来,可以直接用,但是这里有一个问题
需要测试一下,擦除是否会擦除整个扇区,有待验证!!
答:EEPROM的擦除可以直接擦除某个地址的字,不会擦除整个片区
EEPROM的操作相对Flash,比较简单,直接使用HAL库中的函数即可完成
HAL_FLASHEx_DATAEEPROM_Unlock();
HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, DATA_EEPROM_START_ADDR, write_data1);
HAL_FLASHEx_DATAEEPROM_Lock();
...
if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){
        printf(" K1 150ms button!,EEPROM_Erase test\r\n");
        HAL_FLASHEx_DATAEEPROM_Unlock();
        HAL_FLASHEx_DATAEEPROM_Erase(DATA_EEPROM_START_ADDR+4);
        HAL_FLASHEx_DATAEEPROM_Lock();

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。