0 / 0 / 0
Регистрация: 21.10.2010
Сообщений: 120
|
|
1 | |
Работа с переменными, строками, структурами через PROGMEM08.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); } } За основу взял статью "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
|
|
08.11.2014, 20:13 | |
Ответы с готовыми решениями:
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); }
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 |
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 | |
15.11.2014, 19:20 | |
Помогаю со студенческими работами здесь
13
Построить программу для работы со структурами - строками.
«Структуры. Массивы структур» Лабораторная работа 5 «Работа со структурами»
Работа с текстовыми строками. Дополнительные работы со строками Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |