2013-05-07 6 views
0

Я хочу сохранить номер в PIC18, а затем сохранить его, даже если питание потеряно или устройство сбрасывается. Я думаю, что моя часть кода написана отлично, только часть чтения выглядит странно после перезагрузки устройства.Как вы пишете и читаете в памяти с помощью PIC18?

Я использую следующий код, который я получил от Microchip.

Код:

unsigned int value; 
unsigned int DEEdata = 1; 
unsigned int DEEaddr = 0x04; 

DataEEInit(); 
dataEEFlags.val = 0; 

DataEEWrite(DEEdata,DEEaddr); 
value = DataEERead(DEEaddr); 
Nop(); 
printf("%d",value); 

выводе: 1

Однако, когда я сброса устройства и использовать только код чтения я всегда получаю 255.

код для чтения:

DataEEInit(); 
value = DataEERead(DEEaddr); 
printf("%d",value); 

Выход: 255

Почему это происходит? Я предполагаю, что значение не сохраняется или часть чтения неверна. Спасибо!

+0

есть ли в вашей настройке eeprom? если вы получаете 255 (0xFF), он либо стирается, либо никогда не записывается, либо вы выполняете стирание при запуске. 'EE' на functon называет намек на то, что его запись на eeprom. какой номер вашего устройства? –

+0

У меня есть pic18f87j11 – Ammar

+1

@Ammar Если вы не нашли ответ здесь (хотя я вижу, что есть некоторые многообещающие ответы), вы можете проверить форум Microchip http://www.microchip.com/forums/. Я нашел их полезными в прошлом. –

ответ

0

Некоторые микросхемы PIC18 имеют внутреннюю ЭСППЗУ в дополнение к внутренней вспышке. У 18F87J11 нет этого, поэтому у вас есть 2 варианта:

1) Запись во флеш-память - здесь хранится ваша программа. убедитесь, что количество циклов записи/чтения в порядке.

2) Используйте внешний I2C или SPI память для параметров конфигурации

