本方法只適用于使用AVR作為核心的Arduino!
閃存(程序)內(nèi)存而不是SRAM存儲數(shù)據(jù)。有各種類型的可用內(nèi)存的描述上的Arduino板。
該PROGMEM關鍵字是一個可變調(diào)節(jié)劑,但只應在pgmspace.h定義的數(shù)據(jù)類型使用。它告訴編譯器“把這個信息到閃存”,而不是到SRAM,它通常會去。
PROGMEM是pgmspace.h庫僅在AVR架構可用的一部分。所以,你首先需要包含庫頂部草圖,就像這樣:
[mw_shl_code=cpp,true]#include <avr/pgmspace.h>[/mw_shl_code]
使用語法:
[mw_shl_code=cpp,true]const dataType variableName[] PROGMEM = {data0, data1, data3...};[/mw_shl_code]
dataType 任何變量類型
variableName 數(shù)組名稱
請注意,因為PROGMEM是一個可變的調(diào)節(jié)劑,也沒有嚴格的,它應該走的快規(guī)律,Arduino的編譯器接受以下所有的定義,這也是代名詞。然而實驗已經(jīng)表明,在Arduino的各種版本(具有用GCC版本做),PROGMEM可以在一個位置,而不是工作在另一!白址怼毕旅娴睦右呀(jīng)過測試,Arduino的合作13. IDE的早期版本可能更好地工作,如果PROGMEM的變量名后包括在內(nèi)。
[mw_shl_code=cpp,true]const dataType variableName[] PROGMEM = {}; // use this form
const PROGMEM dataType variableName[] = {}; // or this form
const dataType PROGMEM variableName[] = {}; // not this one[/mw_shl_code]
雖然PROGMEM可以在單個變量使用,真的是唯一值得大驚小怪的,如果你有更大的數(shù)據(jù)塊需要存儲,這通常是最容易在數(shù)組中(或其他C數(shù)據(jù)結構超出了我們現(xiàn)在的討論)。
使用PROGMEM也是一個兩步過程。獲取數(shù)據(jù)到閃存后,它需要特殊的方法(函數(shù)),在pgmspace.h庫還規(guī)定,從程序存儲器中的數(shù)據(jù)讀回SRAM,所以我們可以做一些有用的事情吧。
示例程序:
下面的代碼片段說明了如何讀取和寫入字符(字節(jié))和int(2字節(jié))PROGMEM。
[mw_shl_code=cpp,true]#include <avr/pgmspace.h>
// 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;
int k; // counter variable
char myChar;
void setup() {
Serial.begin(9600);
while (!Serial);
// put your setup code here, to run once:
// read back a 2-byte int
for (k = 0; k < 5; k++)
{
displayInt = pgm_read_word_near(charSet + k);
Serial.println(displayInt);
}
Serial.println();
// read back a char
int len = strlen_P(signMessage);
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(signMessage + k);
Serial.print(myChar);
}
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
}[/mw_shl_code]
字符串數(shù)組
用大量的文字,如配有液晶顯示器的一個項目工作時,設置一個字符串數(shù)組它往往是方便。因為字符串本身是數(shù)組,這是在實際的二維陣列的實例。
這些往往是這樣把它們放入程序存儲器經(jīng)常需要大的結構。下面的代碼說明了這個想法。
[mw_shl_code=cpp,true]/*
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);
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))); // Necessary casts and dereferencing, just copy.
Serial.println(buffer);
delay( 500 );
}
}[/mw_shl_code]
注意事項
請注意,必須使用全局變量定義flash存儲的數(shù)據(jù),或者用static關鍵字定義,這樣才能使PROGMEM正常工作。
如果在一個函數(shù)中使用如下方式定義,PROGMEM將無法正常工作:
[mw_shl_code=cpp,true]const char long_str[] PROGMEM = "Hi, I would like to tell you a bit about myself.\n";[/mw_shl_code]
要作為局部變量定義,必須添加static 關鍵字,如:
[mw_shl_code=cpp,true]const static char long_str[] PROGMEM = "Hi, I would like to tell you a bit about myself.\n"[/mw_shl_code]
F()宏
通常我們都使用如下語句,進行串口輸出:
[mw_shl_code=cpp,true]Serial.print("Write something on the Serial Monitor");[/mw_shl_code]
但這樣使用,每次調(diào)用時,都會先將數(shù)據(jù)保存在RAM中。當我們要輸出長的字符串時,就會占用很多的RAM空間。使用F()就可以很好的解決這個問題:
[mw_shl_code=cpp,true]Serial.print(F("Write something on the Serial Monitor that is stored in FLASH"));[/mw_shl_code]
承擔因您的行為而導致的法律責任,
本站有權保留或刪除有爭議評論。
參與本評論即表明您已經(jīng)閱讀并接受
上述條款。