1. 程式人生 > 實用技巧 >【雕爺學程式設計】Arduino動手做(68)---AT24C256儲存模組

【雕爺學程式設計】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();

}