无法写入闪存程序存储器(PIC18F4620)

时间:2014-08-13 07:54:05

标签: c++ pic18 flash-memory

我试图将一些数据写入闪存程序存储器。我阅读了数据表并按照步骤操作。我还编辑了rom数组的链接描述文件。下面是我在C中尝试写入地址0xFF00的闪存程序存储器序列的代码。

            TBLPTR = 0x3fc000;           // start of erase seq
            EECON1 = 0b10010100;         //EEPGD = 1, FREE = 1, WREN = 1,
            INTCONbits.GIE = 0;
            EECON2 = 0x55;
            EECON2 = 0xAA;
            EECON1bits.WR = 1;           
            INTCONbits.GIE = 1;
            EECON1bits.WREN = 0;    

            TBLPTRU = 0x3F;              // start of write seq
            TBLPTRH = 0xC0;
            TBLPTRL = 0x00;
            for(i = 0; i<64; i++)
            {

                TABLAT = dispData0[i];
                TBLPTRL = i;
            }   
            EECON1 = 0b10000100;         // EEPGD = 1, WREN = 1
            INTCONbits.GIE = 0;
            EECON2 = 0x55;
            EECON2 = 0xAA;
            EECON1bits.WR = 1;
            INTCONbits.GIE = 1;
            EECON1bits.WREN = 0;

            TBLPTR = 0x00ff00;
            dispData3[0] = TABLAT;
            TBLPTR++;
            dispData3[1] = TABLAT;

下面是我编辑的链接器脚本:

    // File: 18f4620_e.lkr
// Sample linker script for the PIC18F4620 processor

LIBPATH .

FILES c018i_e.o
FILES clib_e.lib
FILES p18f4620_e.lib

CODEPAGE   NAME=page       START=0x0               END=0xFEFF
CODEPAGE   NAME=para       START=0xFF00            END=0xFFFF         PROTECTED
CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED
CODEPAGE   NAME=config     START=0x300000          END=0x30000D       PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED
CODEPAGE   NAME=eedata     START=0xF00000          END=0xF003FF       PROTECTED

DATABANK   NAME=gpre       START=0x0            END=0x5F
ACCESSBANK NAME=accessram  START=0x60           END=0x7F
DATABANK   NAME=gpr0       START=0x80           END=0xFF
DATABANK   NAME=gpr1       START=0x100          END=0x1FF
DATABANK   NAME=gpr2       START=0x200          END=0x2FF
DATABANK   NAME=gpr3       START=0x300          END=0x3FF
DATABANK   NAME=gpr4       START=0x400          END=0x4FF
DATABANK   NAME=gpr5       START=0x500          END=0x5FF
DATABANK   NAME=gpr6       START=0x600          END=0x6FF
DATABANK   NAME=gpr7       START=0x700          END=0x7FF
DATABANK   NAME=gpr8       START=0x800          END=0x8FF
DATABANK   NAME=gpr9       START=0x900          END=0x9FF
DATABANK   NAME=gpr10      START=0xA00          END=0xAFF
DATABANK   NAME=gpr11      START=0xB00          END=0xBFF
DATABANK   NAME=gpr12      START=0xC00          END=0xCFF
DATABANK   NAME=gpr13      START=0xD00          END=0xDFF
DATABANK   NAME=gpr14      START=0xE00          END=0xEFF
DATABANK   NAME=gpr15      START=0xF00          END=0xF7F
ACCESSBANK NAME=accesssfr  START=0xF80          END=0xFFF          PROTECTED

SECTION    NAME=CONFIG     ROM=config
SECTION    NAME=DATTBL     ROM=para

STACK SIZE=0x100 RAM=gpr14

1 个答案:

答案 0 :(得分:2)

您的代码存在两个问题。首先,您尝试在地址0x3FC000处擦除并写入闪存,同时尝试从地址0x00FF00读取闪存。第二个是TBLLAT的读写操作实际上并不执行读或写操作。它只是一个分段寄存器,用于执行读取或写入,您需要使用TBLRDTBLWT指令。这些指令在C中不可用,因此您需要使用内联汇编:

 TBLPTR = 0x00FF000      // start of write seq
 for(i = 0; i<64; i++) {
     TABLAT = dispData0[i];
     _asm TBLWTPOSTINC _endasm // write TBLLAT to flash; increment TBLPTR
 }

 ...

 TBLPTR = 0x00FF00;
 _asm TBLRDPOSTINC _endasm //  read flash into TBLLAT; increment TBLPTR
 dispData3[0] = TABLAT;
 _asm TBLRDPOSTINC _endasm
 dispData3[1] = TABLAT;

我在Microchip论坛上发现了这篇文章的TBLWTPOSTINC内联汇编指令:http://www.microchip.com/forums/m653617.aspx#msg653672