متغیر هایی از نوع PROGMEM در کامپایلر GCC

  • نویسنده موضوع Alma
  • تاریخ شروع

Alma

مدیر
پرسنل مدیریت
شاید برای شما هم پیش اومده باشه که وقتی از متغیر ها یاجدول های بزرگی مثل فونت ها استفاده میکنید در صورتی که این متغیر حتی اگر به صورت const هم تعریف شده باشه رم رو مشغول میکنه و در واقع اگر شما نیاز به یک بایت اون داشته باشید کل متغیر در حافظه رم قرار خواهد گرفت

برای رفع این مشکل باید متغیر رو از نوع فلش PROGMEM تعریف کرد و مقدار اون رو در صورت نیاز از ادرسی که در اختیار قرار میگیره خوند در این صورت همه متغیر ی رشته در رم قرار نمیگیره بلکه فقط مقداری از اون که نیاز هست و خونده شده

برای این منظور بایدابتدا فایل pgmspace.h رو وارد برنامه کنیم

کد:
#include "pgmspace.h"

حالا یه رشته از نوع PROGMEM تعریف میکنیم برای مثال اینجا قراره یه فونت 8x8 تعریف کنیم

کد:
const  char f8x8b[] PROGMEM = {
    0x08,0x08,0x00,0x80,0x00,0x00,0x00,0x00 ,
    0x7E,0x81,0x95,0xB1,0xB1,0x95,0x81,0x7E ,
    0x7E,0xFF,0xEB,0xCF,0xCF,0xEB,0xFF,0x7E ,
    0x0E,0x1F,0x3F,0x7E,0x3F,0x1F,0x0E,0x00 ,
    0x08,0x1C,0x3E,0x7F,0x3E,0x1C,0x08,0x00 ,
    0x38,0x38,0x9F,0xFF,0x9F,0x38,0x38,0x00 ,
    0x10,0x38,0xBC,0xFF,0xBC,0x38,0x10,0x00 ,
    0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00 ,
    0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF ,
    0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00 ,
    0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF ,
    0x70,0x88,0x88,0x88,0x89,0x7D,0x03,0x0F ,
    0x00,0x4E,0x51,0xF1,0xF1,0x51,0x4E,0x00 ,
    0xC0,0xE0,0x7F,0x05,0x05,0x05,0x05,0x07 ,
    0xC0,0xE0,0x7F,0x05,0x05,0x65,0x75,0x3F ,
    0x5A,0x5A,0x3C,0xE7,0xE7,0x3C,0x5A,0x5A ,
    0x7F,0x3E,0x3E,0x1C,0x1C,0x08,0x08,0x00 ,
    0x08,0x08,0x1C,0x1C,0x3E,0x3E,0x7F,0x00 ,
    0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00 ,
    0x00,0x00,0x5F,0x00,0x00,0x5F,0x00,0x00 ,
    0x06,0x09,0x09,0x7F,0x01,0x01,0x7F,0x01 ,
    0x40,0xDA,0xA7,0xA5,0xE5,0x59,0x03,0x02 ,
    0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x00 ,
    0x80,0x94,0xB6,0xFF,0xFF,0xB6,0x94,0x80 ,
    0x00,0x0C,0x06,0x7F,0x06,0x0C,0x00,0x00 ,
    0x00,0x18,0x30,0x7F,0x30,0x18,0x00,0x00 ,
    0x08,0x08,0x08,0x2A,0x3E,0x1C,0x08,0x00 ,
    0x08,0x1C,0x3E,0x2A,0x08,0x08,0x08,0x00 ,
    0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x00 ,
    0x08,0x1C,0x3E,0x08,0x08,0x3E,0x1C,0x08 ,
    0x30,0x38,0x3C,0x3E,0x3C,0x38,0x30,0x00 ,
    0x06,0x0E,0x1E,0x3E,0x1E,0x0E,0x06,0x00 ,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
    0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x00 ,
    0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00 ,
    0x00,0x14,0x7F,0x14,0x14,0x7F,0x14,0x00 ,
    0x00,0x24,0x2A,0x6B,0x6B,0x2A,0x12,0x00 ,
    0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00 ,
    0x30,0x4A,0x45,0x4D,0x32,0x48,0x48,0x00 ,
    0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x00 ,
    0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00 ,
    0x00,0x00,0x41,0x22,0x1C,0x00,0x00,0x00 ,
    0x08,0x2A,0x1C,0x1C,0x1C,0x2A,0x08,0x00 ,
    0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00 ,
    0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00 ,
    0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00 ,
    0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00 ,
    0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x00 ,
    0x00,0x3E,0x61,0x51,0x49,0x45,0x3E,0x00 ,
    0x00,0x44,0x42,0x7F,0x40,0x40,0x00,0x00 ,
    0x00,0x62,0x51,0x51,0x49,0x49,0x66,0x00 ,
    0x00,0x22,0x41,0x49,0x49,0x49,0x36,0x00 ,
    0x10,0x18,0x14,0x52,0x7F,0x50,0x10,0x00 ,
    0x00,0x27,0x45,0x45,0x45,0x45,0x39,0x00 ,
    0x00,0x3C,0x4A,0x49,0x49,0x49,0x30,0x00 ,
    0x00,0x03,0x01,0x71,0x09,0x05,0x03,0x00 ,
    0x00,0x36,0x49,0x49,0x49,0x49,0x36,0x00 ,
    0x00,0x06,0x49,0x49,0x49,0x29,0x1E,0x00 ,
    0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x00 ,
    0x00,0x00,0x80,0x66,0x00,0x00,0x00,0x00 ,
    0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00 ,
    0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00 ,
    0x00,0x00,0x00,0x41,0x22,0x14,0x08,0x00 ,
    0x00,0x02,0x01,0x01,0x51,0x09,0x06,0x00 ,
    0x00,0x3E,0x41,0x5D,0x55,0x55,0x1E,0x00 ,
    0x00,0x7C,0x12,0x11,0x11,0x12,0x7C,0x00 ,
    0x00,0x41,0x7F,0x49,0x49,0x49,0x36,0x00 ,
    0x00,0x1C,0x22,0x41,0x41,0x41,0x22,0x00 ,
    0x00,0x41,0x7F,0x41,0x41,0x22,0x1C,0x00 ,
    0x00,0x41,0x7F,0x49,0x5D,0x41,0x63,0x00 ,
    0x00,0x41,0x7F,0x49,0x1D,0x01,0x03,0x00 ,
    0x00,0x1C,0x22,0x41,0x51,0x51,0x72,0x00 ,
    0x00,0x7F,0x08,0x08,0x08,0x08,0x7F,0x00 ,
    0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0x00 ,
    0x00,0x30,0x40,0x40,0x41,0x3F,0x01,0x00 ,
    0x00,0x41,0x7F,0x08,0x14,0x22,0x41,0x40 ,
    0x00,0x41,0x7F,0x41,0x40,0x40,0x60,0x00 ,
    0x00,0x7F,0x01,0x02,0x04,0x02,0x01,0x7F ,
    0x00,0x7F,0x01,0x02,0x04,0x08,0x7F,0x00 ,
    0x00,0x3E,0x41,0x41,0x41,0x41,0x3E,0x00 ,
    0x00,0x41,0x7F,0x49,0x09,0x09,0x06,0x00 ,
    0x00,0x1E,0x21,0x21,0x31,0x21,0x5E,0x40 ,
    0x00,0x41,0x7F,0x49,0x19,0x29,0x46,0x00 ,
    0x00,0x26,0x49,0x49,0x49,0x49,0x32,0x00 ,
    0x00,0x03,0x01,0x41,0x7F,0x41,0x01,0x03 ,
    0x00,0x3F,0x40,0x40,0x40,0x40,0x3F,0x00 ,
    0x00,0x0F,0x10,0x20,0x40,0x20,0x10,0x0F ,
    0x00,0x3F,0x40,0x40,0x38,0x40,0x40,0x3F ,
    0x00,0x41,0x22,0x14,0x08,0x14,0x22,0x41 ,
    0x00,0x01,0x02,0x44,0x78,0x44,0x02,0x01 ,
    0x00,0x43,0x61,0x51,0x49,0x45,0x43,0x61 ,
    0x00,0x7F,0x41,0x41,0x41,0x00,0x00,0x00 ,
    0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x00 ,
    0x00,0x41,0x41,0x41,0x7F,0x00,0x00,0x00 ,
    0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00 ,
    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 ,
    0x00,0x00,0x00,0x03,0x04,0x00,0x00,0x00 ,
    0x00,0x20,0x54,0x54,0x54,0x54,0x78,0x40 ,
    0x00,0x01,0x7F,0x30,0x48,0x48,0x48,0x30 ,
    0x00,0x38,0x44,0x44,0x44,0x44,0x28,0x00 ,
    0x00,0x30,0x48,0x48,0x48,0x31,0x7F,0x40 ,
    0x00,0x38,0x54,0x54,0x54,0x54,0x18,0x00 ,
    0x00,0x00,0x48,0x7E,0x49,0x01,0x02,0x00 ,
    0x00,0x98,0xA4,0xA4,0xA4,0xA4,0x78,0x04 ,
    0x00,0x41,0x7F,0x08,0x04,0x04,0x78,0x00 ,
    0x00,0x00,0x44,0x7D,0x40,0x00,0x00,0x00 ,
    0x00,0x60,0x80,0x80,0x80,0x84,0x7D,0x00 ,
    0x00,0x01,0x7F,0x10,0x28,0x44,0x40,0x00 ,
    0x00,0x00,0x41,0x7F,0x40,0x00,0x00,0x00 ,
    0x00,0x7C,0x04,0x04,0x78,0x04,0x04,0x78 ,
    0x00,0x7C,0x08,0x04,0x04,0x04,0x78,0x00 ,
    0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00 ,
    0x00,0x84,0xFC,0x98,0x24,0x24,0x18,0x00 ,
    0x00,0x18,0x24,0x24,0x98,0xFC,0x84,0x00 ,
    0x00,0x44,0x7C,0x48,0x04,0x04,0x18,0x00 ,
    0x00,0x48,0x54,0x54,0x54,0x54,0x24,0x00 ,
    0x00,0x04,0x04,0x3F,0x44,0x44,0x20,0x00 ,
    0x00,0x3C,0x40,0x40,0x40,0x20,0x7C,0x00 ,
    0x00,0x0C,0x10,0x20,0x40,0x20,0x10,0x0C ,
    0x00,0x3C,0x40,0x40,0x38,0x40,0x40,0x3C ,
    0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00 ,
    0x00,0x9C,0xA0,0xA0,0xA0,0xA0,0x7C,0x00 ,
    0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00 ,
    0x00,0x08,0x08,0x36,0x41,0x41,0x00,0x00 ,
    0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x00 ,
    0x00,0x00,0x41,0x41,0x36,0x08,0x08,0x00 ,
    0x00,0x02,0x01,0x01,0x02,0x02,0x01,0x00
};


