2009年12月20日 星期日

Microchip 25LC160 EEPROM 16K SPI Bus Serial EEPROM

Microchip 25AA160/25LC160/25C160 EEPROM提供以SPI Slave方式供SPI Master裝置進行存取EEPROM
一般來說透過SPI介面上至少會提供:
1. CS (Chip Select)
2. SO (Data Output) --> 連接到MCU端的SPI 介面上的SI(資料輸入腳)
3. SI (Data Output) --> 連接到MCU端的SPI 介面上的SO(資料輸出腳)
4. SCK (Clock)


在Datasheet上一般都會提供一些用於讀寫的指令:
a. WRSR 0000 0001 (0x01)
b. WRITE 0000 0010 (0x02)
c. READ 0000 0011 (0x03)
d. WRDI 0000 0100 (0x04)
e. RDSR 0000 0101 (0x05)
f. WREN 0000 0110 (0x06)

讀取EEPROM裡頭的資料
1. CS 設於LOW狀態
2. 傳送8 bit的 READ 0000 0011 (0x03)指令
3. 傳送16 bit的EEPROM記憶區位址. 先送第 15 ~8 bits 再送 7~0bit.
4. 完成後再任意寫一個值到SSPBUF 中將資料強迫推出
5. 完成讀取後要再將CS設定於HIGH狀態

寫入資料到EEPROM中
1. CS 設於LOW狀態
2. 傳送8 bit的 WREN 0000 0110 (0x06))指令 //Write Enable命令要先傳送
3. CS設定於HIGH狀態
4. CS 設於LOW狀態
5. 傳送8 bit的 WRITE 0000 0010 (0x02)指令 //Write命令要先傳送
6. 傳送16 bit的EEPROM記憶區位址. 先送第 15 ~8 bits 再送 7~0bit.
7. 傳送所要寫的資料(一次只能寫一個 byte)
8. 寫完後要再 CS設定於HIGH狀態
範例如下:

CS = 0;
WriteSPI ( WREN ); //這裡是寫入 Write Enable命令
CS = 1;

CS = 0;
WriteSPI ( WRITE );
WriteSPI ( 0x00 ); //這裡是要寫在EEPROM上的位址 High
WriteSPI ( 0x01 ); //這裡是要寫在EEPROM上的位址 Low
WriteSPI ( 0x78 ); //這裡是資料
CS = 1;


檢查讀取暫存器狀態(Read Status Register RDSR)
1. CS 設於LOW狀態
2. 傳送8 bit的 RDSR 0000 0101 (0x05) //Read Status Register命令要先傳送
3. 檢查所讀回的資料中的第0個bit (WIP)是否還在寫入狀態. 0表示正在寫入 1.表示己經寫好
範例如下:
do{
CS = 0;
WriteSPI ( RDSR ); //Select Device
dummy=ReadSPI();
CS = 1;
}while(dummy&0x01);

經過上述的操作就可以達到對EEPROM以標準SPI Interface進行操作.

[註]感謝友人Resen Huang (首席) 的詳細解說.

MSB 與 LSB 的資料排列方式

假設資料結構子如下:
struct myData
{
unsigned addr_hi:2 // 佔 2 bits
unsigned instr :6 // 佔 6 bits
unsigned char instr_low // 佔 8 bits
}

資料內容為:
myData = 0x5A5B; // 0b0101101001011011

MSB表示方式
+-----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|value| 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
+-----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|--------> 1 byte <--------- |--------> 1 byte <--------- |






LSB表示方式(定義struct的順序要調整過)
struct myData
{
unsigned char instr_low // 佔 8 bits
unsigned instr :6 // 佔 6 bits
unsigned addr_hi:2 // 佔 2 bits
}

+-----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|value| 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
+-----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+-----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|--------> 1 byte <--------- |--------> 1 byte <--------- |


小結:
MSB的機器在訂struct時要從bit 7 ~ bit 0
LSB的機器在訂struct時要從bit 0 ~ bit 7