2017年3月17日 星期五

[Arduino] EEPROM


EEPROM,或寫作E2PROM,全稱電子抹除式可複寫唯讀記憶體 (英語:Electrically-
Erasable Programmable Read-Only Memory),是一種可以通過電子方式多次複寫的半導
體存儲裝置。相比EPROM,EEPROM不需要用紫外線照射,也不需取下,就可以用特定的
電壓,來抹除晶片上的資訊,以便寫入新的資料。

EEPROM有四種工作模式:讀取模式、寫入模式、擦拭模式、校驗模式。
讀取時,晶片只需要Vcc低電壓(一般+5V)供電。編程寫入時,
晶片通過Vpp(一般+25V, 較新者可能使用 12V 或 5V)獲得編程電壓,
並通過PGM編程脈衝(一般50ms)寫入資料。擦拭時,只需使用Vpp高電壓,
不需要紫外線,便可以擦拭指定位址的內容。為保證寫入正確,在每寫入一塊資料後,
都需要進行類似於讀取的校驗步驟,若錯誤就重新寫入。
現今的 EEPROM 通常已不再需要使用額外的 Vpp 電壓,且寫入時間也已有縮短。


以上資料來源:

電子抹除式可複寫唯讀記憶體https://zh.wikipedia.org/wiki/%E9%9B%BB%E5%AD%90%E6%8A%B9%E9%99%A4%E5%BC%8F%E5%8F%AF%E8%A4%87%E5%AF%AB%E5%94%AF%E8%AE%80%E8%A8%98%E6%86%B6%E9%AB%94


在Arduino的微控器晶片內,其實有0.5KB到4KB不等的EEPROM記憶體(視MCU不同而有差異),可以用來儲存一些斷電後仍要留存的資料。

EEPROM 有寫入次數的限制,ATmega 系列微控制器的 EEPROM 其每一個位置大約只能寫入 10 萬次,在使用的時候,最好盡量公平對待 EEPROM 的每一塊空間,不要對特定一個位置一直寫入,如果頻繁地使用固定的一塊位置,那麼該塊空間壽命會急速縮短。

以下是不同Arduino Chip EEPROM大小

Chip Sizp
ATmega328 1024 bytes
ATmega168 512 bytes
ATmega8 1024 bytes
ATmega1280 4KB (4096 bytes)
ATmega2560 4KB (4096 bytes)

參考資料來源:
http://coopermaa2nd.blogspot.tw/2010/12/arduino-eeprom.html
以下是EEPROM API

  • EEPROM Clear: Clear the bytes in the EEPROM. 
  • 清除所有EEPROM資料(所以位址都將使用了一次)
  • EEPROM Read: Read the EEPROM and send its values to the computer.
  • 讀取指定的位址(一個byte)
  • EEPROM Write: Stores values from an analog input to the EEPROM.
  • 把資料寫入指定的位址(一個byte)
  • EEPROM Crc: Calculates the CRC of EEPROM contents as if it was an array.
  • 計算整個EEPROM的CRC ,確認資料是否正確。
  • EEPROM Get: Get values from EEPROM and prints as float on serial.
  • 一次取得n個byte的資料,例如float是4個byte。
  • EEPROM Iteration: Understand how to go through the EEPROM memory locations.
  • 說明如何透過EEPROM儲存資料。
  • EEPROM Put: Put values in EEPROM using variable semantics.
  • 一次放入n個byte的資料,例如我可以直接把float寫入連入4個byte。
  • EEPROM Update: Stores values read from A0 into EEPROM, writing the value only if different, to increase EEPROM life.
  • update和write不同在於,如果此位址中的資料和欲寫入的相同,則不寫,節省一次EEPROM位址的存取。

參考資料來源:

http://makerpro.cc/2015/05/arduino%CA%BBs-new-eeprom-libraries/
要使用EEPROM,必須引入EEPROM.h

首先我們先來取得一下EEPROM大小

#include <EEPROM.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

 Serial.print("EEPROM length: ");
 Serial.println(EEPROM.length());
 
   
}

void loop() {
  // put your main code here, to run repeatedly:

}

執行結果

























寫入位置0,再讀取位址0
#include <EEPROM.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);


  
  EEPROM.write(0,10);

  byte b=EEPROM.read(0);

  Serial.println(b);
}

void loop() {
  // put your main code here, to run repeatedly:

}

執行結果












接下來我們把寫入那行註解起來,上傳程式碼,然候我們斷電再接上看看。


#include <EEPROM.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);


  
  //EEPROM.write(0,10);

  byte b=EEPROM.read(0);

  Serial.println(b);
}

void loop() {
  // put your main code here, to run repeatedly:

}

執行結果。























接下來我們來試試put和get


#include <EEPROM.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);


  
  //EEPROM.write(0,10);

  byte b=EEPROM.read(0);

  Serial.println(b);


  float pi=3.14159;
  EEPROM.put(2,pi);

  float readfloat=0;
  
  EEPROM.get(2,readfloat);
  Serial.println(readfloat);
  
}

void loop() {
  // put your main code here, to run repeatedly:

}

執行結果,看起來float寫入EEPROM有精度問題,只能存4個byte,3.14159只能寫入3.14




























沒有留言:

張貼留言