Невозможно выполнить запись во флэш-память программ (PIC18F4620)

я пытаюсь записать некоторые данные во флэш-память программы. Я прочитал лист данных и последовал шагу. А также я отредактировал скрипт компоновщика для массива ромов. ниже приведены мои коды для последовательностей флэш-памяти на 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

person user3932504    schedule 13.08.2014    source источник
comment
летучий ли EECON2? в противном случае компилятор мог бы оптимизировать запись в него.   -  person odinthenerd    schedule 14.08.2014


Ответы (1)


В вашем коде две проблемы. Во-первых, вы пытаетесь стереть и записать флэш-память по адресу 0x3FC000, одновременно пытаясь прочитать ее по адресу 0x00FF00. Во-вторых, чтение и запись из TBLLAT на самом деле не выполняет операцию чтения или записи. Это просто промежуточный регистр, чтобы выполнить чтение или запись, вам нужно использовать инструкцию TBLRD или TBLWT. Эти инструкции недоступны в 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;

Инструкцию по встроенной сборке TBLWTPOSTINC я нашел в этом сообщении на форумах Microchip: http://www.microchip.com/forums/m653617.aspx#msg653672

person Ross Ridge    schedule 13.08.2014
comment
по какой-то причине он не считывает данные, которые я только что написал. Я использовал 3fc000 для tblptr, потому что в листе данных указано, что для записи 16-битный старший бит определяет адрес (?), а 5 младших битов - это регистр хранения 64 памяти. для стирания 5 младших разрядов игнорируются. вот почему я использовал 0x3fc000 при записи в 0xff00. - person user3932504; 14.08.2014
comment
Я не понимаю, почему вы думаете, что это означает, что вам нужно умножить адрес на 64. Это означает только то, что младшие 5 бит адреса игнорируются при стирании. Установка TBLPTR на 0x00FF00, 0x00FF01 или 0x00FF3F и выполнение операции стирания удалит все 64 байта во флэш-памяти между 0x00FF00 и 0x00FF3F включительно. При записи младшие 5 бит не игнорируются, и операция записи, когда TBLPTR равно 0x00FF01, записывает по адресу 0x00FF01 во флэш-памяти. - person Ross Ridge; 14.08.2014
comment
я понимаю. Спасибо за разъяснения. в любом случае обратное чтение неверно. Я подозреваю, что это биты конфигурации. я прочитал о разделе 23 о CPn, WRTn и EBTRn, и я отключил все это. это может быть проблемой? - person user3932504; 14.08.2014