همونطوری که مشاهده میکنید رشته ما از نوع PROGMEM تعریف شده
برای خوندن از این رشته هم باید از ماکرو pgm_read_byte استفاده کنیم یعنی نمیشه به صورت معمولی از این رشته استفاده کرد لذا به این صورت عمل میکنیم

کد:
for(uint8_t i=0; i<8; i++)str[i] = pgm_read_byte(&f8x8b[(' ' - 'A') * 8 + i]);

upload_2019-1-27_14-56-50.png

همونطوری که در تصویر فوق مشاهده میکنید در صورتی که متغیر از نوع PROGMEM نباشه 98.4 درصد از رم اشغال میشه اما وقتی از نوع PROGMEM باشه حتی یک بایت از رم هم اشغال نخواهد شد

upload_2019-1-27_14-55-23.png

توجه داشته باشید

دلیل اینکه هیچ رمی اشغال نمیشه اینه که کامپایلر فقط از ادرس و اشاره گر استفاده میکنه
در واقع وقتی متغیری از نوع PROGMEM تعریف میکنیم اشاره گری به ادرس خاصی از حافظه فلش که مقدار دهی شده تعریف کردیم
 

saeeddelshad0020

همکار
ممنون مهندس عالی بود....یعنی ما بخوایم اکثر متغیر هامون رو با این روش اشاره گر بنویسیم و به ادرسش اشاره کنیم حجم رم ما خیلی میاد پایین درسته؟
 

Alma

مدیر
پرسنل مدیریت
ممنون مهندس عالی بود....یعنی ما بخوایم اکثر متغیر هامون رو با این روش اشاره گر بنویسیم و به ادرسش اشاره کنیم حجم رم ما خیلی میاد پایین درسته؟
دوست عزیز وقتی شما هر متغیری رو صدا میکنید کل اون متغیر در رم قرار میگیره
حالا اگر این متغیر یه رشته خیلی بزرگ مثل یه دیتای فونت یا موارد مشابه باشه کل متغیر در رم قرار خواهد گرفت که باعث اشغال رم میشه در صورتی که فقط به چند بایت اون نیاز هست
 

EHSAN1082

همکار
حرف نداره _ مهندس کی نژاد هم اشاره کرده بودن اما توضیحات شما فهم ما را بیشتر کرد
 
بالا پایین