1  /  1  页   1 跳转 查看:544

PIC24F读写FLASH功能

PIC24F读写FLASH功能

Microchip的官方资料里,PIC24F系列RTSP对FLASH的读写存在问题。

NVMCON中NVMOP操作,只有_NVMOP = 0001和0010两个操作可测试通过,另外两个操作在SIM仿真的时候报错。

我写了几段代码,主要是为了保存系统参数的,只对FLASH的24位中LB UB两个字节进行操作。
因为asm()经过编译产生的汇编指令会对WREG0进行覆盖而造成FlashAddr的值被Dest地址覆盖,所以FlashErasePage和FlashWriteData两个函数中又另外定义了temp16,保证执行tblrdl和tblrdh指令时WREG0内是FlashAddr的内容。

void FlashReadData(UINT16 FlashAddr,UINT8 *Dest,UINT8 DataNum)
{
        TBLPAG = 0x00;
        for(;DataNum>0;DataNum--){
                asm("tblrdl.b [%1],%0":"=r"(*Dest):"r"(FlashAddr));
                Dest++;
                asm("tblrdh.b [%1],%0":"=r"(*Dest):"r"(FlashAddr));
                Dest++;
                FlashAddr += 2;
        }
}

void FlashErasePage(UINT16 FlashAddr)
{
        UINT16 temp16;

        NVMCON = FLASHERASEPAGE;
        TBLPAG = 0x00;
        temp16 = FlashAddr;
        asm("tblwtl w0,[w0]");

        NVMKEY = 0x55;
        NVMKEY = 0xaa;
        _WR = 1;
        Nop();
        Nop();
}

void FlashWriteData(UINT16 FlashAddr,UINT8 *Dest,UINT8 DataNum)
{
        UINT16 temp16;

        NVMCON = FLASHERASEPAGE;
        TBLPAG = 0x00;
        temp16 = FlashAddr;
        asm("tblwtl w0,[w0]");

        NVMKEY = 0x55;
        NVMKEY = 0xaa;
        _WR = 1;
        Nop();
        Nop();

        NVMCON = FLASHPROGLINE;
        TBLPAG = 0x00;
        for(;DataNum>0;DataNum--){
                asm("tblwtl.b %0,[%1]"::"r"(*Dest),"d"(FlashAddr));
                Dest++;
                asm("tblwth.b %0,[%1]"::"r"(*Dest),"d"(FlashAddr));
                Dest++;
                FlashAddr += 2;
        }

        NVMKEY = 0x55;
        NVMKEY = 0xaa;
        _WR = 1;
        Nop();
        Nop();
}

程序验证过功能正常,有没有大虾帮忙精简一下。
最后编辑louis_chen 最后编辑于 2008-09-30 19:06:47
 

回复: PIC24F读写FLASH功能

在LZ的基础上,修改成支持大于64K地址的读写FLASH功能
#include "p24Fxxxx.h"

#define UINT32 unsigned long
#define UINT16 unsigned int
#define UINT8  unsigned char

#define FLASH_ERASEPAGE 0x4042
#define FLASH_PROGLINE  0x4001

void FlashReadData(UINT32 FlashAddr,UINT8 *Dest,UINT8 DataNum)
{
        TBLPAG = ((FlashAddr & 0x7F0000)>>16);
        FlashAddr = (FlashAddr & 0x00FFFF);
          for(;DataNum>0;DataNum-=2)
        {
            asm("tblrdl.b [%1],%0":"=r"(*Dest):"r"(FlashAddr));
                Dest++;
              asm("tblrdh.b [%1],%0":"=r"(*Dest):"r"(FlashAddr));
              Dest++;
              FlashAddr += 2;
        }
}

void FlashErasePage(UINT32 FlashAddr)
{       
          NVMCON = FLASH_ERASEPAGE;
         
        TBLPAG = ((FlashAddr & 0x7F0000)>>16);
        FlashAddr = (FlashAddr & 0x00FFFF);
                asm("tblwtl w0,[w0]");

          NVMKEY = 0x55;
          NVMKEY = 0xaa;
          _WR = 1;
          Nop();
          Nop();
}

void FlashWriteData(UINT32 FlashAddr,UINT8 *Dest,UINT8 DataNum)
{
                FlashErasePage(FlashAddr);

          NVMCON = FLASH_PROGLINE;
         
          TBLPAG = ((FlashAddr & 0x7F0000)>>16);
        FlashAddr = (FlashAddr & 0x00FFFF);
         
          for(;DataNum>0;DataNum-=2)
        {       
            asm("tblwtl.b %0,[%1]"::"r"(*Dest),"d"(FlashAddr));
            Dest++;
            asm("tblwth.b %0,[%1]"::"r"(*Dest),"d"(FlashAddr));
            Dest++;
          FlashAddr += 2;
          }
          NVMKEY = 0x55;
                NVMKEY = 0xaa;
                _WR = 1;
          Nop();
          Nop();
}
 
1  /  1  页   1 跳转

版权所有 贝能国际  Burnon国际  Sitemap

Powered by Discuz!NT 2.1.202    Copyright © 2001-2009 Comsenz Inc.
Processed in 0.0156255 second(s) , 4 queries. 闽ICP备05003850号
返顶部