Приветствую Вас ГостьПятница, 26.04.2024, 03:47

AVR & ARDUINO




Каталог статей

Главная » Статьи » Справочник

PROGMEM

Микроконтроллеры AVR имеют Гарвардскую архитектуру, в которой в отличии от архитектуры фон Неймана, перепрограммируемое пространство (Flash) используется для программ, а RAM для данных, и каждая из них имеет отдельное адресное пространство. Использование утилиты PROGMEM позволяет хранить постоянные данные в программном пространстве, и использовать их в приложении Arduino.

Ключевое слово PROGMEM является модификатором переменной , оно должно быть использовано только с типами данных, определенными в pgmspace.h. Это ключевое слово говорит компилятору "положить эту информацию в флэш-память", а не в SRAM, где ее обычно хранит программа.

PROGMEM является частью библиотеки pgmspace.h. Таким образом, необходимо в первую очередь подключить библиотеку в верхней части скетча:

#include <avr/pgmspace.h>

Синтаксис

 dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}; 

dataType - любой тип переменной памяти программы, определенные в pgmspace.h (см ниже).

variableName - имя вашего массива данных.

Обратите внимание, что для модификатора переменной PROGMEM нет жестких правил о том, где он должен находиться, так компилятор Arduino принимает все представленные ниже определения, которые также являются синонимами. Однако эксперименты показали, что в различных версиях Arduino (использующих GCC), PROGMEM может работать в одном месте, а в другом - нет. Ниже представленный пример был протестирован для работы с Arduino 13. Более ранние версии IDE могут работать лучше, если PROGMEM находится после имени переменной.

 dataType variableName[] PROGMEM = {}; // используйте эту форму
 dataType PROGMEM variableName[] = {}; // НЕ используйте эту форму
 PROGMEM dataType variableName[] = {}; // используйте эту форму

В общем, переменные PROGMEM могут быть использованы и для одной переменной, но их использование оправдано только, если у вас есть большие блоки данных, которые необходимо хранить, которые, как правило, представляют собой массивы (структуры данных Си вне нашего настоящего обсуждения) .

Использование PROGMEM является двухэтапной процедурой. После того, как данные сохранены в флэш-памяти, они требуют специальных методов (функций), также определеных в библиотеке pgmspace.h, чтобы считать данные из программной памяти обратно в SRAM, где мы можем сделать что-то полезное с ними.

Как упоминалось выше, важно использовать типы данных, описанные в pgmspace.h . Если использовать обычные типы данных для вызовов данных из программного пространства, то могут генирироваться непонятные ошибки. Ниже представлен список поддерживаемых типов переменных. Числа с плавающей точкой в памяти программ не поддерживается.

  

prog_char signed char 1 байт   от -127 до 128
prog_uchar unsigned char 1 байт   от 0 до 255
prog_int16_t signed int 2 байта   от -32 767 до 32 768
prog_uint16_t unsigned int 2 байта   от 0 до 65 535
prog_int32_t signed long 4 байта от -2 147 483 648 до 2,147,483,647
prog_uint32_t   unsigned long   4 байта   от 0 до 4 294 967 295

Пример

Следующий фрагмент кода иллюстрируют, как читать и писать данные типа unsigned char (размер 1 байт) и int (размер 2 байта) в PROGMEM.

#include <avr/pgmspace.h>

//создаем некоторые беззнаковые целые
PROGMEM prog_uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};

//создаем некоторые символы
prog_uchar signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};

unsigned int displayInt;
int k; // переменная-счетчик
char myChar; 

// считываем по 2 байта в переменную int
 displayInt = pgm_read_word_near(charSet + k)

// считываем символ
myChar = pgm_read_byte_near(signMessage + k); 

Массивы строк

Часто бывает удобно при работе с большими объемами текста, такие как проекты с LCD-дисплеем, применять массивы строк. Поскольку сами строки являются массивами, то на самом деле это пример использования двумерного массива.

Это обычно крупные структуры, поэтому часто желательно расположить их в памяти программ. Приведенный ниже код иллюстрирует идею.

/*
 PROGMEM string demo
 Как хранить таблицу строк в памяти программ (Flash), 
 и извлекать их.

 Информация взята из:
 http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

 Настройка таблицы (массива) строк в программной памяти программ немного сложна,
 но здесь представлен хороший шаблон для подражания. 

 Настройка строк - это двухэтапный процесс. Сначала определите строки.

*/

#include <avr/pgmspace.h>
// "String 0" и т.д. - это строки для хранения данных.
prog_char string_0[] PROGMEM = "String 0"; 
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";
prog_char string_5[] PROGMEM = "String 5";


// Затем создаем таблицу для ссылки на строки.

PROGMEM const char *string_table[] = 
{ 
 string_0,
 string_1,
 string_2,
 string_3,
 string_4,
 string_5 };

char buffer[30]; // Убедитесь, что буфер достаточен для размещения самой большой строки

void setup() 
{
 Serial.begin(9600);
}


void loop() 
{
 /* Using the string table in program memory requires the use of special functions to retrieve the data.
 The strcpy_P function copies a string from program space to a string in RAM ("buffer"). 
 Make sure your receiving string in RAM is large enough to hold whatever
 you are retrieving from program space. */
 /* Использование таблицы строк в программной памяти требует использования специальных функций для
 извлечения данных.
 Функция strcpy_P копирует строку из памяти программ в оперативную память ("buffer"). 
 Убедитесь, что ваш буфер в памяти достаточно большой, чтобы вместить любую
 извлекаемую строку из памяти программ. */


 for (int i = 0; i < 6; i++)
 {
 strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Необходимые преобразования типов и разыменования для копирования. 
 Serial.println( buffer );
 delay( 500 );
 }
}

Смотрите также:

массив

string


Справочник

Материалы взяты с официального сайта проекта Arduino и представлены по лицензии Creative Commons Attribution-ShareAlike 3.0 License.



Источник: http://arduino.cc/en/Reference/PROGMEM
Категория: Справочник | Добавил: magi (23.01.2015)
Просмотров: 12457 | Теги: PROGMEM, программная память | Рейтинг: 0.0/0
Всего комментариев: 0
avatar
Поиск
Вход на сайт
На правах рекламы

Мы переезжаем на сайт Arduino по-русски