今天來實驗下IIC 讀寫外部EEPROM,這邊可能有部分讀者會覺得奇怪,阿arduino 本身不是就有了嗎?這句話是沒錯拉,但是畢竟是在MCU內部的,所以內部的EEPROM 也會有大小上的限制,先來看一下資料手冊,由於我是使用arduino NANO,我查NANO 上面的atmel MCU EEPROM的大小
這邊我們可以看到內建只有1kbytes,其實也不小了拉,但是總是有其他時候會需要,那我們先了解起來,萬一哪天需要紀錄一堆變數資料且,需要斷電再開啟時不被清除,就很需要了
開發環境
Arduino IDE 1.8.2
材料
1.
at24c256 模組
2.
Arduino Nano + Nano擴展板
3.
杜邦線 n 條
4.
邏輯分析儀 一台
接線說明
NANO |
At24C256 |
Vcc |
Vcc |
A5 |
SCL |
A4 |
SDA |
Gns |
Gnd |
這邊說一下,再使用arduino IIC library 時,有些時候我們不知道是否是真的有把資料寫進去,所以需要使用邏輯分析儀(下次有空來寫一下使用教學),確認寫入讀取行為是符合時序。
Step1 模組認識
在使用模組前,一定要先大致上看一下資料手冊喔
使用電壓為DC 5V
設定晶片的位址是透過設定A1 A0 腳位
對應到模組上面腳位
模組腳位 |
功能 |
Vcc |
電源 |
SCL |
通訊用 |
SDA |
通訊用 |
GND |
電源 |
A0 |
設定位址 |
A1 |
設定位址 |
A2 |
沒功能 |
WP |
寫入保護 |
大略看完資料手冊後,會發現A2呢?A2要做甚麼?其實A2沒功能啦
模組上面的接腳,可以透過使用短路帽來決定設備位址
接下來如果At24C256 模組與NANO 接好後如下
Step2 寫程式-寫入資料
要怎麼寫入AT24C256,要看一下資料手冊的協定,如下圖
紅色的地方是晶片的位置,藍色的地方是晶片內部欲存放資料的位址,Data就是要存入的資料
如果模組上面的短路帽有照我的方式接的話,Device Address 為 0x50 ,接下來我們嘗試在晶片的
0x00位址寫入一個字元’H’
#include <Wire.h>
#define DeviceAddress 0x50
void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
I2C_write('H');
}
void I2C_write(unsigned char
data)
{
Wire.beginTransmission(0x50); // transmit to device
Wire.write(0x00); //
sends one byte
Wire.write(0x00); //
sends one byte
Wire.write(data); //
sends one byte
Wire.endTransmission(); // stop
transmitting
}
燒錄進去後,我們用邏輯分析儀看是不是真的有arduino Nano是否有送出命令,寫入資料到
位址0x00 0x00的地方。
(hex 與 ASCII顯示)
這邊我們可以看到已經將命令及資料設定出去了,且資料的通訊格式與資料手冊一樣,接下來開始寫讀回資料的功能。
Step3 寫程式-讀回資料
要從AT24C256讀取資料時的通訊方式,其實有兩種方式,但我是使用下圖的方式,先告訴AT24C256我要讀取的資料位址,再進行讀取該位址的資料。
根據上面Step2的程式碼,替換成下面
#include <Wire.h>
#define DeviceAddress 0x50
void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
Serial.println((char)I2C_read());//將讀回來的資料轉成char 型態,並從序列埠印出
delay(1000);
}
unsigned char I2C_read()
{
unsigned char re_char;
Wire.beginTransmission(0x50); // transmit to device #8
Wire.write(0x00); // sends one byte
Wire.write(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
Wire.requestFrom(0x50,1); //Send Read requestFrom
if (Wire.available())re_char
= Wire.read();
return re_char;
}
void I2C_write(unsigned char data)
{
Wire.beginTransmission(0x50); // transmit to device
Wire.write(0x00); // sends one byte
Wire.write(0x00); // sends one byte
Wire.write(data); // sends one byte
Wire.endTransmission(); // stop transmitting
}
從邏輯分析儀讀到的資料
(二進制)
(hex + ASCII)
你可以在圖片中發現,讀取時控制讀寫的位元變成1,紅線處
參考資料
使用到的函式說明
WireBeginTransmission
https://www.arduino.cc/en/Reference/WireBeginTransmission
WireEndTransmission
https://www.arduino.cc/en/Reference/WireEndTransmission
WireRequestFrom
https://www.arduino.cc/en/Reference/WireRequestFrom
參考資料
Atmel 328P AU
At24c256
https://ww1.microchip.com/downloads/en/DeviceDoc/doc0670.pdf
Arduino 資料
https://playground.arduino.cc/Code/I2CEEPROM/
https://www.arduino.cc/en/Tutorial/LibraryExamples/MasterWriter
https://www.hobbytronics.co.uk/arduino-external-eeprom
沒有留言:
發佈留言