arduinoProgmem

PROGMEM

ذخیره داده در فلش، یا همان محل ذخیره ی کدهای برنامه به جای SRAM. همان طور که می دانید SRAM محل ذخیره ی متغیرهایی است که توسط برنامه ایجاد می شود. و نسبت به حافظه ی FLASH ظرفیت خیلی کمتری دارد. برای مطالعه انواع حافظه به اینجا مراجعه کنید.

PROGMEM:

کلمه ی PROGMEM یک اصلاح کننده ی متغیر است، که باید فقط با نوع داده هایی که در کتابخانه pgmspace.h تعریف شده اند استفاده شود. این کلمه به کامپایلر می گوید که “این اطلاعات را در حافظه ی فلش ذخیره کن”. به جای اینکه در حافظه ی SRAM قرار بدهد. همانطور که می دانید بطور معمول متغیر در SRAM قرار می گیرد.

PROGMEM بخشی از کتابخانه pgmspace.h می باشد. این کتابخانه در ورژن های جدید نرم افزار آردوینو به طور اتوماتیک به پروژه اضافه می شود. اگر شما از ورژن های قدیمی تر از 1.0 استفاده می کنید، باید این کتابخانه را به بالای برنامه ی خود اضافه کنید.مانند مثال زیر:

#include <avr/pgmspace.h>

استفاده از PROGMEM دو رویه دارد. بعد از قرار دادن داده در حافظه ی فلش.برای خواندن آن از حافظه ی فلش و برگرداندنش به حافظه ی SRAM ، هم یک متد مخصوص که در کتابخانه pgmspace.h تعریف شده است وجود دارد.

نحوه استفاده:

const dataType variableName[] PROGMEM = {data0, data1, data3…​};

dataType: نوع متغیر.

variableName: اسم متغیر.

چون PROGMEM یک تعریف کننده ی منغیر است، هیچ قانون سختی برای اینکه در کجای برنامه استفاده شود وجود ندارد. بنابراین کامپایلر آردوینو همه نوع روش استفاده از آن را که در زیر آمده قبول می کند. ولی تجربه نشان داده که در بعضی ورژن های آردوینو PROGMEM با یکی از این روش ها کار کرده و با بقیه کار نکند.در جدیدترین ورژن آردوینو وقتی که PROGMEM را بعد از اسم متغیر استفاده کردیم بهتر جواب داد.

const dataType variableName[] PROGMEM = {}; // use this form
const PROGMEM dataType variableName[] = {}; // or this one
const dataType PROGMEM variableName[] = {}; // not this one

یک کد نمونه از PROGMEM:

در مثال زیر نحوه ی خواندن و نوشتن منغیرهایی از نوع CHAR و INT با استفاده از PROGMEM نشان داده شده است:

// save some unsigned ints
const PROGMEM uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};

// save some chars
const char signMessage[] PROGMEM = {"I AM PREDATOR,  UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};

unsigned int displayInt;
char myChar;


void setup() {
  Serial.begin(9600);
  while (!Serial);  // wait for serial port to connect. Needed for native USB

  // put your setup code here, to run once:
  // read back a 2-byte int
  for (byte k = 0; k < 5; k++) {
    displayInt = pgm_read_word_near(charSet + k);
    Serial.println(displayInt);
  }
  Serial.println();

  // read back a char
  for (byte k = 0; k < strlen_P(signMessage); k++) {
    myChar = pgm_read_byte_near(signMessage + k);
    Serial.print(myChar);
  }

  Serial.println();
}

void loop() {
  // put your main code here, to run repeatedly:
}

آرایه ای از رشته ها:

وقتی در پروژه هایی از مقدار زیادی نوشته استفاده می کنیم، آرایه ای از رشته ها تعریف می کنیم. چون خود رشته ها نوعی آرایه هستند. این مثال از یک آرایه ی دو بعدی می باشد:

/*
  PROGMEM string demo
  How to store a table of strings in program memory (flash),
  and retrieve them.

  Information summarized from:
  http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

  Setting up a table (array) of strings in program memory is slightly complicated, but
  here is a good template to follow.

  Setting up the strings is a two-step process. First, define the strings.
*/

#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";


// Then set up a table to refer to your strings.

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

char buffer[30];  // make sure this is large enough for the largest string it must hold

void setup() {
  Serial.begin(9600);
  while (!Serial);  // wait for serial port to connect. Needed for native USB
  Serial.println("OK");
}


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. */


  for (int i = 0; i < 6; i++) {
    strcpy_P(buffer, (char *)pgm_read_word(&(string_table[i])));  // Necessary casts and dereferencing, just copy.
    Serial.println(buffer);
    delay(500);
  }
}

نکته:

توجه داشته باشید که متغیر باید بصورت گلوبال تعریف شده باشد یا از نوع static باشد، در غیر اینصورت PROGMEM کار نخواهد کرد.

نوع کوتاه شده:

وقتی که از دستوری با ساختار زیر استفاده می کنیم:

Serial.print("Write something on  the Serial Monitor");

نوشته ی شما بطور معمول در RAM ذخیره می شود. اگر برنامه ی شما، برای نشان دادن نوشته های مختلف، از پورت سریال زیاد استفاده می کند، خیلی زود RAM پر می شود. اگر شما حافظه فلش خالی دارید می توانید با استفاده از نوع کوتاه شده ی این دستوری که یاد گرفتیم، کاری کنید نوشته ها بر روی حافظه ی فلش ذخیره شوند.

Serial.print(F("Write something on the Serial Monitor that is stored in FLASH"));

 

دیدگاه ها :

من بات نیستم

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *