STM32 使用HAL库实现flash读写
记录使用HAL库实现向flash指定地址写入数据并读取数据的方法
总体流程可以分为擦除、写入、上锁、读取四个步骤:
1.擦除
首先弄清楚自己的疑问:为什么要擦除?不能直接写入吗?
答:stm32中flash的写入操作只能将数据位从“1”变为“0”,而无法将“0”变回“1”。比如11110000可以通过写入操作被更改为00000000,而无法被更改为11111111,而擦除操作就是先帮我们把所有为全部置1。
而擦除也是有规则的,在stm32中对flash的擦除操作的对象只能是页,这里要注意不同型号的stm32的页大小是不同的(1K或2K)。
这里附上stm32扇区分布以及对应flash地址:
选择好需要擦除的页后就可以进行擦除操作了:
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = ADDR_FLASH_SECTOR_3;
EraseInitStruct.NbPages = 1;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
{
while(1);
}
TypeErase用于选择擦除方式,按页擦除还是擦除整个flash(一般都是按页);然后选择好要擦除的起始地址和页数,起始地址一般都设置为扇区的起始地址,也可以按照自己的需要去确定。
2.写入
写入操作直接调用HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
TypeProgram可以是16位32位或者64位,根据需要设置即可;然后传入地址和需要写入的数据即可。例:向Address写入32位的数据DATA_32
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) != HAL_OK)
{
while(1);
}
3.上锁
直接调用以下代码:
HAL_FLASH_Lock();
4.读取
也很简单,直接使用指针指向地址即可
READ = *(uint32_t*)Address;
实验验证
我们定义DATA_32为0x1234ABCD,并向0x0800C000地址写入并在程序中读取数据至变量READ,debug的结果如下:
可以发现存在flash中的数据看上去好像顺序不太对,但是我们读取出来的数据是正确的。这由于flash中每个地址可以存储一个字节的数据,并且是由低位到高位存储的,所以在地址0x0800C000处存储的是DATA_32的低2位0xCD,而后面的0xAB,0x34,0x12分别存储在0x0800C001,0x0800C002,0x0800C003处。如果我们要在后面继续写入数据,那么则需要从0x0800C004开始写入。
作者:电工小王(全国可飞)