Arduino UNO R3主處理器ATMega328P的芯片內部擁有3種存儲器:數據存儲器,程序存儲器和電可擦寫可編程存儲器;它們各自有不一樣的用途。編程
數據存儲器是一塊2KB大小的靜態隨機存儲器(SRAM)。其中一部分空間分配給了通用寄存器和I/O寄存器,其他部分通常用於存儲全局變量,堆棧數據和支持動態內存分配。它的存取速度快,但掉電後數據會丟失。函數
程序存儲器是一塊32KB大小的閃存(Flash),其中0.5KB用於引導程序。它能夠屢次擦寫,掉電後數據不會丟失,通常用於存儲程序。oop
電可擦寫可編程只讀存儲器(EEPROM)是一塊1KB大小的獨立數據存儲空間。它和程序存儲器同樣能夠用於保存程序運行中的數據,但在掉電後數據不會丟失。ui
Arduino IDE提供了幾個EEPROM的示例,eeprom_write示例將0引腳上的模擬信號轉換爲數字信號,並將轉換結果以字節的形式保存到EEPROM中:spa
1 // eeprom_write.ino 2 #include <EEPROM.h> 3 4 int addr = 0; 5 6 void setup() { 7 } 8 9 void loop() { 10 int val = analogRead(0) / 4; 11 12 EEPROM.write(addr, val); 13 14 addr = addr + 1; 15 if (addr == EEPROM.length()) { 16 addr = 0; 17 } 18 19 delay(100); 20 }
和eeprom_write示例相反,eeprom_read示例將EEPROM中的數據以字節的形式讀出,並打印到串口0上:code
1 // eeprom_read.ino 2 #include <EEPROM.h> 3 4 int address = 0; 5 byte value; 6 7 void setup() { 8 Serial.begin(9600); 9 while (!Serial) { 10 ; 11 } 12 } 13 14 void loop() { 15 value = EEPROM.read(address); 16 17 Serial.print(address); 18 Serial.print("\t"); 19 Serial.print(value, DEC); 20 Serial.println(); 21 22 address = address + 1; 23 if (address == EEPROM.length()) { 24 address = 0; 25 } 26 27 delay(500); 28 }
與EEPROM相關的Arduino庫函數有:blog
EEPROM.write(address, val):向EEPROM指定地址寫入一個字節的數據內存
address:指定數據寫入的地址it
val:寫入的數據table
EEPROM.read(address):從EEPROM指定地址讀出一個字節的數據
address:指定數據讀取的地址
函數返回讀取的一個字節數據
EEPROM.length():獲取EEPROM大小
函數返回EEPROM的大小
ATMega328P的EEPROM由3個寄存器控制,EEPROM地址寄存器(EEARH和EEARL)和EEPROM數據寄存器EEDR分別用於在寫入或讀取EEPROM時保存地址信息和數據信息。EEPROM控制寄存器EECR的結構以下圖所示:
|
|
EEPM1 |
EEPM0 |
EERIE |
EEMPE |
EEPE |
EERE |
將EEPROM主機寫使能位EEMPE置1後,4個時鐘週期內將EEPROM寫使能位EEPE置1,就能夠數據寫入EEPROM的指定地址中;向EEPROM讀使能位EERE寫入1,則能夠將EEPROM指定地址的數據讀入EEDR寄存器中。
經過直接訪問寄存器改寫以上程序爲:
1 // eeprom_write_reg.ino 2 #include <EEPROM.h> 3 4 int addr = 0; 5 void eeprom_write(int address, byte val); 6 7 void setup() { 8 } 9 10 void loop() { 11 int val = analogRead(0) / 4; 12 13 eeprom_write(addr, val); 14 15 addr = addr + 1; 16 if (addr == EEPROM.length()) { 17 addr = 0; 18 } 19 20 delay(100); 21 } 22 23 void eeprom_write(int address, byte val) { 24 while (EECR & (1 << EEPE)); 25 EEAR = address; 26 EEDR = val; 27 EECR |= (1 << EEMPE); 28 EECR |= (1 << EEPE); 29 } 30 31 // eeprom_read.ino 32 #include <EEPROM.h> 33 34 int address = 0; 35 byte value; 36 byte eeprom_read(int address); 37 38 void setup() { 39 Serial.begin(9600); 40 while (!Serial) { 41 ; 42 } 43 } 44 45 void loop() { 46 value = eeprom_read(address); 47 48 Serial.print(address); 49 Serial.print("\t"); 50 Serial.print(value, DEC); 51 Serial.println(); 52 53 address = address + 1; 54 if (address == EEPROM.length()) { 55 address = 0; 56 } 57 58 delay(500); 59 } 60 61 byte eeprom_read(int address) { 62 while (EECR & (1 << EEPE)); 63 EEAR = address; 64 EECR |= (1 << EERE); 65 return EEDR; 66 }