Работа с массивами
- Войдите на сайт для отправки комментариев
Пнд, 21/09/2020 - 17:13
Всем привет! Делаю небольшой проект. Устройство не большое, в основном нужно будет обрабатывать массивы с данными. Массивов будет много. Для экономии ОЗУ решил сделать массивы типа PROGMEM (в массивы ничего записываться не будет, только чтение). Столкнулся с тем, что если сделать массив типа PROGMEM то чтение с него не происходит (точнее на выходе получаю "левые" значения). Вот пример кода:
byte A = 0;
byte B = 0;
byte i = 0;
const int bitmap[] PROGMEM = {
0x99,0x42,0x24,0x99,0x99,0x24,0x42,0x99
};
void setup() {
Serial.begin(115200);
}
void loop() {
A = 1 << i;
B = bitmap[i];
Serial.print(A);
Serial.print(" ");
Serial.println(B);
delay(1000);
i++;
if (i>7) i = 0;
}
На выходе получается следующее:
1 0 2 6 4 0 8 1 16 0 32 6 64 6 128 6
Если же массив убрать из PROGMEM, то все считывается правильно:
byte A = 0;
byte B = 0;
byte i = 0;
int bitmap[]= {
0x99,0x42,0x24,0x99,0x99,0x24,0x42,0x99
};
void setup() {
Serial.begin(115200);
}
void loop() {
A = 1 << i;
B = bitmap[i];
Serial.print(A);
Serial.print(" ");
Serial.println(B);
delay(1000);
i++;
if (i>7) i = 0;
}
На выходе:
1 153 2 66 4 36 8 153 16 153 32 36 64 66 128 153
Подскажите, что я делаю не так? Мне нужно Чтобы массивы читались из флеша, а не загружались в ОЗУ
Прошу прощения. Первый абзац почему-то оказался под спойлером....
массивы из PROGMEM надо читать "ручками".
Можно подробнее?
pgm_read_ надо загуглить
непосредственный доступ к переменным в ПРОГМЕМ, типа
- не работает. необходимо использовать специальные операторы типа pgm_read_byte() pgm_reaf_word() и так далее
Подробнее - в референсе
Спасибо за помощь! Исправил, теперь работает:
B = pgm_read_byte(&bitmap[i]);
forfrends вы там еще с типами переменных разберитесь ! А то пишете в память int, а читаете byte ...
forfrends вы там еще с типами переменных разберитесь ! А то пишете в память int, а читаете byte ...
ему - абсолютно пох. главное - прочитать чонить.
ему - абсолютно пох. главное - прочитать чонить.
ага, он уже отключился, побежал использовать...
forfrends вы там еще с типами переменных разберитесь ! А то пишете в память int, а читаете byte ...
ему - абсолютно пох. главное - прочитать чонить.
потому как есть разделение, кто читатели, кто писатели )))
непосредственный доступ к переменным в ПРОГМЕМ, типа
- не работает. необходимо использовать специальные операторы типа pgm_read_byte() pgm_reaf_word() и так далее
Подробнее - в референсе
Не помню, говорил я или нет, что я ламер, но вот эта информация для меня вообще новая. В последнем проекте CRC-таблицу держал в прогмеме и замечательно она оттуда читалась. Можете подсказать тупенькому, почему она читалась?
const unsigned short PROGMEM CRC_Table[256] = { тута длиннющая таблица на СРС16 }; unsigned short CRC_Sum(unsigned short wIniValue, uint8_t lpData) { wIniValue = CRC_Table[((wIniValue >> 8) ^ lpData++) & 0xFF] ^ (wIniValue << 8); return wIniValue; };Как я понимаю, тут как раз классический a = b[3]*с;
Не помню, говорил я или нет, что я ламер, но вот эта информация для меня вообще новая. В последнем проекте CRC-таблицу держал в прогмеме и замечательно она оттуда читалась. Можете подсказать тупенькому, почему она читалась?
а контроллер какой был?
Не помню, говорил я или нет, что я ламер, но вот эта информация для меня вообще новая. В последнем проекте CRC-таблицу держал в прогмеме и замечательно она оттуда читалась. Можете подсказать тупенькому, почему она читалась?
а контроллер какой был?
Ну так STM32 жеж
Я почему интересуюсь то? Алгоритм мною успешно сперт из этих ваших интернетов (правда пришлось доработать под свой СРС) и я откровенно не все в нем понимаю. Работает и ладно. Но хотелось бы иметь понимание даже спертого кода, а не только мною написанного :)
Так вот и учусь поманеньку...
DetSimen, b707, Я не пишу, потому что не вижу смысла кому-то что-то доказывать.
DetSimen, b707, Я не пишу, потому что не вижу смысла кому-то что-то доказывать.
а разве тут надо что-то доказывать? - Вы описали массив как int, читаете как байт. Это надо доказывать или пока согласны?
далее вам указали на эту очевидную ошибку, умный человек поблагодарил бы и исправил... а вы что-то доказывать рветесь... Что?
Ну как что? Что вы жалкие, ничтожные личности. Некоторые люди кюшать не могут, пока в интернете кому то это не докажут :)
Ну так STM32 жеж
не, я пока не настолько продвинут, чтобы уверенно обсуждать. У меня в коде PROGMEM активно используется. но я работаю с ним "по прописи", через pgm_read_xxx. Возможно, что в СТМ32 разницы между const PROGMEM и просто const нет, но повторюсь что пока не готов что-то говорить. Может кто другой подскажет.
попробовал на примере кода ТС из первого поста
//#define USE_PGM #ifndef USE_PGM const byte bitmap[]= { 0x99,0x42,0x24,0x99,0x99,0x24,0x42,0x99 }; #else const byte bitmap[] PROGMEM= { 0x99,0x42,0x24,0x99,0x99,0x24,0x42,0x99 }; #endif void setup() { Serial.begin(115200); } void loop() { A = 1 << i; #ifndef USE_PGM B = bitmap[i]; #else B = pgm_read_byte(&bitmap[i]); #endif Serial.print(A); Serial.print(" "); Serial.println(B); delay(1000); i++; if (i>7) i = 0; }для Ардуино Нано код с ПРОГМЕМ занимает 205 байт ОЗУ, без - 213 (флеш одинаков)
для СТМ32 - что с прогмем, что без - разницы нет.
Зато если в коде для СТМ32 убрать const в описании массива - оперативка становится меньше на 8 байт.
Вывод - для СТМ32 квалификатор PROGMEM не нужен, достаточно описать данные как const
b707, я посмотрю как вы сможете исправить код в первом сообщении...
Не понимаю. почему вы завелись? Или вам мало той благодарности, которую я выразил в сообщении №6? Ок, разные типы данных, ок, исправил это у себя на компьютере, так зачем обсирать в 5-м и 6-м сообщении? для этого есть повод? Только потому что я не ответил и тем самым зацепил ваше самолюбие? Зачем высмеивать кого-то и искать что-то за что можно зацепиться и полить человека грязью?
b707, относительно PROGMEM - это не влияет на использование флеша, только влияет на использование ОЗУ.
b707, я посмотрю как вы сможете исправить код в первом сообщении...
не понял, вы разве его еще не исправили? спрашивайте тогда
Мужики, "жесть" - это уже отожжённая сталь, так что отжигать её здесь совершенно не обязательно.
Ну так STM32 жеж
В STM и ОЗУ и flash находятся в едином адресном пространстве. В отличие от AVR.
И в дефайнах PROGMEM для STM заменяется то ли на пробел, то ли вообще опускается.
Кстати, опишите для STM переменную и константу, а потом выведите адреса той и другой и сравните с таблицей распределения памяти. Узнаете много интересного.