在一些应用中,经常需要存储一些信息,掉电后可以保存。当然,可以外挂eeprom,flash也可以。不过呢,占用空间,资源,增加成本,设计上的难度也会增加(况且,460的flash这么大,分出来一点作为数据存储)。更具hc32f460的资料,有如下信息:
1 flash擦除的最小单元为8K bytes,最小编程单元4 bytes;
2 flash在擦除和编程期间,从flash读取的数值是不确定的(很关键)。
根据这些信息,设计思路如下:
1 选择16K的flash空间作为数据存储,两个扇区轮流使用,在擦除一个扇区完成时,数据没有写入成功,即使断电还有最近一次的数据,避免数据测地丢失的状况;
2 执行写入和擦除操作时,不能从flash执行程序,因此需要将部分程序在ram中运行,还必须关中断(自己想吧)。
下面介绍实现的具体方法(Keil开发环境):
在ram中运行程序
首先必须要解决如何在ram中运行代码,在keil中使编译的代码在ram中执行。
第一步:制作scatter文件
下面是我是用的,*(.RAM_CODE)这一句是重点,后面用到。
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00000000 0x00080000 { ; load region size_region
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x1FFF8000 0x0002F000 { ; RW data
*(.RAM_CODE)
.ANY (+RW +ZI)
}
}
第二步:使用预处理指令#pragma,使代码在ram中运行。
华大直接把flash相关的函数都封装好了,但是需要修改hc32f460_efm.c,使其能在ram运行。
将需要在ram中运行的程序开始和结束的部分加上两句话,如下:
这样,函数EFM_ErasePgmCmd就会在ram中运行了。要把所有擦除和编程时调用的函数都这样处理。
当然,也可以直接把文件hc32f460_efm.c开始和结束加上这两句话,不用麻烦了,就是多占用了ram。根据自己的情况决定。
如何擦除一个扇区和编程,自己看看就行了,华大把函数都写好了。
存储数据思路及实现
储存数据的flash地址,自己定义,一定要8K对齐,假设每次存储的数据为0x100个数据。轮流写入,例如0x08100,0x08200,0x08300....当两个扇区都用完了,需要擦除上一个扇区,以此类推。
存储为0x100个数据,建议包含这些信息:校验[推荐crc16/32],存储序号[每次+1],数据有效标识等。
如何判断哪个数据是有可用的?
1 根据数据的有效标识,以及校验,判断数据是否正确;
2 根据存储序号的大小,选择序号最大的记录作为最后的记录。同时,如果需要更新,从此开始。
如果正在写入,突然断电,那么上次记录还在;如果正在擦除完一个扇区,又断电了,上次的数据还在。(杠精,怎么总是在关键时停电?)
这样是不是很安全了?
这篇文章是个人的使用心得,希望各位能指点,共同提高。