AVR開發 Arduino方法(六) 內存子系統

  Arduino UNO R3主處理器ATMega328P的芯片內部擁有3種存儲器:數據存儲器,程序存儲器和電可擦寫可編程存儲器;它們各自有不一樣的用途。編程

1. 數據存儲器

  數據存儲器是一塊2KB大小的靜態隨機存儲器(SRAM)。其中一部分空間分配給了通用寄存器和I/O寄存器,其他部分通常用於存儲全局變量,堆棧數據和支持動態內存分配。它的存取速度快,但掉電後數據會丟失。函數

2. 程序存儲器

  程序存儲器是一塊32KB大小的閃存(Flash),其中0.5KB用於引導程序。它能夠屢次擦寫,掉電後數據不會丟失,通常用於存儲程序。oop

3. 電可擦可編程只讀存儲器

  電可擦寫可編程只讀存儲器(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的大小

 

  ATMega328PEEPROM3個寄存器控制,EEPROM地址寄存器(EEARHEEARLEEPROM數據寄存器EEDR分別用於在寫入或讀取EEPROM時保存地址信息和數據信息。EEPROM控制寄存器EECR的結構以下圖所示:

 

 

EEPM1

EEPM0

EERIE

EEMPE

EEPE

EERE

EEPROM主機寫使能位EEMPE1後,4個時鐘週期內將EEPROM寫使能位EEPE1,就能夠數據寫入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 }
相關文章
相關標籤/搜索