Заголовочный файл или библиотека для тестирования i2c FRAM?
Я нашел заголовочный файл для тестирования i2c eeprom 24LC256, но использовал его для протестируйте мой eeprom CAT24C32. Тестовый скетч работает нормально. Я изменил строку BLOCKSIZE 8, потому что мой eeprom имеет только 32-байтовую страницу для записи.
У меня также есть FRAM MB85RC256V. Могу ли я использовать тот же заголовок для проверки FRAM. Я видел, что команда записи байта такая же, как eeprom, но запись страницы имеет другую сторону буфера, там написано, что она имеет 32 КБ. Могу ли я его использовать?
Если я ошибся, помогите мне. Большое спасибо!
Здесь .h
#ifndef EEPROM_ROUTINES
#define EEPROM_ROUTINES
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
#define BLOCKSIZE 8
#define I2CADDR 0x57
#define BLOCKSIZE_READ 30
template <class T>
uint16_t writeObjectSimple(uint8_t i2cAddr, uint16_t addr, const T& value){
const uint8_t* p = (const uint8_t*)(const void*)&value;
uint16_t i;
for (i = 0; i < sizeof(value); i++){
Wire.beginTransmission(i2cAddr);
Wire.write((uint16_t)(addr >> 8)); // старший бит
Wire.write((uint16_t)(addr & 0xFF));// LSB
Wire.write(*p++);
Wire.endTransmission();
addr++;
delay(5); //максимальное время записи в 24LC256
}
return i;
}
template <class T>
uint16_t readObjectSimple(uint8_t i2cAddr, uint16_t addr, T& value){
uint8_t* p = (uint8_t*)(void*)&value;
uint8_t objSize = sizeof(value);
uint16_t i;
for (i = 0; i < objSize; i++){
Wire.beginTransmission (i2cAddr);
Wire.write((uint16_t)(addr >> 8)); // старший бит
Wire.write((uint16_t)(addr & 0xFF));// LSB
Wire.endTransmission();
Wire.requestFrom(i2cAddr, (uint8_t)1);
if(Wire.available()){
*p++ = Wire.read();
}
addr++;
}
return i;
}
template <class T>
uint16_t writeObject(uint16_t addr, const T& value){
const uint8_t* p = (const uint8_t*)(const void*)&value;
Wire.beginTransmission(I2CADDR);
Wire.write((uint16_t)(addr >> 8)); // старший бит
Wire.write((uint16_t)(addr & 0xFF)); // младший бит
// в цикле: подсчитывает байты, которые мы можем отправить до
//наш блок заполняется
//но инициализируем его числом байт до
//следующий 16-байтовый выровненный адрес
uint8_t blockBytes = (addr/BLOCKSIZE + 1)*BLOCKSIZE - addr;
uint16_t i;
for (i = 0; i < sizeof(value); i++){
if (blockBytes == 0){
//блок заполнен;
Wire.endTransmission(); //отправляем буфер
delay(5);
// перезапустить новый блок
addr = (addr/BLOCKSIZE + 1)*BLOCKSIZE;
blockBytes = BLOCKSIZE;
Wire.beginTransmission(I2CADDR);
Wire.write((uint16_t)(addr >> 8)); // старший бит
Wire.write((uint16_t)(addr & 0xFF));// LSB
}
Wire.write(*p++); // отправляем байт данных
blockBytes--; //уменьшаем размер блока
}
Wire.endTransmission();
delay(5); //требуемая задержка записи 5 мс
return i;
}
template <class T>
uint16_t readObject(uint16_t addr, T& value){
uint8_t* p = (uint8_t*)(void*)&value;
Wire.beginTransmission(I2CADDR);
Wire.write((uint16_t)(addr >> 8)); // старший бит
Wire.write((uint16_t)(addr & 0xFF)); // младший бит
Wire.endTransmission();
// подсчитывает байты, которые мы можем прочитать до того, как буфер будет исчерпан
uint8_t blockBytes = 0;
uint16_t objSize = sizeof(value);
uint16_t i;
for (i = 0; i < objSize; i++){
if (blockBytes==0){
//нам нужен новый блок
blockBytes = BLOCKSIZE_READ;
if (objSize < blockBytes) blockBytes = objSize;
// получаем новый блок
Wire.requestFrom((uint8_t)I2CADDR, blockBytes);
}
if(Wire.available()){
//читаем байт из буфера
*p++ = Wire.read();
blockBytes--;
}
}
return i;
}
#endif
Вот скетч для проверки eeprom
#include <Wire.h>
#include "eeprom_routines.h" //определения функций:
//записатьОбъект, прочитатьОбъект,
//writeObjectSimple, readObjectSimple
#define BLOCK_OPERATIONS 0
#if BLOCK_OPERATIONS>0
#define __WRITE__(ad, obj) writeObject(ad,(obj))
#define __READ__(ad, obj) readObject(ad,(obj))
#else
#define __WRITE__(ad, obj) writeObjectSimple(0x57,ad,(obj))
#define __READ__(ad, obj) readObjectSimple(0x57,ad,(obj))
#endif
#define MEM_ADDR_MULTI 3458
// Это структура, которую мы пишем и читаем из EEPROM
class MyData{
long result;
public:
float f1;
float f2;
double f3;
int i1;
long i2;
long i3;
bool negative;
long getResult(){
return result;
}
long calcResult(){
//выполняет расчет со своими данными
//и сохраняет результат в приватную переменную
long i = (i2+i3)/i1;
double f = f3/(f1+f2);
result = f/i;
//округлять
result += result>0 ? 0.5 : -0.5;
if (negative) result=-result;
return result;
}
MyData() : result(0){ }
};
void setup(){
Serial.begin(9600);
Wire.begin();
MyData data[5];
//данные[0] - результат должен быть 20
data[0].i1 = 10;
data[0].i2 = 150000;
data[0].i3 = 350000;
data[0].f1 = 0.5;
data[0].f2 = 2.5;
data[0].f3 = 3.0E+6;
data[0].negative = false;
//данные[1] - результат должен быть -40
data[1].i1 = data[0].i1;
data[1].i2 = data[0].i2;
data[1].i3 = data[0].i3;
data[1].f1 = data[0].f1;
data[1].f2 = data[0].f2;
data[1].f3 = 2*data[0].f3;
data[1].negative = true;
//данные[2] - результат должен быть 80
data[2].i1 = data[0].i1;
data[2].i2 = data[0].i2;
data[2].i3 = data[0].i3;
data[2].f1 = data[0].f1;
data[2].f2 = data[0].f2;
data[2].f3 = 4*data[0].f3;
data[2].negative = false;
//данные[3] - результат должен быть -20
data[3].i1 = data[0].i1;
data[3].i2 = -data[0].i2;
data[3].i3 = -data[0].i3;
data[3].f1 = data[0].f1;
data[3].f2 = data[0].f2;
data[3].f3 = data[0].f3;
data[3].negative = false;
//данные[4] - результат должен быть -2
data[4].i1 = data[0].i1;
data[4].i2 = -data[0].i2;
data[4].i3 = -data[0].i3;
data[4].f1 = data[0].f1*10;
data[4].f2 = data[0].f2*10;
data[4].f3 = -data[0].f3;
data[4].negative = true;
Serial.println ("Data before writing to eeprom");
for (int i=0; i<5; i++){
data[i].calcResult();
Serial.print("data-"); Serial.print(i);
Serial.print(": result = ");
Serial.println(data[i].getResult());
}
Serial.print("Size of each object: ");
Serial.println(sizeof(MyData)) ;
Serial.println ("Writing data to eeprom");
int memaddr = MEM_ADDR_MULTI;
long t0 = millis();
for (int i=0; i<5; i++){
memaddr += __WRITE__(memaddr, data[i]);
}
long t1 = millis();
Serial.print ("...writing finished. Elapsed time: ");
Serial.println(t1-t0);
delay(1000);
Serial.println ("Reading data from eeprom");
MyData read[5];
t0 = millis();
memaddr = MEM_ADDR_MULTI;
for (int i=0; i<5; i++){
memaddr += __READ__(memaddr, read[i]);
}
t1 = millis();
Serial.print ("Time to read: "); Serial.println(t1-t0);
for (int i=0; i<5; i++){
Serial.print ("Read object: #");
Serial.println(i);
long storedResult = read[i].getResult();
Serial.print (" >stored result = ");
Serial.println(storedResult);
long newResult = read[i].calcResult();
Serial.print (" >recalculated result = ");
Serial.println(newResult);
if (storedResult== newResult &&
storedResult==data[i].getResult() )
Serial.println ("SUCCESS");
else Serial.println ("FAIL");
}
}
void loop() {
}
Здесь серийный вывод теста eeprom CAT24C32
Data before writing to eeprom
data-0: result = 20
data-1: result = -40
data-2: result = 80
data-3: result = -20
data-4: result = -2
Size of each object: 27
Writing data to eeprom
...writing finished. Elapsed time: 126
Reading data from eeprom
Time to read: 15
Read object: #0
>stored result = 20
>recalculated result = 20
SUCCESS
Read object: #1
>stored result = -40
>recalculated result = -40
SUCCESS
Read object: #2
>stored result = 80
>recalculated result = 80
SUCCESS
Read object: #3
>stored result = -20
>recalculated result = -20
SUCCESS
Read object: #4
>stored result = -2
>recalculated result = -2
SUCCESS
@asterix, 👍0
1 ответ
На сайте Fujitsu сказано
Кроме того, приложения, которые использовали другие продукты с интерфейсами I2C, такие как EEPROM и микроконтроллеры, теперь могут заменить EEPROM новыми продуктами FRAM
Поэтому вы можете использовать его без каких-либо изменений в коде.
- Как управлять длиной чтения переменных I2C, требующей увеличения адреса (эмуляция IC Wire/I2C/EEPROM)
- о том, как записать данные во весь EEprom?
- Неустойчивое поведение при использовании DUE с чипом Microchip 24FC64 EEPROM?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Как читать и записывать EEPROM в ESP8266
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?