PROGMEM 키워드 사용법

 

PROGMEM

 

PROGMEM 키워드는 데이터를 SRAM 대신 Flash(Program) 메모리에 생성하는 키워드입니다. PROGMEM 은 변수 앞에 사용할 수 있는 키워드로 pgmspace.h 파일에 선언된 데이터 타입에만 적용할 수 있습니다. 이 키워드를 사용한다는 것은 컴파일러에게 “이 변수를 일반적으로 사용하는 SRAM 대신 Flash 메모리에 저장하라”고 지시하는 것과 유사합니다.

 

PROGMEM 키워드는 pgmspace.h 라이브러리의 일부이기 때문에 사용하기 전에, 스케치 최 상단에 아래와 같은 선언문을 넣어줘야 합니다. (최신 아두이노 IDE 에서는 이 과정이 없어도 사용할 수 있습니다. 오히려 사용할 경우 일부 라이브러리와 충돌을 일으킬 수도 있는듯 합니다.)

#include <avr/pgmspace.h>

 

 

PROGMEM 사용방법

 

PROGMEM 키워드를 사용하는 일반적인 방법은 아래와 같습니다.

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

변수를 선언할 때 PROGMEM 키워드를 넣는 위치는 유연하게 조정할 수 있습니다. 다만 아두이노 IDE 버전에 따라 컴파일러인 GCC 버전이 틀리고, GCC 버전에 따라 특정 위치가 아니면 에러를 발생할 수도 있습니다. 이 때는 적절히 위치를 조정해줘야 합니다.

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

배열이 아닌 형태의 변수에도 PROGMEM 키워드를 사용할 수 있습니다.

 

PROGMEM 키워드로 변수를 선언할 때와 마찬가지로 PROGMEM 으로 선언된 변수를 사용할 때도 특별한 방법을 이용해야 합니다. 변수를 사용하기 위한 별도의 함수가 pgmspace.h 에 선언되어 있으므로 이 파일을 참고하세요. 아래 예제에서 자세한 사용방법을 확인하실 수 있습니다.

 

PROGMEM 키워드를 적용할 수 있는 데이터 타입은 아래와 같습니다. (실수형 변수는 사용 불가)

prog_char          – a signed char (1 byte) -127 to 128
prog_uchar       – an unsigned char (1 byte) 0 to 255
prog_int16_t    – a signed int (2 bytes) -32,767 to 32,768
prog_uint16_t  – an unsigned int (2 bytes) 0 to 65,535
prog_int32_t    – a signed long (4 bytes) -2,147,483,648 to * 2,147,483,647.
prog_uint32_t  – an unsigned long (4 bytes) 0 to 4,294,967,295

 

 

예제

 

아래 코드는 char 배열(문자열)과 int 배열(정수 배열)을 PROGMEM 키워드로 선언해서 사용하는 방법입니다.

#include <avr/pgmspace.h>


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

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

unsigned int displayInt;
int k;    // counter variable
char myChar;  

// read back a 2-byte int
 displayInt = pgm_read_word_near(charSet + k)

// read back a char 
myChar =  pgm_read_byte_near(signMessage + k);

 

C 에서 문자열은 char 형 배열입니다. 이런 문자열의 묶음, 즉 문자열 배열을 생성할 경우도 PROGMEM을 응용해서 사용할 수 있습니다. 아래 코드를 참고하세요.

/*
 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>
prog_char string_0[] PROGMEM = "String 0";   // "String 0" etc are strings to store - change to suit.
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";


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

PROGMEM const char *string_table[] = 	   // change "string_table" name to suit
{   
  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);
}


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 );
  }
}

 

You may also like...