求教Arduino外置EEPROM的代码
手上有一块UNO,记录编码器数据和运行时间,UNO内部EEPROM有点小,想拓展至外部EEPROM,用<EEPROM.h>库是不是只能写在UNO内部?怎样才能写到外部EEPROM中?本帖最后由 Youyou 于 2014-8-28 13:28 编辑
你好,你是打算外扩什么样的芯片呢?如果是AT24CXX系列,比如AT24C32,操作挺简单的,直接用I2C的库进行操作就好了。具体的代码,可以自己看下收据手册来写,或者在github上找相关的代码。
这段关于I2C的EEPROM代码你可以参考下:https://github.com/Soshimo/I2C-Serial-EEPROM-Arduino-Library
Youyou 发表于 2014-8-28 13:19
你好,你是打算外扩什么样的芯片呢?如果是AT24CXX系列,比如AT24C32,操作挺简单的,直接用I2C的 ...
感谢大神的提点,现在遇到一个问题(我用的是AT24C#include <Wire.h>
#include <i2cEEPROM.h>
i2cEEPROMClass(rom);
void setup()
{
Serial.begin(9600);
rom.begin(0);
rom.writeByte(0,0xaa); delay(10);
}
void loop()
{
byte a = rom.readByte(0); delay(10);
Serial.println(a); delay(10);
delay(1000);
}
02N),根据你提供的库写代码,却无法将数据写入EEPROM中,每次读取都为255,求指点 加饭 发表于 2014-8-28 17:31
感谢大神的提点,现在遇到一个问题(我用的是AT24C
02N),根据你提供的库写代码,却无法将数据写入EEPRO ...
你的器件地址设置错误,你对照下数据手册和自己的接线方法,把AT24C02的地址确定下来,这个地址在I2C通讯中用来寻址。
void begin(int deviceId);这条函数就是用来设置地址的,但你却填了0,从机的地址错了,那肯定读和写都是错误的。 Youyou 发表于 2014-8-28 18:08
你的器件地址设置错误,你对照下数据手册和自己的接线方法,把AT24C02的地址确定下来,这个地址在I2C通讯 ...
我将AT24C02的A0~A2都接地,那int deviceId = 0 ? Youyou 发表于 2014-8-28 18:08
你的器件地址设置错误,你对照下数据手册和自己的接线方法,把AT24C02的地址确定下来,这个地址在I2C通讯 ...
经过查证,地址修改为0x50,但读取数据后,Wire.endTransmission()为0,数据依旧是0xFF,错在哪里? 加饭 发表于 2014-8-29 10:32
经过查证,地址修改为0x50,但读取数据后,Wire.endTransmission()为0,数据依旧是0xFF,错在哪里? ...
把你的完整代码还有完整的连线图发上来看看,不然很难知道哪个细节出了问题。 Youyou 发表于 2014-8-29 11:17
把你的完整代码还有完整的连线图发上来看看,不然很难知道哪个细节出了问题。 ...
经过部分修改,能写入24C02中,但读取出问题——不管读取#include <Wire.h>
#include <i2cEEPROM.h>
i2cEEPROMClass(rom);
int R_W=2; // LOW is write data ; HIGH is read data
void setup()
{
Serial.begin(9600);
pinMode(R_W,OUTPUT);
rom.begin(0x57);
digitalWrite(R_W,LOW);
rom.writeByte(1,0xaa); delay(10);
rom.writeByte(10,0xbb); delay(10);
rom.writeByte(2,0xcc); delay(10);
/* writeString(2,"star");
delay(10);
writeString(3,"end");
delay(10);*/
}
void loop()
{
rom.begin(0x57);
digitalWrite(R_W,HIGH);
byte a = rom.readByte(10); delay(10);
Serial.println(Wire.endTransmission());delay(10);
Serial.println(a,HEX); delay(10);
delay(1000);
}
地址为多少,读取结果为最后一个写入结果,代码及电路图如下,求赐教 本帖最后由 Youyou 于 2014-8-29 22:52 编辑
你的连线图没有问题,按照此图,你的地址0X57也是对的。你参考下我的代码试试看,我经过测试,成功写入并读取的。
我的连线是:A0到A2全部接地,WP管脚也接地。串口看读取的值,每一次按下复位键,打印的值就会增长一次。
#include "Wire.h"
#include "i2cEEPROM.h"
void setup()
{
i2cEEPROM.begin(0x50);
byte num = i2cEEPROM.readByte(0)+1;
i2cEEPROM.writeByte(0,num);
Serial.begin(9600);
}
void loop()
{
Serial.println(i2cEEPROM.readByte(0));
delay(1000);
}
注:该连线图只适用于Arduino UNO!
顺便说一下,我发现如果先初始化串口再初始化I2C,在这中间需要加入一些延时,否则读出的数据也不对,一直是255。
也就是说,需要改成这样:
void setup()
{
Serial.begin(9600);
delay(10);
i2cEEPROM.begin(0x50);
byte num = i2cEEPROM.readByte(0)+1;
i2cEEPROM.writeByte(0,num);
}
Youyou 发表于 2014-8-29 16:39
你的连线图没有问题,按照此图,你的地址0X57也是对的。你参考下我的代码试试看,我经过测试,成功写入并读 ...
这次串口读取的数据一直都是255...更换两颗能正常使用的AT24C02,结果都一样~:dizzy: :'(请问你用的是什么板子?我用的是某宝山寨的MEGA2560~ 加饭 发表于 2014-8-29 19:53
这次串口读取的数据一直都是255...更换两颗能正常使用的AT24C02,结果都一样~ 请问你用的是什 ...
我用的是Arduino UNO,所以,SDA和SCL就是A4和A5。
你用的是mega2560,那么SDA和SCL就是D20和D21,注意板子的区别。你修改下连线。
还有,根据你的连线图,AT24C02的地址设置管脚(A0A1A2)都接成了高电平,那么器件地址就是0x57。我的连线方式是将他们全部置为低电平,所以器件地址为0x50。你修改下代码就可以用了。 本帖最后由 加饭 于 2014-9-1 11:15 编辑
Youyou 发表于 2014-8-29 22:50
我用的是Arduino UNO,所以,SDA和SCL就是A4和A5。
你用的是mega2560,那么SDA和SCL就是D20和D21,注意板 ...
我不用那个库文件,改用共用体,但出了个奇怪的问题——我AT24C02明明全接低电平(代码中硬件地址应该0x50),但经过write_data(0x57 ,0x00 ,0x11);这一句后,读取的内容变成0x11,怎么会这样呢?而且,只要软件中编写硬件地址在0x50~0x57之间,都能写入EEPROM中,已经确定SDA和SCL的引脚没有接错,求大神指点</blockquote></div><div class="blockcode"><blockquote>#include <Wire.h>
// 从指定位置写一个数据
void setup()
{
Serial.begin(9600);
delay(10);
Wire.begin();
}
byte val = 0;
int index = 0;
void loop()
{
byte a0 = 0x00;
byte b0 = 0x00;
write_data(0x50 ,0x00 ,0xbb);
write_data(0x57 ,0x00 ,0x11);
a0 = read_data(0x50 ,0x00);
b0 = read_data(0x57 ,0x00);
Serial.print("a=");delay(10);
Serial.println(a0,HEX);delay(1000);
Serial.print("b=");delay(10);
Serial.println(b0,HEX);delay(1000);
}
void write_data(byte num ,byte add ,byte data)
{
// write
Wire.beginTransmission(int(num));
Wire.write(add);delay(10); // sendaddress ww
Wire.write(data);delay(10); // senddata ww
Wire.endTransmission(); //
delay(10);//very import ww
}
byte read_data(byte num ,byte add)
{
// read
Wire.beginTransmission(int(num));
Wire.write(add); // sendaddress
Wire.endTransmission(); //
Wire.requestFrom(int(num), 1); // request 2 bytes from slave device #112
if(Wire.available())
{
val = Wire.read();// receive high byte (overwrites previous reading)
}
delay(10);
return val;
}
加饭 发表于 2014-9-1 11:08
我不用那个库文件,改用共用体,但出了个奇怪的问题——我AT24C02明明全接低电平(代码中硬件地址应该0x50 ...
这个是你写程序实现的功能,write_data(0x57 ,0x00 ,0x11)这条函数,其中0x57表示器件地址,0x00表示数据写入的地方,0x11是写入的数据,因此经过这个操作后,0x11已经吸入了,那么你再读取,读到的值就是0x11了。 Youyou 发表于 2014-9-4 13:25
这个是你写程序实现的功能,write_data(0x57 ,0x00 ,0x11)这条函数,其中0x57表示器件地址,0x00 ...
我只有一块AT24C02,而且器件地址是0x50,那么地址为0x57的数据怎么会写入到地址为0x50的芯片中? 加饭 发表于 2014-9-5 09:27
我只有一块AT24C02,而且器件地址是0x50,那么地址为0x57的数据怎么会写入到地址为0x50的芯片中? ...
我用你的代码实验了下,应该是有问题的,读出来就是FF,不管是a还是b。 本帖最后由 Youyou 于 2014-9-5 12:25 编辑
加饭 发表于 2014-9-5 09:27
我只有一块AT24C02,而且器件地址是0x50,那么地址为0x57的数据怎么会写入到地址为0x50的芯片中? ...下面这段代码按照你的风格来写的,测试通过,你可以试下。
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
}
void loop()
{
byte a0,b0;
writeData(0x50,0x00,0xbb);
writeData(0x57,0x00,0x11);
a0 = readData(0x50,0x00);
b0 = readData(0x57,0x00);
Serial.println(a0);
Serial.println(b0);
delay(3000);
}
void writeData(int m_deviceid,int add,byte data)
{
Wire.beginTransmission(m_deviceid);
Wire.write(add>>8);
Wire.write(add & 0xFF);
Wire.write(data);
Wire.endTransmission();
delay(10);
}
byte readData(int m_deviceid,int add)
{
byte result;
Wire.beginTransmission(m_deviceid);
Wire.write(add>>8);
Wire.write(add & 0xFF);
Wire.endTransmission();
Wire.requestFrom(m_deviceid, 1);
result = Wire.read();
return result;
} 这个问题解决了吗? 我也出现了这种情况,从0x50 到0x57都能读到数据255 但是我接线是按照0x50接的 本帖最后由 Abelwong 于 2019-4-24 01:59 编辑
目前手中僅有24LC02,實測24C02改善讀取一直都是0xFF的方式是必須修改read的地址設定方式才能正常讀取,讀取部分如下:
byte readData(unsigned int address) {
byte result;
Wire.beginTransmission(0x50);
Wire.write(address);
Wire.endTransmission();//此行務必要在Wire.write(address)之後
Wire.requestFrom(0x50, 1);
result = Wire.read();
return result;
}
页:
[1]