产品资料搜索:

最新产品展示

  • LDM8035接触式模块
    接触式IC卡读写模块 支持SLE4442/4428 小型化 低功耗 方便使用
  • LDM522-MINI射频模块
    体积小(1.9cm*1.4cm) ISO14443-A以及Mifare, Ultrlight&EV1等的低功耗模块
  • LDM-A3射频读卡器
    支持ISO14443A/B 二代证ID 低功耗 免驱
  • LDM523射频读卡模块
    支持iso14443A/B 韦根接口 二代证ID
  • LPC2000 内部flash用作EEPROM使用详解

    2009-4-26

    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 或 1024 或 4096 或 8192.
    4)Flash在擦写时不能访问,这也是IAP是要关闭中断的原因。关中断可以用下面的语句来实现:__asm{MSR     CPSR_c, #0xdf},与此对应,开中断可以下面的语句:__asm{MSR     CPSR_c, #0x5f}。
    另外,经常有人问如何将一个常量的数值定义在Flash的特定地址上,我觉得这个功能不太实用,因为每次擦除的最小单位是8K,到不如直接写数据到Flash的一个地址,这个地址是在一个空扇区中,读和写都以这个地址为基址。由于编译后的代码是向下靠紧的,所以你可以查看一下编译后的代码量,然后选择靠上的地址做为用的变量区。如果实在想把数组定义在Flash的特定位置好像可以用分散加载。
    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不好用的假象

    © 2014 龙达科技有限公司版权所有,所有内容未经许可严禁复制