登录 免费注册 首页 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

Philips LPC2000 内部Flash用作EEPROM使用详解

作者:robinsun 栏目:ARM技术
PHILIPS LPC2000 内部FLASH用作EEPROM使用详解
折腾了几天,终于可以用FLASH来代替EEPROM了。总结一下欢迎拍砖。同时感谢北京zlg朱先生的耐心解答。
PHILIPS LPC2000 内部FLASH用作EEPROM使用详解

1.    LPC2000的FLASH简介
FLASH存储器系统包含128kB FLASH器件的16个扇区和256kB FLASH器件的17个扇区。FLASH存储器从地址0开始并向上增加。FLASH boot装载程序同时提供片内FLASH存储器的ISP和IAP编程接口。IAP、ISP和RealMonitor程序都位于boot扇区。boot扇区存在于所有的器件当中。ISP和IAP命令不允许对boot扇区执行写/擦除/运行操作。在128kB FLASH器件中只有120kB FLASH可供用户程序使用。器件共包含256kB的FLASH,其中,248kB的FLASH可供用户程序使用。Boot Block一般位于片内FLASH存储器顶端。在128kB FLASH中,它是第16个扇区(对应的扇区号是15),在256kB FLASH中,它是第18个扇区(对应的扇区号是17)。Boot Block占有的FLASH存储器扇区不能用来存放用户数据。
LPC2000系列提供在在应用中编程IAP,最终用户代码直接执行在应用编程 (IAP)对片内FLASH存储器进行擦除和编程操作。Falsh可以擦写10000次,512字节行编程时间为1ms。单扇区或整片擦除时间为400ms。
FLASH存储器在写或擦除操作过程中不可被访问。
执行FLASH写/擦除操作的IAP命令使用片内RAM顶端的32个字节空间。如果应用程序中允许IAP编程,那么用户程序不应使用该空间。
很多8位单片机中有页的概念,页为FLASH编程的最小单位,每次可以擦除和编程一个页的内容,由于页中包含的字节较少,在这种情况下把FLASH用作EEPROM灵活性会很好。而LPC2000系列没有页的概念,它只有扇区这个最小的FLASH编程单位,即用户即使是只修改一个字节,也需要首先擦除8K的FLASH
FLASH当作EEPROM的过程,其实就是对FLASH进行读-修改-写的过程。
2.    向FLASH中写数据
FLASH必须遵循选择扇区,擦除,选择扇区,写的过程,具体到程序的编写,必须先后有下面的代码:
SelSector(1,1);                           // 选择扇区1
   EraseSector(1,1);                         // 擦除扇区1
SelSector(1,1);                           // 选择扇区1
   for(i=0;i<512;i++)
      source[i]=0x41;
   RamToFLASH(0x00002000, (uint32)source, 512); // 写数据到扇区1
应用的时候需要注意下面几点:
1)如果写之前没有选择扇区,是不能正确写入的。
2)如果写之前没有擦除,写入是不正确的。
3)最少写512字节,写入的字节数应当为512 或 102440968192.
4)FLASH在擦写时不能访问,这也是IAP是要关闭中断的原因。关中断可以用下面的语句来实现:__asm{MSR     CPSR_c, #0xdf},与此对应,开中断可以下面的语句:__asm{MSR     CPSR_c, #0x5f}。
另外,经常有人问如何将一个常量的数值定义在FLASH的特定地址上,我觉得这个功能不太实用,因为每次擦除的最小单位是8K,到不如直接写数据到FLASH的一个地址,这个地址是在一个空扇区中,读和写都以这个地址为基址。由于编译后的代码是向下靠紧的,所以你可以查看一下编译后的代码量,然后选择靠上的地址做为用的变量区。如果实在想把数组定义在FLASH的特定位置好像可以用分散加载,具体可以参考zlg的FAQ的第378问。
3.    从FLASH中读数据
FLASH中读数据比较简单,可以定义一个指针变量,该指针变量指向特定的FLASH地址,例如可以写成下面的样子:
uint32 i;
uint8 * p;
p=(uint8 *)0x1C000;
for(i=0;i<400;i++)
{
     Puthexbyte(*(p++));
}
4.    FLASH的加密
代码读保护 这是Bootloader修订版1.61的特性。 代码读保护通过向FLASH地址单元0x1FC(用户FLASH扇区0)写入0x87654321(十进制表示为2271560481)来使能。地址单元0x1FC用来允许为fiq异常处理程序保留部分空间。当JTAG调试端口的代码读保护被使能时,外部存储器引导和以下ISP命令将被禁能:
&#61548;    读存储器
&#61548;    写RAM
&#61548;    运行
&#61548;    将RAM内容复制到FLASH
上述ISP命令终止时返回CODE_READ_PROTECTION_ENABLED。 代码读保护使能时,ISP擦除命令只允许擦除用户扇区的内容。这种限制是代码读保护不使能时所没有的。IAP命令不受代码读保护的影响。
采用工程模板的RelInFLASH会自动加密。
5.    采用工程模板时需要注意的地方
采用ZLG的工程模板时需要注意下面几点:
1)修改堆栈,在STARTUP.S文件中的初始化堆栈为 StackUsr-20*4
2)设置编译参数-apcs/intervork,需要注意是修改 Language Settings/ARM C Compiler/ATPS下面的。我一开始的时候不小心选择的语言设置是ARM Assembler ,结果运行程序后一写FLASH就错,大家要选准语言设置。
3)变量定义,由于一次至少写512个字节,所以跟读写操作的变量最好定义为uint32类型的,我犯的一个错误是将变量定义为uint8类型的,如下面:
uint8 i;
for(i=0;i<512;i++)
   source[i]=0x41;
