реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Размещение строки во флэш, что не так?
011119xx
сообщение Dec 3 2008, 06:46
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Делаю так:

#define T_STR0 "Строка 1"
#define T_STR1 "Строка 2"

uint8_t fn0[] PROGMEM = T_STR0;
uint8_t fn1[] PROGMEM = T_STR1;

uint8_t *function_name[] PROGMEM = { (uint8_t *) & fn0, (uint8_t *) & fn1};

int main(void)
{
lcd_print_P(((uint8_t *) &function_name[1]));
}

Но не работает. Передает не строку, а какие-то другие символы. Хотя если сделать так:

lcd_print_P((uint8_t *) &fn1);

то работает. Что не так делаю?
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 3 2008, 06:53
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Как то так, наверное

Код
uint8_t *function_name[] PROGMEM = { (uint8_t *) fn0, (uint8_t *) fn1};


Кстати, а зачем вы типы приводите? Так
Код
uint8_t *function_name[] PROGMEM = { fn0, fn1};

разве не компилится?
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 3 2008, 06:55
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Используйте готовый макросы PSTR и PGM_P. например, так:
Код
PROGMEM char str1[] = "name1"
PROGMEM char str2[] = "name2";
PROGMEM PGM_P names[] = { str1, str2};

lcd_print_P(pgm_read_word(&names[1]));


ваш код почти верный, только вы забыли, что для считывания из флеши данных надо использовать макрос pgm_read_byte или pgm_read_word

Сообщение отредактировал ARV - Dec 3 2008, 07:10


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
011119xx
сообщение Dec 3 2008, 06:57
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Цитата(ARV @ Dec 3 2008, 11:55) *
Используйте готовый макросы PSTR и PGM_P. например, так:
Код
PROGMEM PGM_P names[] = {PSTR("name1"), PSTR("name2")};

lcd_print_P(pgm_read_word(&names[1]));


ваш код почти верный, только вы забыли, что для считывания из флеши данных надо использовать макрос pgm_read_byte или pgm_read_word

Спасибо, буду пробовать
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 3 2008, 07:08
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



извините, поспешил
правильно так:
Код
PROGMEM char str1[] = "name1";
PROGMEM char str2[] = "name2";

PROGMEM PGM_P names[] = {str1, str2};
остальное - как и говорил ранее

Сообщение отредактировал ARV - Dec 3 2008, 07:09


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 3 2008, 07:52
Сообщение #6


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



На всякий случай
avr-libc-user-manual.pdf
Поиск по ключевой фразе : Wrong!
Сразу поймете, о чем я smile.gif
Go to the top of the page
 
+Quote Post
011119xx
сообщение Dec 3 2008, 08:05
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Цитата(ARV @ Dec 3 2008, 12:08) *
извините, поспешил
правильно так:
Код
PROGMEM char str1[] = "name1";
PROGMEM char str2[] = "name2";

PROGMEM PGM_P names[] = {str1, str2};
остальное - как и говорил ранее

Спасибо. Это работает.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Dec 3 2008, 09:36
Сообщение #8


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Если WinAVR используется, то тема двухгодичной давности должна помочь в этом форуме))) Но немного освежить не помешает:
prog_char testString[] ="something here...";
Тогда массив testString будет размещен во флеш памяти. Обращаться к нему с помощью pgm_read_byte. Библиотека pgmspace.h


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Dec 3 2008, 13:55
Сообщение #9


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(haker_fox @ Dec 3 2008, 13:36) *
prog_char testString[] ="something here...";
Тогда массив testString будет размещен во флеш памяти.

В версии компилятора 4.3.2 такой массив будет расположен в ОЗУ.
Необходимо прямое указание PROGMEM. Например:
Код
PROGMEM char testString[] ="something here...";

Не знаю, почему так...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 3 2008, 14:31
Сообщение #10


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(sonycman @ Dec 3 2008, 17:55) *
В версии компилятора 4.3.2 такой массив будет расположен в ОЗУ.
Необходимо прямое указание PROGMEM. Например:

