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

Unable to write to flash program memory(PIC18F4620)

本文关键字:存储器 PIC18F4620 程序存储 程序 闪存      更新时间:2023-10-16

我正在尝试将一些数据写入闪存程序存储器。我阅读了数据表并按照步骤操作。我还编辑了链接器脚本的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

您的代码有两个问题。第一个是,你试图擦除和写入地址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