Flash存储器的在线擦写方法

3.64K flash程序存储区

C8051f020单片机的程序存储器包括64K字节的FLASH。该存储器以512字节为一个扇区,可以在系统编程,且不需要特别的外部编程电压。从0xFE00~0xFFFF的512个字节被保留,由工厂使用。还有一个位于地址0x10000~0x1007F的128字节的扇区,该扇区可以做为一个小的软件常数表使用。

除了有512个保留字节不能使用之外,还有两个字节的安全锁定字节以保护FLASH。读锁定字节的每一为控制一个大小为8K的存储区域,对应关系如图3所示。写/擦除锁定字节也一样,每一位控制一个8K的存储区域。

图3



4.FLASH操作

用软件对Flash 编程的过程中应该注意如下几点:

①Flash 存储器用MOVCA, @A+DPTR 指令读取;

②Flash 存储器用MOVX@DPTR,A 指令写入;

③Flash 页以512 字节分界0200h, 0400h, 依此类推;

④Flash 写操作只能写入0,因此在写一个Flash 字节之前包含该字节的页必须首先被擦除,使该页中 的所有位都为1;

⑤在进行Flash 擦除之前,必须将PSWE 和PSEE 置1;

⑥Flash 页的擦除操作是将PSWE 和PSEE 置1,并向该页512 字节中的任一字节进行写操作;

⑦含有读锁定字节和写/ 擦除锁定字节的Flash 页不能由用户软件擦除,但是该页可以由用户软件写入,该页只能通过JTAG 接口擦除。

用软件对Flash 进行写操作时步骤如下:

①为了避免对Flash 存储器的误写,在PSWE 为1期间禁止中断;

②置位FLWE(FLSCL.0) ,以允许Flash 存储器的写/ 擦除操作;

③置位PSEE(PSCTL.1) 以允许扇区擦除;

④用MOVX 指令向待擦除扇区的任何一个地址写入一个数据字节;

⑤清除PSEE ,以禁止Flash 扇区擦除;

⑥置位PSWE(PSCTL.0) ,以允许写入;

⑦用MOVX 指令向刚擦除的扇区中所期望的地址写入数据字节,并重复该步直到结束(写入的字节数可以是一个字节到整个扇区的任何值);

⑧清除PSWE ,以禁止Flash 写;

⑨ 重新允许中断。



为了更改C8051f020中FLASF存储区中一个多字节数据集中的某一个字节,整个数据集必须首先被保存到一个临时的存储区;然后将扇区擦除,更新数据;最后将数据集写回到原扇区。128字节的扇区规模数据更新更加容易,可以使用内部数据RAM做为临时存储区,而不浪费程序存储空间。由于FLASH读操作是用MOVC指令实现的,因此用于读操作的FLASH指针必须是code类型。

在对FLASH存储器进行写操作前,必须将其进行擦除。由于FLASH写操作是用MOVX指令实现的,所以用于写或擦除的FLASH指针必须是xdata类型

本文内容根据一下资料整理



1.《C8051F020/1/2/3混合信号ISP FLASH维控制器数据手册》 潘琢金译

2.Silicon Laboratories Application notes

3.C8051F020中Flash存储器的在线擦写方法 韩红芳 孙守昌
C8050F02x单片机FLASH读写(Keil C编程心得) 收藏
在单片机编程中往往需要长期保存某些数据,尤其是一些配置参数,这样掉电后这些数据仍然还在。于是就开始了FLASH读写的编程,经过了一天多的努力,终于把FLASH的读写调通了。主要有三点:

一、读FLASH

要用MOVC指令才能读FLASH,这个比较简单。

二、写FLASH

严格按照下面的流程即可完成写操作

1. 禁止中断。

2. 置位FLWE(FLSCL.0),以允许由用户软件写/擦除FLASH。

3. 置位PSEE(PSCTL.1),以允许FLASH 扇区擦除。

4. 置位PSWE(PSCTL.0),以允许FLASH 写。

5. 用MOVX 指令向待擦除扇区内的任何一个地址写入一个数据字节。

6. 清除PSEE 以禁止FLASH 扇区擦除。

7. 用MOVX 指令向刚擦除的扇区中所希望的地址写入数据字节。重复该步直到所有字

节都已写入(目标扇区内)。

8. 清除PSWE 以禁止FLASH 写,使MOVX 操作指向XRAM 数据空间。

9. 重新允许中断。

三、指针

C语言里可没有MOVC和MOVX,为了实现这两个指令,需要定义指针。根据Keil C的语法可知,将变量(指针)声明为code型和xdata型时相应的赋值操作即对应于MOVC和MOVX。当然,如果用汇编语言就没这个问题了。

下面给出一个最简单的例子(在C8051F020及Keil uV2下调试通过,程序的功能是每次复位后P1口的输出状态为上次的取反)

#include

unsigned char test; //保存输出状态

//在FLASH中保存输出状态

/*For reading*/

unsigned char code test_c _at_ 0xCF20;

/*For writing*/

unsigned char xdata test_x _at_ 0xCF20;

void ReadState()

{ //从FLASH中读取信号输出状态与PWM值

test=test_c;

}

void StoreState()

{ //此函数不可频繁调用,对FLASH有损(寿命一般为100000次)

//在FLASH中写入输出状态

EA=0; //为了避免对FLASH的误写,需禁止中断

FLSCL = 0x81; //允许由用户软件写/擦除FLASH

PSCTL = 0x03; //允许FLASH扇区擦除及FLASH写

test_x=0; //擦除扇区

PSCTL &= 0xFD; //清除PSEE 以禁止FLASH 扇区擦除

test_x=~test; //输出状态按位取反后写入FLASH

PSCTL = 0; //禁止FLASH写

// FLSCL = 0x80; //disable FLASH writes

EA=1; //重新允许中断

}

void main(void)

{ WDTCN=0xde;

WDTCN=0xad;

//Add initialization code here

P1MDOUT=0xff;

ReadState();

P1=test;

StoreState();

while(1);

}

相关文档
最新文档