Ссылка на PROGMEM

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 136
Зарегистрирован: Чт янв 02, 2014 21:28:22

Сообщение 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
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение 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]; // а вот это зависит от структуры массива
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 136
Зарегистрирован: Чт янв 02, 2014 21:28:22

Сообщение 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 пиксел :o
по поводу pgm_read_byte_far, обьем mega2560 256кбайт, а это 18 бит, uint16_t не логично использовать, pgm_read_byte_far принимает адрес uint32_t, последний контролер с которым я работал был ATMEGA16, проблем не было, да и сейчас нету, не пойму почему с этим контролером проблемы.
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

По поводу железки. В студии есть вполне годный симулятор, можно пройтись по проблемному куску кода и сверяя передаваемые значения определить причину.
Попробуйте также в map файле линкера посмотреть адреса массивов шрифта и потыкать их напрямую в функцию чтения. Быть может вы некорректно вычисляете адреса или преобразоваваете типы. Больше пока посмоветовать нечего поскольку с AVRGCC плотно не работал.
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Аватара пользователя
Сообщения: 136
Зарегистрирован: Чт янв 02, 2014 21:28:22

Сообщение servmv »

uk8amk писал(а):По поводу железки. В студии есть вполне годный симулятор, можно пройтись по проблемному куску кода и сверяя передаваемые значения определить причину.
Попробуйте также в map файле линкера посмотреть адреса массивов шрифта и потыкать их напрямую в функцию чтения. Быть может вы некорректно вычисляете адреса или преобразоваваете типы. Больше пока посмоветовать нечего поскольку с AVRGCC плотно не работал.
Я про это пишу, в симуляторе все отлично. Данные есть, адреса тоже совпадают, другим кодом пробовал

Код: Выделить всё

FontSel = (uint32_t) &SmallFont[0]; // а вот это зависит от структуры массива
а на железке не работает. Типы я не преобразовываю. В FontSel ложится адрес, по которому реально есть данные. Вот скриншет.

на железке в dt попадает 255 (пробовал туда в место dt прописать вручную "8") линии рисуются длинной в 9 пикс. Я четко нашел где проблема, но я не понимаю что не так.

дисасемблированный фрагмент
Последний раз редактировалось servmv Сб янв 02, 2016 16:36:37, всего редактировалось 1 раз.
Контактная информация:
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 136
Зарегистрирован: Чт янв 02, 2014 21:28:22

Сообщение 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 пикселей
Контактная информация:
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 136
Зарегистрирован: Чт янв 02, 2014 21:28:22

Сообщение 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)
я конечно по пробовал оба варианта, не помогло, но выбесило в край.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

А попробовать отладку в железе есть возможность ?
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 136
Зарегистрирован: Чт янв 02, 2014 21:28:22

Сообщение 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 и брак чего либо можно исключить.
Контактная информация:
Вымогатель припоя
Сообщения: 541
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение 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);
на

Код: Выделить всё

char dt = pgm_read_byte_far(FontSel + x1);
покажите ваш проект для отладчика.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18708
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я не пойму: зачем вы пользуете far-процедуры чтения из PROGMEM? по умолчанию данные в PROGMEM размещаются в первых 64К адресов, поэтому доступны по обычному, не far-указателю. в моей практике был случай, когда прилось задействовать более 64К памяти под константные данные, но то особый случай. что можно напихать в память, что в 64К не влезает?! :shock:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 136
Зарегистрирован: Чт янв 02, 2014 21:28:22

Сообщение servmv »

ARV писал(а):я не пойму: зачем вы пользуете far-процедуры чтения из PROGMEM? по умолчанию данные в PROGMEM размещаются в первых 64К адресов, поэтому доступны по обычному, не far-указателю. в моей практике был случай, когда прилось задействовать более 64К памяти под константные данные, но то особый случай. что можно напихать в память, что в 64К не влезает?! :shock:
Да по началу так и было, а про far даже незнал, это уже гугл помог. Тему можно закрыть. Что было не так я отписал тут
Контактная информация:
Ответить

Вернуться в «AVR»