pp.381ff.
avr/pgmspace.h
ライブラリーを使う。定数データをフラッシュメモリーへ書き込むときはPROGMEM
マクロを、そのデータを読み出すときはpgm_read_byte()
、pgm_read_word()
を使う。
const 型 変数名 PROGMEM = 値;
と記述すると、値はRAMには格納されずにプログラム領域(フラッシュメモリー)に格納される。- 1バイトデータは
pgm_read_byte(アドレス);
で読み出す。 - 2バイトデータは
pgm_read_word(アドレス);
で読み出す。
PROGMEMは不揮発性であり、プログラムメモリーに存在し続ける。だからどのサブルーチンからでも利用できる。したがってPROGMEMはグローバル変数であり、グローバル名前空間で宣言すべきである。すなわちPROGMEM変数は、函数定義の外側で宣言すべきである。そうすれば、PROGMEM変数のスコープが何か特定の函数に限定されていないことと、PROGMEM変数に格納されたデータへはどの函数からでもアクセスできることとがコンパイラーに知らせられる。
著者によれば、PROGMEMのデータは全部別のヘッダーファイルに定義するのが一番簡単との由。
#define F_CPU 1000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #include "USART.h" // 長い文字列定数をフラッシュメモリーに格納してみる。 const char myVeryLongString[] PROGMEM = "\n\"It\'s very reasonable. We agreed on the rate before I started the job. And if anything, it\'s an underestimate. If you feel dissatisfied, I suggest you go to another agency or the Better Business people and ask whether they feel the rate is unreasonable for the job.\" How long did she think eighty-two dollars kept a private detective going? With an office to hire. With a daughter to feed.\n"; int main(){ initUSART(); char oneLetter; while(1){ for(uint16_t i=0; i<sizeof(myVeryLongString); i++){ oneLetter = pgm_read_byte(&(myVeryLongString[i])); // 文字列を1文字ずつ表示する。pgm_read_byte()の引数はアドレス。 transmitByte(oneLetter); _delay_ms(10); } _delay_ms(1000); } return 0; }