DataEEWrite вы используете это из библиотеки «ЭСППЗ эмуляции» от микрочип (связанного в комментариях ниже. Есть несколько вещей, быть осторожными:

  • упускает при перепрограммировании вспышки вы можете переписать ваши настройки
  • Помните, что это на самом деле не ЭСППЗ циклы записей ограничены, и вы должны удалить большие участки памяти - вы можете! 't стереть один байт
+0

Я бы очень хотел, чтобы какой-то пример о записи во флеш-память с использованием языка C, я думаю, что это мой лучший вариант. Для DataEEWrite() - я получил его из следующей [ссылки] (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en538000), спасибо @Will. – Ammar

+0

Я до сих пор не могу заставить его работать :( – Ammar

+1

OK Теперь я понимаю, что вы используете библиотеку эмуляции. Это позволяет использовать вспышку как своего рода притворную EEPROM. Вам нужно настроить некоторые константы для этого и вызвать init, прежде чем пытаться читать или писать. Все это находится в контрольном списке на странице 14 этого документа: http://ww1.microchip.com/downloads/en/AppNotes/01095D.pdf – Will

-2

Для сохранения значений в силовом цикле следует использовать память SRAM. Убедитесь, что у вас есть память SRAM.

+0

Я честно не знаю в данный момент, но я спросил кого-то, и я должен получить ответ в ближайшее время.Приносим извинения за неудобства. Это единственная проблема, которую вы подозреваете? – Ammar

+0

Да. Если у вас нет возможности записывать во флэш-память (что, как я подозреваю, у вас ее нет, я могу ошибаться), использование SRAM - единственный способ сохранить значения в силовом цикле. Вы всегда можете взаимодействовать с SRAM с микроконтроллером. – CatchMeIfYouTry

+0

Возможно, эта информация полезная, у меня есть pic18f87j11. – Ammar

1

Устройство, которое вы используете, не имеет внутренней энергонезависимой памяти, кроме Flash, обычно используемой для хранения кода.

У вас есть два варианта, которые я могу видеть:

  1. использовать некоторые внешний флэш или EEPROM и его интерфейс к шине внешней памяти, которая доступна на этом ПОС (см 97 Семейного Datasheet).
  2. Удалите внутреннюю флешку, чтобы зарезервировать небольшую порцию, которая может использоваться для хранения ваших данных (чтобы она не мешала области памяти, используемой исключительно для кода) и записывала ваши данные в этот регион (стр. 87).

Я не работал с PIC в течение многих лет, поэтому не могу предложить вам много способов реализации, но я подозреваю, что есть много примеров, которые вы можете использовать на веб-сайте Microchip.

По сути, причина, по которой ваш код не работает, заключается в том, что вы пытаетесь получить доступ к памяти, которой нет. Если он есть, то интерфейс неверен.

EDIT:

Я поглядела через страницу примеры кода для PIC18 на веб-сайте компании Microchip и не может найти примеры C для записи в память программы. К сожалению, похоже, вам придется реализовать его в ассемблере. Я не знаю, семантику для MPLAB компилятор, но, как правило, это будет что-то как это, если вы собираетесь сделать это рядный:

void my_assembler_function(void) 
{ 
    // Inline assembler code, actioned via C. 
    asm("MOV x y"); 
    asm("MOV y z"); 
} 

В качестве альтернативы, многие компиляторы C для микропроцессора позволяют вам для вызова внешнего файла .s с вызовом функции C, что избавит вас от необходимости делать его встроенным.

Я думаю, вы можете следовать примеру, который я нашел here, чтобы фактически реализовать функциональность, с которой вы работаете.

+0

Я хочу попробовать вариант 2 сейчас, а затем, если необходимо, я переключусь на вариант 1, пример для варианта 2 завершит ваш ответ. – Ammar

+0

Какой компилятор вы используете? –

+0

Я использую MPLAB IDE C18 – Ammar

1

SRAM не может быть использован для хранения энергонезависимых данных ...

SRAM потеряет данные во время цикла питания ...

Варианты: 1. Использовать внутренний EEPROM, если имеется. 2. Внешний EEPROM через I2C или SPI. 3. Библиотека эмуляции данных PIC18.

0

Значение 255 является значением по умолчанию для памяти EEPROM. Я думаю, что после изменения кода вы снова запрограммируете микроконтроллер IC. Таким образом, ваша память EEPROM будет стерта и вернется к своему значению по умолчанию. Если вы используете MPLAB в качестве компилятора, вы можете перейти к «Programmer'tab»> «Настройки»> «Память программ»> «Параметры программы» и нажать «Сохранить EEPROM» в программе. Надеюсь, что это сработает.

0

Две функции: запись во флеш-память с использованием 64-байтового буфера @ 8-байтовых блоков и функция чтения/сравнения вспышки.

Для устройства: PIC18F46K80

Наполнители для заголовка файла:

#define PRGM_BUFFER_SIZE 8 
#define TABLE_WRITE_SIZE 64 

#define LOAD_TBL_PTR(x) { TBLPTRU = ((((x)>>8)>>8)&0xff);\ 
         TBLPTRH = (((x) >> 8) & 0xff);\ 
         TBLPTRL = ((x) & 0xff);\ 
        } 

Запись в функции вспышки:

/****************************************************** 
* Function  : write_block 
* Input  : uint16_t position in destination flash 
* Global  : uint8_t buffer[64] - Location of source data 
* Output  : None 
* Description : Writes the contents of the 64 byte 
* data buffer to program flash space. Only 64 bytes 
* can be written at once. The process of writing 
* to flash is: Erase->Write. 
******************************************************/ 
static void write_block(uint16_t addr) 
{ 
    int r, c; 

    // Erase flash block first. Erases a 64 byte block at a time. 

    LOAD_TBL_PTR(addr); 

    EECON1bits.EEPGD = 1; // Point to flash program memory 
    EECON1bits.CFGS = 0; // Access flash memory 
    EECON1bits.WREN = 1; // Enable write to memory 
    EECON1bits.FREE = 1; // Enable Erase operation 

    EECON2 = 0x55; 
    EECON2 = 0xAA; 

    EECON1bits.WR = 1;  // Clear the flash 

    asm("NOP");    // Stall 

    // Write buffer to internal buffer. This process writes 8 bytes at a time 
    // so we need to loop 8 times (8*8 = 64).) 

    for (r = 0; r < 8; r++) 
    { 
     LOAD_TBL_PTR((addr + (r * 8))); 

     for (c = 0; c < PRGM_BUFFER_SIZE; c++) 
     { 
      TABLAT = buffer[(r * 8) + c]; 

      asm("TBLWT*+");  // Push byte and then inc to next internal buffer cell 
     } 

     // Write the block to flash 

     asm("TBLRD*-");   // Point back to original row 

     // Write internal buffer to flash 

     EECON1bits.EEPGD = 1; // Point to flash program memory 
     EECON1bits.CFGS = 0; // Access flash program memory 
     EECON1bits.WREN = 1; // Enable write to memory 
     INTCONbits.GIE = 0;  // Disable interrupts 

     EECON2 = 0x55; 
     EECON2 = 0xAA; 

     EECON1bits.WR = 1;  // Start programming flash 
     INTCONbits.GIE = 1;  // Re-enable interrupts 
     EECON1bits.WREN = 0; // Disable write to memory 
    } 
} 

проверка записанных данных (показывает флэш-чтения)

/****************************************************** 
* Function  : compare_block 
* Input  : uint16_t position in destination flash 
* Global  : uint8_t buffer[64] - Location of previous written data 
* Output  : bool true=successful, false=did not match 
* Description : Reads a 64 byte block of flash memory and 
* compares it to the data found in the global buffer. 
******************************************************/ 
static bool compare_block(uint16_t addr) 
{ 
    bool retVal = true; // succeeds 
    uint8_t i = 0; 

    INTCONbits.GIE = 0;  // Disable interrupts 

    LOAD_TBL_PTR(addr); 

    for (i = 0; i < TABLE_WRITE_SIZE && retVal == true; i++) 
    { 
     asm("TBLRD*+"); 

     if (buffer[i] != TABLAT) 
      retVal = false; 
    } 

    INTCONbits.GIE = 1;  // Enable interrupts 

    return retVal; 
} 

Ваш, Bryan Wilcutt