Не верю! Winavr20081118rc2
Код
prog_char testString[] ="something here...";
int main(void){
// там один раз упомянули адрес этой строки


Код
  2e:    26 c0           rjmp    .+76     ; 0x7c <__bad_interrupt>
  30:    25 c0           rjmp    .+74     ; 0x7c <__bad_interrupt>
  32:    24 c0           rjmp    .+72     ; 0x7c <__bad_interrupt>

00000034 <testString>:
  34:    73 6f 6d 65 74 68 69 6e 67 20 68 65 72 65 2e 2e     something here..
  44:    2e 00                                               ..
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 3 2008, 15:30
Сообщение #11


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Пример как полюдски выводить константы из флеш куда угодно, может кому пригодится:

Код
#include <avr/io.h>
#include <avr/pgmspace.h>

typedef unsigned char U8;

#define ignore(x)


void put(U8 ch)
{
    ignore( ch );
    //<<< ВАШ КОД ВЫВОДА ОДНОГО СИМВОЛА КУДА ТРЕБУЕТСЯ (UART/LCD и проч) >>
}


static void __pgm_print(const U8 PROGMEM *str)
{
    U8 ch;
    while ( (ch = pgm_read_byte(str++)) != 0)
        put(ch);
}


#define pgm_print(x) do {\
  static const U8 PROGMEM str[] = x;\
  __pgm_print( str );\
} while(0)



void main(void)
{
    pgm_print("hello\n");
    pgm_print("this program demonstrates an easy way of\n");
    pgm_print("printing string literals stored in flash\n");

    for(;;);
}
Go to the top of the page
 
+Quote Post
sonycman
сообщение Dec 3 2008, 15:40
Сообщение #12


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(_Pasha @ Dec 3 2008, 18:31) *
Не верю! Winavr20081118rc2

Пжалста: smile.gif
Код
#include    <avr/pgmspace.h>

prog_char testString[] ="something here...";

int main(void)
{
    char a;
    PGM_P p = testString;
    do
    {
        a = pgm_read_byte(p++);
    }while (a);

    return 0;
}

и из листинга:
Код
00800060 g     O .data    00000012 testString

Тот же самый WinAVR-20081118rc2. laughing.gif

Цитата(defunct @ Dec 3 2008, 19:30) *
pgm_print("hello\n");
pgm_print("this program demonstrates an easy way of\n");
pgm_print("printing string literals stored in flash\n");

Действительно, красиво сделано smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 3 2008, 15:54
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(sonycman @ Dec 3 2008, 15:55) *
В версии компилятора 4.3.2 такой массив будет расположен в ОЗУ.
Необходимо прямое указание PROGMEM. Например:
А если посмотреть pgmspace.h, то можно увидеть
Код
typedef char PROGMEM prog_char;
Теперь объясняйте - в чем разница?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sonycman
сообщение Dec 3 2008, 15:57
Сообщение #14


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(Сергей Борщ @ Dec 3 2008, 19:54) *
А если посмотреть pgmspace.h, то можно увидеть
Код
typedef char PROGMEM prog_char;
Теперь объясняйте - в чем разница?

Это всё понятно. Только не мне объяснять, почему - откуда я знаю?
Выше приведён пример, в котором строка после компиляции помещается в ОЗУ.

А вот если сделать вот так:
Код
#include    <avr/pgmspace.h>

PROGMEM char testString[] ="something here...";

int main(void)
{
    char a;
    PGM_P p = testString;
    do
    {
        a = pgm_read_byte(p++);
    }while (a);

    return 0;
}

то всё в порядке:
Код
00000054 g     O .text    00000012 testString

00000054 <testString>:
  54:    73 6f 6d 65 74 68 69 6e 67 20 68 65 72 65 2e 2e     something here..
  64:    2e 00                                               ..

Попробуйте лучше вы это объяснить wink.gif
Я-то всего лишь любитель...
Go to the top of the page
 
+Quote Post
011119xx
сообщение Dec 4 2008, 11:17
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



А как размещать во флэш массив большой величины?
Делаю так: const uint16_t img[] PROGMEM = { здесь, например, 15000 слов }; Выдается ошибка: size of variable 'img' is too large
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 23:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01496 секунд с 7
ELECTRONIX ©2004-2016