上一篇介紹過了I2C的基本原理以及相關的函數,這一篇會介紹EEPROM來做為I2C實作的示範。
什麼是EEPROM?
全名是電子抹除式可複寫唯讀記憶體,他是一種唯讀記憶體(ROM)可以透過程式去多次的寫入資料,同時斷電後不會清出資料。如果需清除資料可以在特定電壓下來清除資料,重新的寫入。
這一次使用的是AT24C256B EEPROM,它的特點如下
- 使用I2C介面
- 儲存容量256kbit (1 page 32K * 8)
- 硬體寫入保護
接下來來看一下腳位如何連接:
- VCC : 連接5V
- WP : 寫入保護 可以不用接(WP = 1 禁止寫入)
- SCL : 時鐘線 連接到開發板上的SCL (PB6)
- SDA : 資料線 連接到開發板上的SDA (PB7)
- A0 A1 A2 : 每一個I2C設備都有它專屬的地址在這為 1 0 1 0 A2 A1 A0 R/W,假設都不接的話地址為 1 0 1 0 0 0 0 R/W
- GND : 接地
時序
- 資料有效性 : 當SCL = 1時資料穩定 SDA不可更動 ; SCL = 0時資料混亂可進行資料交換
- 起始與結束信號
//I2C Start
SDA = 1;
delay();
SCL = 1;
delay();
SDA = 0;
delay();
SCL = 0;
delay();
//I2C Stop
SDA = 0;
delay();
SCL = 1;
delay();
SDA = 1;
delay();
- ACK : 下圖可以看到當EEPROM在接收到完整8bit訊息後,會在第9個bit去輸出ACK。
設備地址
上圖是AT24C256B的設備地址,前面有提到前4bit是設備固定的地址無法更動。可以更動後方A2-A0來改變地址,最多可以接上8個。
R/W : 指的是Read / Write 會接續在地址後方,透過R/W bit 可以告知EEPROM這一次的指令是要讀取還是寫入資料。 ( R = 1 , W = 0)
如何對AT24C256B寫入
- Byte write : 一次只寫入一個byte的資料量
上圖為Byte Write的說明我們把它拆解成以下步驟 :
- 先發送起始信號
- 設備定址(1 0 1 0 A2 A1 A0 0),因為是寫入所以最後的R/W會是0。
- 輸出一個ACK (這時Master可以去讀取看看有沒有ACK的回覆)
- 接上第一個寫入地址
- ACK
- 第二個寫入地址
- ACK
- 要寫入的資料
- ACK
- 結束信號
這邊先說明一下寫入地址是什麼?
上圖可以看到AT24C256B的儲存空間是分為512頁且每一頁有64Byte。
First word address : 可以把它理解成頁數
Second word address : 可以把它理解成第幾頁當中的第幾個字
根據上面說的 512頁*64個字,而兩地址總共為15bit。(0-511)(0-63)
2^9 = 512頁 2^6 = 64個字所以在Second Word Address低6bit就是頁內地址而其餘的就是頁數地址。
舉例來說假如我們要寫第3頁的第2個位置就會是 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0
- Page Write : 一次寫入一整頁的64bytes
上圖為Page Write的說明我們把它拆解成以下步驟 :
- 先發送起始信號
- 設備定址(1 0 1 0 A2 A1 A0 0),因為是寫入所以最後的R/W會是0。
- 接上第一個寫入地址
- ACK
- 第二個寫入地址
- ACK
- 持續寫入n資料(0≤n≤63),每一筆資料會接一個ACK
- 停止信號
這邊要注意假設原先這一頁已有資料,後續超過的資料將覆蓋到同頁前面的資料並不會換頁。
如何對AT24C256B讀取
讀取分為三種方式: 當前地址讀取、隨機地址讀取、順序讀取
- 當前地址讀取 : AT24C256B會保存上一次讀or寫的地址,透過這個方式會去讀取n+1的位置。要注意假設是該頁最後一個位置會翻轉地址回到第一個地址。舉例來說假設上次寫入 0 page 1 word 那使用當前地址讀取就會讀到0 page 2 word的資料。
- 先發送起始信號
- 接上設備地址(1 0 1 0 A2 A1 A0 1),因為讀取所以最後的R/W會是1。
- ACK
- 這時會帶回該地址的資料
- NACK (SDA = 1)
- 發送停止信號
- 隨機地址讀取 : 下圖有一段是Dummy Write 在這過程其實是去寫入一個地址改變AT24C256B所儲存的上一次讀寫地址,接著透過當前地址讀的方法讀取資料。
- 先發送起始信號
- 設備地址(1 0 1 0 A2 A1 A0 0 ),因為是寫入所以最後的R/W會是0。(要寫入地址資料)
- ACK
- 寫入一個地址去改變AT24C256B的上一次地址
- ACK
上方5個步驟是Dunny Write的拆解
- 再發送一次起始信號(開始當前位置讀的步驟)
- 設備地址(1 0 1 0 A2 A1 A0 1),因為讀取所以最後的R/W會是1。
- ACK
- 帶回讀取到的資料
- NACK
- 結束信號
- 連續讀取 : 啟動方式由隨機地址讀取與當前地址讀取來啟動,當每讀到一筆資料回覆給EEPROM一個ACK,就可以持續讀取資料。同樣當讀取到最後一筆時會把地址翻轉回第一個。
- 起始信號
- 設備地址(1 0 1 0 A2 A1 A0 0 ),因為是寫入所以最後的R/W會是0。
- ACK
- 寫入頁地址
- ACK
- 頁內地址
- ACK
- 再發送一次起始信號
- 設備地址(1 0 1 0 A2 A1 A0 1),因為讀取所以最後的R/W會是1。
- ACK
- 只要有ACK就持續讀取資料,當要停止時則由MCU發送一個NACK
- 結束信號