RamToFLASH(0x00002000, (uint32)source, 512); // 写数据到扇区1
结果可想而知,一直在for循环中运行而跳不出来,这到给我们一个IAP不好用的假象。


2楼: >>参与讨论
ecjtu
我认为还要补充!
 在运行IAP时,是不是还应该这样啊

uint32 MAMCRBAK;
uint32 PLLCONBAK;

__asm{MSR     CPSR_c, #0xdf}
   MAMCRBAK=MAMCR;
   MAMCR=0;
   PLLCONBAK=PLLCON;
   PLLCON=0;
  PLLFEED=0xaa;
  PLLFEED=0x55;
。。。。。。。。。IAP
    MAMCR=MAMCRBAK;
     PLLCON=PLLCONBAK;
     PLLFEED=0xaa;
     PLLFEED=0x55;
__asm{MSR     CPSR_c, #0x5f}



3楼: >>参与讨论
zlgARM
版主点评:
欢迎各位热心网友将自己的心得共享出来,让大家分享。
帮助别人,也是帮助自己!

欢迎各位网友在这个帖子后面讨论和IAP相关的问题。

4楼: >>参与讨论
hhuzhang
谢谢啊, robinsun 和 ecjtu

正是不错,很多的疑问都解决了,谢谢了啊!呵呵!


5楼: >>参与讨论
zhwz12
再想问问:
FLASH里放有程序,在操作IAP时应该计算程序空间,在程序空间以外的地址上操作吗?且在分散加载后地址如何确定?在单片LPC2114系统中。
感谢!

6楼: >>参与讨论
hxj830088
请教FLASH用作EEPROM使用
我看了你发贴子“PHILIPS LPC2000 内部FLASH用作EEPROM使用详解”,还是有点疑问,还希望大虾多多指教。你能否把你写的函数,
SelSector(1,1);                           // 选择扇区1
EraseSector(1,1);                         // 擦除扇区1
RamToFLASH(0x00002000, (uint32)source, 512); // 写数据到扇区1

这三个函数体发给在下参考一下,我按照《LPC2119_2129_2194_2292_2294-01使用指南.pdf》上的C语言的例子,自己也写了一个,但是在调用函数iap_entry (ISP_Command , ISP_Result);时,程序就会死掉,不知道为什么!

7楼: >>参与讨论
hxj830088
请教FLASH用作EEPROM使用
我已经知道了那三个函数体。谢谢!

8楼: >>参与讨论
yuzhongren
RamToFLASH 这个函数怎么理解阿
我看到的书上都是 RamToFLASH(目标地址, 源地址, 512);
这里为啥是RamToFLASH(目标地址, 源数据, 512);呢
还有3.    从FLASH中读数据
FLASH中读数据比较简单,可以定义一个指针变量,该指针变量指向特定的FLASH地址,例如可以写成下面的样子:
uint32 i;
uint8 * p;
p=(uint8 *)0x1C000;
for(i=0;i<400;i++)
{
     Puthexbyte(*(p++));
}
这里的Puthexbyte(*(p++))函数我怎么找不到阿


9楼: >>参与讨论
lipyxj
LPC2131 iap例程编译出错
2.IAP演示实验例程怎么编译不过?提示连接错误

testiap.axf: Error: L6241E: startup.o(vectors) cannot use the address of '~IW' function ResetInit as the image contains 'IW' functions.
testiap.axf: Error: L6241E: startup.o(vectors) cannot use the address of '~IW' function Undefined as the image contains 'IW' functions.
testiap.axf: Error: L6241E: startup.o(vectors) cannot use the address of '~IW' function SoftwareInterrupt as the image contains 'IW' functions.
testiap.axf: Error: L6241E: startup.o(vectors) cannot use the address of '~IW' function PrefetchAbort as the image contains 'IW' functions.
testiap.axf: Error: L6241E: startup.o(vectors) cannot use the address of '~IW' function DataAbort as the image contains 'IW' functions.
testiap.axf: Error: L6241E: startup.o(vectors) cannot use the address of '~IW' function FIQ_Handler as the image contains 'IW' functions.

参与讨论
昵称:
讨论内容:
 
 
相关帖子
easyarm2200自带的演示程序为什么不运行?
提高中断服务程序速度的办法
请问:如何打开和编辑*.scf文件?
请大家帮忙看一下这个小程序
我不明白这个函数有什么用
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入


Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号