чтение констант ПЗУ pic18 с помощью C18

Я изо всех сил пытаюсь понять, почему я получаю случайные данные при попытке чтения из многомерной таблицы, хранящейся в ПЗУ.

У меня есть таблица растровых символов, которую я хочу отобразить на OLED-экране. Таблица символов слишком велика, чтобы поместиться в оперативной памяти, и ПЗУ - естественное место для нее. Когда я пытаюсь прочитать элементы из таблицы, данные не те, что хранятся в таблице.

Вот что я пытаюсь сделать. У меня есть растровое изображение, объявленное как многомерный массив в начале C-файла, где оно используется:

rom const char number[15][4][20] = { {
{0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0x70, 0x78, 0x38, 0x38, 0x38, 0x38, 0x78, 0x70, 0xf0, 0xe0, 0xc0, 0x00, 0x00},// row 1 columns 19
{0x00,...

Здесь я пытаюсь прочитать данные и вывести их на экран:

for(i=0; i<4; i++)
    {
        PutImage(number[digit][i],20,4,offset,i+2);
    }

Реализация функции PutImage:

void PutImage(char ptr[], unsigned char sizex, unsigned char sizey, unsigned char startx, unsigned char starty)
{
unsigned char _page, _column;

//startx += OFFSET;

OledWriteCommand(0xb0+starty);
OledWriteCommand(startx&0x0F);
OledWriteCommand(0x10 | ((startx>>4)&0x0F));

for(_column=0; _column<sizex; _column++)
{
    OledWriteData(ptr[_column]);
}
}

Если я изменю его так, чтобы данные помещались в оперативную память, все работает нормально. Таким образом, проблема должна быть либо в том, что данные изначально хранятся неправильно, либо в том, как я их использовал неправильно.

Я использую рисунок 18F27J53, а в разделе 7.1 таблицы данных (чтение и запись таблиц) рассказывается о некоторых операциях ассемблера, которые используются для перемещения байтов между памятью программы и оперативной памятью. Поскольку я использую C, я не уверен, что мне нужно знать об этом, или компилятор знает, как с этим справиться.


person user2771538    schedule 02.12.2013    source источник
comment
Можете ли вы немного объяснить интерфейс функции для PutImage? для чего используется каждый из параметров?   -  person Pandrei    schedule 02.12.2013


Ответы (2)


Хорошо связанный вопрос и его ответ привели меня к (надеюсь) правильному пути: and-rom-pointers-in-microchip-c18">Могу ли я сделать функцию, которая принимает указатели как на RAM, так и на ROM в Microchip C18?

И спасибо Pandrei также за указание на то, что причиной может быть реализация, если PutImage. Я получил работающий код, создав дублирующую функцию PutROMImage, которая принимает тип «near rom char*» вместо просто «char*», который по умолчанию равен ram.

Таким образом, C18 не позволяет указателям указывать как на RAM, так и на ROM, а параметр функции PutImage по умолчанию имеет значение ram. Таким образом, передача указателя на массив, который находится в ПЗУ, приводит к тому, что указатель указывает на случайные значения.

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

person user2771538    schedule 02.12.2013

наличие данных в ПЗУ (раздел .txt) или ОЗУ (раздел .data) не имеет ничего общего с проблемой, с которой вы столкнулись.

Предполагая, что инициализация выполнена правильно и вы инициализируете все элементы (если вы этого не сделаете, пропущенные элементы будут по умолчанию инициализированы до 0), проблема может заключаться в реализации функции: PutImage. Поскольку у вас возникают проблемы при изменении размера, возможно, у вас есть какие-то жестко запрограммированные значения...

person Pandrei    schedule 02.12.2013
comment
опубликуйте реализацию для PutImage, чтобы мы могли увидеть полную картину. - person Pandrei; 02.12.2013
comment
Спасибо за ответ. Я добавил реализацию PutImage. Дело в том, что числовой массив не помещается в ОЗУ, а ПЗУ будет естественным местом для вещей, которые не нужно менять. - person user2771538; 02.12.2013
comment
что значит не помещается в ОЗУ? где он тогда ставится? - person Pandrei; 02.12.2013
comment
Если я не помещаю массив в память программы, я получаю следующую ошибку от компоновщика: Ошибка - раздел 'номер' не может соответствовать разделу. Раздел 'number' length=0x00000514 В этом случае у меня есть 'code'#pragma idata number перед объявлением number -array. - person user2771538; 02.12.2013