| |
最近要利用LPC915的flash掉电存储数据,查看了使用指南发现资料很全,参考代码都有,但使用了之后才发现在实际应用中存在问题。在网上查找资料,没有发现相关内容,找到了ZLG的技术支持,也没有把问题解释清楚。所有在这里贴出来。
使用指南上给出的代码如下:
bit PGM_USER (unsigned char page_hi , unsigned char page_lo )
{
# define LOAD 0x00 // 清除页寄存器,使能装载
# define EP 0x68 // 擦除和编程页
unsigned char i; // 循环次数
FMCON = LOAD; // 装载命令,清除页寄存器
FMADRH = page_hi; //
FMADRL = page_lo; // 页地址写入地址寄存器
for ( i= 0 ; i <64 ; i=i+1 )
{
FMDATA = dbytes [i] ;
}
FMCON = EP; // 擦除和编程页命令
Fm_stat = FMCON; // 读结果状态
if ( ( Fm_stat & 0xF ) ! =0 ) prog_fail = 1 ; else prog_fail = 0;
return (prog_fail);
}
将该代码应用到自己的程序中后,发现几乎都擦写不了flash(前面偶尔擦写成功过几次),起初以为是相关的写保护或写使能的影响,但排除后还是擦写不了。仔细查看使用指南后,发现以下信息:
“如果在擦除/编程周期内有中断产生,擦除/编程操作被终止,FMCON 的OI 标志(操作被中断)置位。如果某一应用允许在擦除-编程过程中产生中断,可通过用户程序在每次擦除-编程操作后检查OI 标志(FMCON.0)来判断操作是否被终止。一旦擦除-编程操作被终止,用户程序需要重复整个过程来起动页寄存器的装载。”
原来很可能是因为中断的影响,所以在擦写进入空闲状态前,将中断允许清0,待退出空闲状态后恢复中断允许。修改后自己的代码如下:
bit Flash_WriteByte(uint addr, uchar dat)
{
uchar FmState;
FMCON = LOAD; // 设置加载数据命令
FMADRH = addr>>8; // 设置写入地址
FMADRL = addr&0xFF;
FMDATA = dat; // 写入数据
EA = 0;
FMCON = ERS_PROG; // 擦除编程
/*空闲状态*/
EA = 1;
FmState = FMCON;
if( (FmState&0x0F)!=0x00 )
return(0);
else
return(1);/**/
}
如此就可以保证可靠的擦写flash了!
因为在实际应用中绝大多数都会使用到中断,所以,在需要应用擦写flash功能时,都需要注意这一点。