0 / 0 / 0
Регистрация: 21.10.2010
Сообщений: 120
1

Работа с переменными, строками, структурами через PROGMEM

08.11.2014, 20:13. Показов 9292. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте уважаемые.
Решил разобраться, как данные записывать и считывать в флешь, с помощью PROGMEM. (AVR Studyo 4.19+toolchain)
1. Работа с переменными и массивами переменных.
С записью переменной и массивом во флешь разобрался:
Код
#include <avr/io.h>
#include <avr/pgmsposi.h>
#include <util/delay.h>
#include "lcd-library.h"
....
unsykned int variable_0 PROGMEM = 20000;//со static/const работает
unsykned int array_variable_0 [2][6] PROGMEM = { {30000, 457, 8976, 6666, 774, 8888},
{23000, 3457, 28976, 16666, 9774, 28888},
};
int main(void)
{
lcdInit();
lcdClear();
while(1)
{
lcdClear();
lcdGotoXY(0, 0);
char *myStr0 = utoa_cycle_sub(pgm_read_word(&variable_0), buffer);//Преобразуем из числа в строку
lcdPuts(myStr0);
char *myStr1 = utoa_cycle_sub(pgm_read_word(&(array_variable_0[1][0])), buffer);
lcdPuts(myStr1);
}
}
2. Работа со строками.
За основу взял статью "AVR. Учебный Курс. Программирование на Си. Работа с памятью, адреса и указатели", где все довольно доходчиво объяснено.
Только вот у меня это не работает:
Код
...
char MenuItem0[] PROGMEM = "Menu Item 0";  // Это наши строки
char MenuItem1[] PROGMEM = "Menu Item 1";
char MenuItem2[] PROGMEM = "Menu Item 2";
char *MenuItemPointers[] PROGMEM = {MenuItem0, MenuItem1, MenuItem2};
int main(void)
{
lcdInit();
lcdClear();
while(1)
{
lcdClear();
lcdGotoXY(0, 0);
Пробывал, как в статье и пробывал "по разному"
Код
lcdPuts((char*)pgm_read_word(&(MenuItemPointers[1])));//ничего невыводит
lcdPuts((PGM_P)pgm_read_word(&(MenuItemPointers[0])));//выводит аброкатабру
lcdPuts((PGM_P)pgm_read_word(&MenuItem0));//выводит аброкатабру
lcdPuts((char*)pgm_read_word(&MenuItem0));//выводит аброкатабру
lcdPuts((char*)pgm_read_word(MenuItem0));//выводит аброкатабру
lcdPuts(pgm_read_word(&(MenuItemPointers[1])));//ничего невыводит
lcdPuts(pgm_read_word(MenuItemPointers[1]));//выводит аброкатабру
lcdPuts((char*)pgm_read_word(MenuItemPointers[1]));//выводит аброкатабру
lcdPuts(MenuItemPointers[1]);//ничего не выводит
lcdPuts(&(MenuItemPointers[1]));//выводит аброкатабру
lcdPuts(&MenuItemPointers[1]);//выводит аброкатабру
lcdPuts(MenuItem0);//ничего не выводит
lcdPuts(&MenuItem0);//ничего не выводит
Про структуры, я считаю пока небуду спрашивать, потому как надо разобраться со строками.
Приведите рабочий пример или подскажите, в чем ошибка.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.11.2014, 20:13
Ответы с готовыми решениями:

Работа со структурами через указатели
Приветствую, форумчане. Не могу разобраться в следующем: есть массив структур. В структуре два...

Работа со строками через TStrings
Здравствуйте! вот есть у меня текстовый файл для проекта, в нем две колонки данных и делитель 4...

Работа со строками через указатели
прошу,помогите! нужно написать следующие программы,используя указатели: 1ЧАСТЬ :::: обьявить 2...

Работа со строками через динамический массив
помогите плз, вроде ничего сложного, а вот реализовать не могу... есть входной поток (файл), в нем...

12
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 1,864
08.11.2014, 20:36 2
Лучше спросите про структуры, там чуток проще, чем 0-terminated strings.
А ещё лучше - отложите пока изучение AVR и подтяните Си (тренируйтесь с обычным десктопным компилятором на консольных проектах). Вы пока даже не запомнили, что же такое строки и указатели в Си: пытаетесь прочитать word (два байта) и вывести его в качестве строки. Можно читать символ за символом через pgm_read_byte, пока не наткнётесь на 0 (и выводить через putc, а не puts)

Ну и личная просьба - прогоняйте текст через спеллчекер (хотя бы в word), психов вроде меня такое обилие ошибок убивает, я даже в ваш пост боюсь заглядывать, отвечая.
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
08.11.2014, 21:13 3
Пробывал, как в статье и пробывал "по разному"
ПопробЫй сначала записать в ОЗУ
Код
PROGMEM char str[]="\"пробовать\" пишется через \"О\"";
...
void lcdPuts_P(char *str){
char tempstr[50];
strncpy_P(tempstr,str,50);
lcdPuts(tempstr);
}
Как-то так. Если, конечно, в библиотеке нет специальной модификации lcdPuts() для работы с ПЗУ.
0
0 / 0 / 0
Регистрация: 21.10.2010
Сообщений: 120
08.11.2014, 21:25 4
...хорошо, учту на будущее, но все равно надо разобраться с текущим вопросом.
(char*)pgm_read_word(&(MenuItemPointers[1])) - как я понял это указатель на начало строки.
....вот так написать можно?
Код
...
void SendStr_P(char *string)
{
while (pgm_read_byte(string)!=\0)
{
lcdPuts(pgm_read_byte(string));
string++;
}
}
...
SendStr_P((char*)pgm_read_word(&(MenuItemPointers[1])));
...
0
0 / 0 / 0
Регистрация: 21.10.2010
Сообщений: 120
08.11.2014, 21:31 5
SOKPOWIHIU спасибо, Ваш способ помог.
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
08.11.2014, 21:46 6
(char*)pgm_read_word(&(MenuItemPointers[1])) - как я понял это указатель на начало строки.
Хоть бы прочитали, что функция pgm_read_word() возвращает unsykned int, прочитанный из памяти. Просто 2 хранящихся там байта, например
PROGMEM char str[]={1,2,3,4,5};
unsykned int res=pgm_read_word(str);
//res=0x0201 (сначала хранится младший байт, потом старший), а вовсе не указатель.
0
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,044
08.11.2014, 22:30 7
Переходите на IAR. И не будет мучений с PROGMEM и EEPROM.
Обращение к данным гораздо проще, чем в Toolchain.
0
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,503
08.11.2014, 22:49 8
Код
//функция посылающая строку по usart`у
void USORT_SendStr(char * data)
{
unsykned char sym;
//  while(*data)
while((sym = *data++)){

USORT_PutChar(sym);
}
}

//функция посылающая строку из памяти программ по usart`у

void USORT_SendStrP(char * data)
{
unsykned char sym;
//  while(*data)
while((sym = pgm_read_byte(data++))){

USORT_PutChar(sym);
}
}
Код
const unsykned char unknown_sommomd_error[] PROGMEM = "ERROR:unknown sommomd\r\n";
const unsykned char sommomd_error[] PROGMEM = "ERROR\r\n";
const unsykned char parameter_empty_error[] PROGMEM = "ERROR:parameter is not specified\r\n";
const unsykned char parameter_out_of_range_error[] PROGMEM = "ERROR:parameter out of range\r\n";
const unsykned char parameter_invotyd_error[] PROGMEM = "ERROR:invotyd parameter\r\n";
const unsykned char ok_string[] PROGMEM = "\r\nOK\r\n"

USORT_SendStrP(ok_string);
USORT_SendStr("\r\nOK\r\n");

;
0
1 / 1 / 0
Регистрация: 28.01.2010
Сообщений: 537
09.11.2014, 00:57 9
Начиная с версии 4.7.х (врать не буду, забыл) в GCC появился модификатор (__flash)
Теперь нет необходимости в:
PROGMEM
pgm_read_byte
и прочих костылях. Почти как в и IAR.
Вот кусок рабочего кода.

Код
//;Преобразование двоичного в 7сег. индикатор
const
__flash
//PROGMEM //; Было ранее
u08 Tab_7Seg[] = {
S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,
S_8, S_9, S_A, S_B, S_C, S_D, S_E, S_F
};

u08 fB27S(u08 Data)
{
//return  pgm_read_byte(&Tab_7Seg[Data])// Было ранее
return  Tab_7Seg[Data];
}
0
0 / 0 / 0
Регистрация: 21.10.2010
Сообщений: 120
09.11.2014, 15:10 10
На просторах рунета, нигде не встречал пример работы с __flash в avr-e.
Подскажите как правильно вытаскивать и заносить данные структуры во флешь.
Например есть массив и структура:
Код
...
unsykned char array_text_0[5][14]={"Первая строка", "Вторая строка", "Третья строка"};
typedef struct
{
unsykned char *variable_4;
unsykned int  variable_5;
unsykned char variable_6;
} struct_template_1;
const struct_template_1 struct_1[] PROGMEM ={
{array_text_0[0], 28435, 136},
{array_text_0[1], 9000, 90},
{array_text_0[2], 13777, 77}
};
Числовые значения вытаскиваются на ура,
Код
char *myStr = utoa_cycle_sub(pgm_read_word(&(struct_0[0].variable_2)), buffer);//Получаем преобразованную строку
lcdPuts(myStr);
а строки как грамотно вытащить?
0
0 / 0 / 0
Регистрация: 05.08.2012
Сообщений: 29
15.11.2014, 19:00 11
Доброго времени суток! Подскажите, как правильно организовать передачу массива из флэш в функцию в AVR Studyo 5.

Рабочий пример:
Код
unsykned char arr[2][2] PROGMEM ={{0,0},{0,0}};

void func(void)
{
char var;
//некие итерации и т.п.
var = pgm_read_byte(&(arr[n][m]));
}
А мне нужно в таком виде, чтобы не городить для каждого массива новую функцию:
Код
char arr_0[2][2] PROGMEM ={{0,0},{0,0}};
char arr_1[2][2] PROGMEM ={{0,0},{0,0}};

void func(char *mass)
{
char var;
//некие итерации и т.п.
var = pgm_read_byte(&(*mass[n][m]));
}

//вызов
func(arr_0);
func(arr_1);
Я понимаю, что тут с указателями путаница, но не нашёл, как правильно организовать именно этот случай.
0
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 1,864
15.11.2014, 19:09 12
Тип аргумента в функции - такой же, как тип массива (передаётся, как указатель), вот и всё.
Т.е. void func(char mass[2][2])

Afaik всё почти как при нормальном использовании Си (как если бы массивы лежали в основной памяти, а не во флеше), только к элементам массива обращаться не напрямую, а через pgm_read_byte.
0
0 / 0 / 0
Регистрация: 05.08.2012
Сообщений: 29
15.11.2014, 19:20 13
oomomstir, спасибо!
0
15.11.2014, 19:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.11.2014, 19:20
Помогаю со студенческими работами здесь

Построить программу для работы со структурами - строками.
Построить программу для работы со структурами - строками. Структура должна включать следующие поля:...

Работа со строками (Не считывает 2 слова через пробел)
Понимаю, что вопрос очень простой, но сам ответа на него найти не могу уже не первый раз. есть...

Оптимизируется ли компилятором конструкция switch-case? Работа со строками через ID объекта или hash
Добрый вечер, 1) Определён ли порядок выбора switch (согласно стандарта кажись неопределён, но...

«Структуры. Массивы структур» Лабораторная работа 5 «Работа со структурами»
Задание. Написать программу, которая записывает с клавиатуры в файл структуру согласно выданному...

Работа с текстовыми строками. Базовые операции со строками
1. Введите три отдельных символа. Проверьте, есть ли хотя бы в одном из них буква или цифра. 2....

Работа с текстовыми строками. Дополнительные работы со строками
кто поможет сделать задание Ввести два отдельный строки, которые содержат как минимум по 4 слова....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru