mmuyu 发表于 2023-8-31 21:56:11

读写stm32内部flash

    我们使用最多的stm32f103c8t6系列,内部拥有64kb的储存空间拥有存放程序代码。64kb,一般来说是比较充足的,小的项目通常都在20kb左右,如果算上ota的话,在小项目上也能余下一点小空间,因此剩下的空间可以利用来存放一些数据。
通过stm提供的闪存编程手册,我们可以知道,flash被划分成每个1k大小的页。



因此,我们可以使用一个页来存放数据,1个页1k,假如我们存放uint16的话,那么理想情况可以存放512个数据。


接下来我们看看如何写入和读取数据。

首先,要写入数据我们需要先对页进行擦除,最小支持擦除一页。

我们以58页为例,58页地址=52x1024+0x08000000(启动地址) 因此是0x0800e800,擦除过程可以参考手册

其中,解锁过程和等待bus寄存器已经被hal库整合起来,我们直接使用hal提供的代码即可,只需要解除写操作,验证擦除成功,重新锁起flash即可,代码如下。



擦除完成后,我们就可以写入了,这里准备了一个uint16用于测试。



在代码里,先解除写保护,使用半字的模式写入uint16 对于stm32 一个完整的字是4字节,因此半字为2字节。我们最小能写入和擦除的也是半字。

写入完成后,我们就可以读取了,hal没有帮我们实现读取的函数,不过读取的函数还是很简单的,只需要从特定的内存地址读取即可。加上__IO是为了防止编译器优化,否则有可能在写入数据后重新读取到的是缓存数据。

uint16_t flash_read(void){
                return*(__IO uint16_t*)0x0800e800;
}

main的完整代码:

flash_page58_erase();
                uint16_t test = 12345;
                HAL_FLASH_Unlock();
                HAL_StatusTypeDef flash_status=HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,0x0800e800,test);
                HAL_FLASH_Lock();
                if(flash_status!=HAL_OK){
                        printf("flash_write_error\n");
                }else{
                        printf("write page61\n");
                }
                uint16_t temp=flash_read();
                printf("read flash: %d\n",temp);最后我们通过串口查看输出情况:



可以看见,成功读出了数值。

页: [1]
查看完整版本: 读写stm32内部flash