【雕爺學程式設計】Arduino動手做(68)---AT24C256儲存模組
37款感測器與執行器的提法,在網路上廣泛流傳,其實Arduino能夠相容的感測器模組肯定是不止這37種的。鑑於本人手頭積累了一些感測器和執行器模組,依照實踐出真知(一定要動手做)的理念,以學習和交流為目的,這裡準備逐一動手嘗試系列實驗,不管成功(程式走通)與否,都會記錄下來---小小的進步或是搞不掂的問題,希望能夠拋磚引玉。
【Arduino】168種感測器模組系列實驗(資料+程式碼+圖形+模擬)
實驗六十八:AT24C256 I2C介面 EEPROM 儲存模組 IIC
AT24C256
是ATMEL公司256kbit序列電可擦的可程式設計只讀儲存器,8引腳雙排直插式封裝,具有結構緊湊、儲存容量大等特點,可以在2線總線上並接4片該IC,特別適用於具有高容量資料儲存要求的資料採集系統。AT24C256採用SOP-8封裝。
晶片引數
晶片有3種工作電壓;
5.0V(VCC=4.5V~5.5V)
2.7V(VCC=2.7V~5.5V)
1.8V(VCC=1.8V~3.6V)
特性:
內部可以組成32k×8儲存單元
2線序列介面
斯密特觸發,濾波輸入抑制噪聲
雙向資料傳送協議
硬體防寫引腳和軟體資料保護功能
具有64位元組頁寫模式
A0、A1:地址選擇輸入端。在序列匯流排結構中,可以連線4個AT24C256IC。用A0、A1來區分各IC。A0、A1懸空時為0。
SCL:序列時鐘輸入。上升沿將SDA上的資料寫入儲存器,下降沿從儲存器讀出資料送SDA上。
SDA:雙向序列資料輸入輸出口。用於儲存器與微控制器之間的資料交換。
WP:防寫輸入。此引腳與地相連時,允許寫操作;與VCC相連時,所有的寫儲存器操作被禁止。如果不連,晶片內部下拉到地。
VCC:電源。
GND:地。
NC:空。
AT24C256的工作原理
AT24C256內部有512頁,每一頁為64位元組,任一單元的地址為15位。地址範圍0000H~7FFFH。
晶片工作狀態
1)時鐘和資料傳送
一般情況下,SDA被外部的裝置拉到高,只有當SCL為低電平時,SDA上的資料變化,表示要傳送資料。SCL為高時SDA變化表示狀態變化。
2)開始狀態(START)
當SCL為高時,SDA由高到低表示資料傳送開始,這一狀態必須在所有命令之前。
3)結束狀態(STOP)
當SCL為高時,SDA由低到高表示資料傳送結束狀態。
4)應答狀態(ACK)
所有的地址和資料都是以8位的形式序列傳送給儲存器或從儲存器讀出的。儲存器在第9個時鐘週期SDA發零訊號表示已經收到8位資料。見圖匯流排協議圖。
AT24C256 I2C介面 EEPROM 儲存模組
1.板載晶片AT24C256進口晶片;
2.板載I2C通訊所需的上拉電阻;
3.所有管腳均引出並標註;
4.PCB板子尺寸:1.9(CM)x1.1(CM)
模組電原理圖
/* 【Arduino】168種感測器模組系列實驗(資料+程式碼+圖形+模擬) 實驗六十八:AT24C256 I2C介面 EEPROM 儲存模組 IIC */ #include <Wire.h> #define ADDRESS_AT24C256 0x50 word wordAddress = 0x0F00; char str[] = "This is ZLBG."; byte buffer[30]; int i; void setup() { Wire.begin(); Serial.begin(9600); //write Wire.beginTransmission(ADDRESS_AT24C256); Wire.write(highByte(wordAddress)); Wire.write(lowByte(wordAddress)); for (i = 0; i < sizeof(str); i++) { Wire.write(byte(str)); } Wire.endTransmission(); delay(10); } void loop() { Wire.beginTransmission(ADDRESS_AT24C256); Wire.write(highByte(wordAddress)); Wire.write(lowByte(wordAddress)); Wire.endTransmission(); Wire.requestFrom(ADDRESS_AT24C256, sizeof(str)); if(Wire.available() >= sizeof(str)) { for (i = 0; i < sizeof(str); i++) { buffer = Wire.read(); } } for(i = 0; i < sizeof(str); i++) { Serial.print(char(buffer)); } Serial.println(); delay(2000); }
/* 【Arduino】168種感測器模組系列實驗(資料+程式碼+圖形+模擬) 實驗六十八:AT24C256 I2C介面 EEPROM 儲存模組 IIC 程式之二 */ #include <Wire.h> #define EEPROM_ADDR 0x50 void setup() { Wire.begin(); Serial.begin(9600); // TESTS FOR EACH FUNCTION BEGIN HERE Serial.println("Writing Test:"); for (int i=0; i<20; i++){ i2c_eeprom_write_byte(EEPROM_ADDR,i,i+65); Serial.print(". "); delay(10); } Serial.println(""); delay(500); Serial.println("Reading Test:"); for (int i=0; i<20; i++){ Serial.write(i2c_eeprom_read_byte(EEPROM_ADDR, i)); Serial.print(" "); } byte PageData[30]; byte PageRead[30]; for (int i=0; i<30; i++){ PageData = 0; PageRead = 0; } Serial.println(""); for (int i=0; i<30; i++) PageData = i+33; Serial.println("Writing Page Test:"); i2c_eeprom_write_page(EEPROM_ADDR, 100, PageData, 28 ); Serial.println("Reading Page Test:"); i2c_eeprom_read_buffer( EEPROM_ADDR, 100, PageRead, 28); for (int i=0; i<28; i++){ Serial.write(PageRead); Serial.print(" "); } } void loop() { } void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) { int rdata = data; Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); Wire.write((int)(eeaddress & 0xFF)); Wire.write(rdata); Wire.endTransmission(); } void i2c_eeprom_write_page ( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) { Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddresspage >> 8)); Wire.write((int)(eeaddresspage & 0xFF)); byte c; for ( c = 0; c < length; c++) Wire.write(data[c]); Wire.endTransmission(); delay(10); } byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) { byte rdata = 0xFF; Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); Wire.write((int)(eeaddress & 0xFF)); Wire.endTransmission(); Wire.requestFrom(deviceaddress,1); if (Wire.available()) rdata = Wire.read(); return rdata; } void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) { Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); Wire.write((int)(eeaddress & 0xFF)); Wire.endTransmission(); Wire.requestFrom(deviceaddress,length); for ( int c = 0; c < length; c++ ) if (Wire.available()) buffer[c] = Wire.read(); }