|
我们使用最多的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);
复制代码 最后我们通过串口查看输出情况:
可以看见,成功读出了数值。
|
|