Страница 1 из 1
Ссылка на PROGMEM
Добавлено: Пт янв 01, 2016 17:33:36
servmv
Народ помогите выбрать шрифт)
Шрифт лежит в PROGMEM
Код: Выделить всё
const unsigned char SmallFont[] PROGMEM={
0x08,0x0C,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <Space>
............
const unsigned char BigFont[] PROGMEM={
0x10,0x10,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, .............
const unsigned char SevenSegNumFont[] PROGMEM={
0x20,0x32,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF ....
пока 3)
что нужно,
Код: Выделить всё
#define Font8x12 1
#define Font16x16 2
#define Font32x50 3
void UTFT_printChar(uchar sym, uint x, uint y, uchar font){
uint FontSel; // <------------------
if(font == Font8x12){
FontSel = SmallFont; // <------------------
}
if(font == Font16x16){
FontSel = BigFont; // <------------------
}
if(font == Font32x50){
FontSel = SevenSegNumFont; // <------------------
}
cfont_x_size = pgm_read_byte(FontSel); // Высота символа
cfont_y_size = pgm_read_byte(FontSel+1); // Ширина символа, число байт
правильно объявить переменную, куда сохранить адрес, правильно его сохранить и передать в pgm_read_byte
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 08:37:49
uk8amk
http://avr-libc.narod.ru/group__avr__pg ... ce430a587c
Код: Выделить всё
#define pgm_read_byte ( address_short )
pgm_read_byte_near(address_short)
Считывает байт из памяти программ по 16-разрядно-му ("ближнему") адресу.
Примечание: адрес - адрес байта. Адрес находится в пространстве программ.
Исходя из этой информации надо действовать примерно так:
Код: Выделить всё
uint16_t FontSel; // для больших камней там u32 надо
FontSel = (uint16_t) &SmallFont[0]; // а вот это зависит от структуры массива
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 15:02:37
servmv
Чет у меня тут усложнилась ситуация, я почему то не могу прочесть PROGMEM как в учебнике, в симуляторе все работает на железе не работает. Размещение в первом посте расписано.
т.к. на железе некуда вывести байт для просмотра (хотя я уже думаю спаять макетку со светодиодами), я вывожу считанный байт на дисплей но так как шрифта еще нет, вывожу через функцию рисования линии, прочитанный байт используется в качестве длинны линии.
Код: Выделить всё
for (uchar x1=0; x1 < 12; x1++){
char dt = pgm_read_byte_far(SmallFont + x1);
UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
}
то есть читаю 12 байт и рисую 12 линий.
Код: Выделить всё
const unsigned char SmallFont[1144] PROGMEM = {0x08,0x0C,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
первая линия должна быть 1+8 = 9 пиксел
вторая 1+12=13пиксел
остальные по 1
все 12 линий по 256 пиксел
по поводу pgm_read_byte_far, обьем mega2560 256кбайт, а это 18 бит, uint16_t не логично использовать, pgm_read_byte_far принимает адрес uint32_t, последний контролер с которым я работал был ATMEGA16, проблем не было, да и сейчас нету, не пойму почему с этим контролером проблемы.
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 15:57:39
uk8amk
По поводу железки. В студии есть вполне годный симулятор, можно пройтись по проблемному куску кода и сверяя передаваемые значения определить причину.
Попробуйте также в map файле линкера посмотреть адреса массивов шрифта и потыкать их напрямую в функцию чтения. Быть может вы некорректно вычисляете адреса или преобразоваваете типы. Больше пока посмоветовать нечего поскольку с AVRGCC плотно не работал.
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 16:12:47
servmv
uk8amk писал(а):По поводу железки. В студии есть вполне годный симулятор, можно пройтись по проблемному куску кода и сверяя передаваемые значения определить причину.
Попробуйте также в map файле линкера посмотреть адреса массивов шрифта и потыкать их напрямую в функцию чтения. Быть может вы некорректно вычисляете адреса или преобразоваваете типы. Больше пока посмоветовать нечего поскольку с AVRGCC плотно не работал.
Я про это пишу, в симуляторе все отлично. Данные есть, адреса тоже совпадают, другим кодом пробовал
Код: Выделить всё
FontSel = (uint32_t) &SmallFont[0]; // а вот это зависит от структуры массива
а на железке не работает. Типы я не преобразовываю. В FontSel ложится адрес, по которому реально есть данные. Вот
скриншет.
на железке в dt попадает 255 (пробовал туда в место dt прописать вручную "8") линии рисуются длинной в 9 пикс. Я четко нашел где проблема, но я не понимаю что не так.
дисасемблированный фрагмент
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 16:35:02
servmv
В результате вот этого кода:
Код: Выделить всё
for (uchar x1=0; x1 < 12; x1++){
char dt = pgm_read_byte_far(SmallFont + x1);
UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
}
дисплей работает так:
скрин
В результате вот этого кода:
Код: Выделить всё
for (uchar x1=0; x1 < 12; x1++){
char dt = pgm_read_byte_far(SmallFont + x1);
UTFT_drawVLine(x1,0,8,VGA_YELLOW);
}
дисплей работает так:
скрин
как Вы понимаете на первом скрине 12 полосок по 256 пикселей
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 18:01:49
servmv
чет какие то танцы с бубном начинаются, нарыл
статью
где чувак пишет:
When i try put char on display = reading from progmem, microcontroller Atmega2560 "STOP / FROZE" !!! - this is in my opinion very unusual.
I read some topics about "pgm_read_byte_far / _near", next topics about "trampolines" and after lots of hours I read progmem with following command:
"LcdCache[LcdCacheIdx++] = pgm_read_byte_far(0x20100+(uint8_t)&(FontLookup[ch - 32]));"
In original of this command, some people used 0x20000 (on Atmgea2560), but in my case I must experimentaly go to value 0x20100.
This command was used only for my "debug experimenting" - this is wrong way in this situation.
Я не очень шарю в инглиш, но тут чет ужасное пишут,
pgm_read_byte_far(0x20100+(uint8_t)&(FontLookup[ch - 32]));
people used 0x20000 (on Atmgea2560)
я конечно по пробовал оба варианта, не помогло, но выбесило в край.
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 19:04:16
Аlex
А попробовать отладку в железе есть возможность ?
Re: Ссылка на PROGMEM
Добавлено: Сб янв 02, 2016 19:34:59
servmv
Аlex писал(а):А попробовать отладку в железе есть возможность ?
Нет. Мне не найти бюджетный JTAG для atmelstudio6
поставил atmelstudio7, попробовал там скомпилировать, результат тот же.
нашел еще вот это:
ссылка
I read the nice guide from wek :http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=708225 , but in his example he used 1 dimensional arrays, and he concludes that its not possible to use " GET_FAR_ADDRESS " or " pgm_get_far_address "( in newer versions of pgmspace.h)
сделал так:
Код: Выделить всё
FontSel = pgm_get_far_address(SmallFont); // а вот это зависит от структуры массива
for (uchar x1=0; x1 < 12; x1++){
char dt = pgm_read_byte_far(SmallFont + x1);
UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
}
в симуляторе также все отлично, на железке, не работает. Гдето читал про косяки bootloader arduino. Стер на*ер, во фьюзах поставил старт с 0000.
не че не помогает, чю за жопа.
P.S.
По пробовал залить демку что шла в комплекте, все работает на ура (там есть в PGM шрифты) а значит в коде есть обращение к PGM и брак чего либо можно исключить.
Re: Ссылка на PROGMEM
Добавлено: Вс янв 03, 2016 17:28:37
codenamehawk
servmv писал(а):
сделал так:
Код: Выделить всё
FontSel = pgm_get_far_address(SmallFont); // а вот это зависит от структуры массива
for (uchar x1=0; x1 < 12; x1++){
char dt = pgm_read_byte_far(SmallFont + x1);
UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
}
А если попробовать заменить
Код: Выделить всё
char dt = pgm_read_byte_far(SmallFont + x1);
на
покажите ваш проект для отладчика.
Re: Ссылка на PROGMEM
Добавлено: Вс янв 03, 2016 18:03:58
ARV
я не пойму: зачем вы пользуете far-процедуры чтения из PROGMEM? по умолчанию данные в PROGMEM размещаются в первых 64К адресов, поэтому доступны по обычному, не far-указателю. в моей практике был случай, когда прилось задействовать более 64К памяти под константные данные, но то особый случай. что можно напихать в память, что в 64К не влезает?!

Re: Ссылка на PROGMEM
Добавлено: Пн янв 04, 2016 05:50:14
servmv
ARV писал(а):я не пойму: зачем вы пользуете far-процедуры чтения из PROGMEM? по умолчанию данные в PROGMEM размещаются в первых 64К адресов, поэтому доступны по обычному, не far-указателю. в моей практике был случай, когда прилось задействовать более 64К памяти под константные данные, но то особый случай. что можно напихать в память, что в 64К не влезает?!

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