Запись и чтение at24c32
- Войдите на сайт для отправки комментариев
Добрый день. Arduino только начинаю осваивать. Помогите разобраться. Без проблем пишу и читаю по 1 байту.
Функция для записи:
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}
Функция для чтения:
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}
Пример:
//записываю единицу по адресу 4000
i2c_eeprom_write_byte( 0x50, 4000, 1 );
delay(10);
//считываю данные по адресу 4000
byte b = i2c_eeprom_read_byte(0x50, 4000);
Вопрос: как записать 2х байтовое число по адресу 4000? Я понимаю, что в 1 ячейку не поместится, тоесть нужно записывать по адресу 4000 и 4001. Как реализовать такую запись и чтение. Например, я хочу записать в по адресу 4000 значение 3000, а затем считать это значение 3000.
Видел функцию, которая возможно и может так делать, но не могу разобраться...
//пишет
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddresspage >> 8)); // MSB
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.write(data[c]);
Wire.endTransmission();
}
//читает
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.read();
}
http://arduino.ru/forum/programmirovanie/zapis-v-eeprom
http://arduino.ru/forum/programmirovanie/preobrazovanie-unsigned-long-byte-4-shtuki-i-obratno
http://arduino.ru/forum/programmirovanie/pomogite-pozhaluista-s-preobraz...
Спасибо!
Возник вопрос:
все ли ячейки памяти 24С32, установленную на часах модуле часов 3231, можно использовать для своих нужд, или что-то используют часы?
почитайте, пожалуйста, с адреса 0 до 25. какие значения там? 65-90?
пытался писать с 0-го адреса. значеня по адресам 1 и 2 сбиваются, на 66 и 67.
видимо 3231 туда пишет.
Для начала в реализации zs-042 имеет на борту АТ24С32 начальный адрес которой 0x68. И действительно первые 16 байт заняты под часы. Таким образом доступная рамять начинается с 0x78
Для начала в реализации zs-042 имеет на борту АТ24С32 начальный адрес которой 0x68. И действительно первые 16 байт заняты под часы. Таким образом доступная рамять начинается с 0x78
В моем случае не было задержки после записи байта. писался мусор. добавил, все ок, работает как часы, китайские :-)
откуда такая информация?
0х68 начальный адрес? то есть перемычками я меняю начальный адрес? есть сомнения. 68-адрес устройства на шине, а не памяти
Разрешите побыть КО (капитаном).
Вот два модуля RTC 3231 с Ali, оба "сверху" и потом "снизу". На одном напаяна память 24С32 (4 кБ) и он справа, на другом такой памяти нет.
Разумеется, оба модуля работают как RTC часы DS3231 без вопросов (левый не имеет встроенной подтяжки I2C шины, правый имеет 4.7 кОм подтягивающие резисторы). Разумеется, "часы" писать сами по себе куда-либо вовне (например, в EEPROM на той же плате модуля) не могут и не умеют.
Разумеется на фото справа перемычки (A0, A1 и A2) относятся к EEPROM памяти, позволяют изменять ее адрес, в то время как I2C адрес DS3231 ("часы") остается 0x68. Если что, то I2C адрес напаяной 24С32 EEPROM (на фото справа) по умолчанию 0x57 (перемычки не запаяны).
Как представляется разумным, добавление EEPROM к RTC есть калька с удачного проекта, когда к работе RTC добавляют _расписание_, по аналогии с расписанием школьных звонков по дням недели и, может быть, по классам (учащихся). "Регулярную" задачу для часов придумать несложно.
Ну и, разумеется, никакой мистики во всем этом не имеется. Просто часы, просто бесплатно еще и 4 кБ (I2C eeprom) памяти.
вот и я о том-же. а память использовал как раз для будильников.
Посчитал нужным дополнить пост "от имени КО" тем, что от MacSim (дата регистрации на форуме 28/11/2012) многому (ну или кое-чему, что тоже значительно) научился "в процессе". Спасибо.
При работе с памятью 24C32 (i2c 0x57) в модуле DS3231
Пример ... была ошибка, Arduino: 1.6.4 (Windows XP), Плата"Arduino Uno"
Покритикуйтье меня пожалуйста. Я хочу этот модуль применить к следующей задаче. Мне надо опредилить время между аварийным выключением питания и включением. Вот такая блок схема предлагается. Я считываю время с модуля ардуинкой каждую минуту и записываю в память модуля (EEPROM ардуины не подходит изза ограниченого колличества записей). Если ардуина замечает что разница текущего времени и времени в памяти модуля больше минуты, значит питание отключалось, ну и дальше понятно на сколько. Что скажите специалисты? Спасибо.
У at24c32 тоже ограничено число циклов записи, так что решение не лучшее. Заводите сигнал с питания на прерывание, а питание поддерживайте электролитами. Тогда при исчезновении питания, пока работает от электролитов ловите прерывание и записывайте время в EEPROM. Можна и во внутрений, без разницы впринципе.
Спасибо. Но мне непонятно все же как ардуина поймет что питание отключилось и пора сбрасывать в EEPROM. Может имеется ввиду что можно успеть зафиксиповать уменьшение напряжения питания от кнденсатора, пока он будет розряжаться. Какая тогда схема. Мне она видится следующим образом = Запитываем ардуину от стабилизированого источника до 12 В. електролитический конденсатор подключаем паралельно входному питанию и измеряем напряжение самой ардуиной. Когда напряжение станет ниже скажем 10В Начинаем аварийное сохранение данных и может успеем записаться до полной разрядки конденсатора. И тут возникает вопрос какой емкости брать конденсатор, ибо... ибо от этого будет зависеть погрешность в измерении времени
ИгорьУ, либо как говорит Logik (кстати этот вариант мы неоднократно обсуждали на форуме, ищите) , либо можно взять часы на чипе DS1307, в нём есть пользовательское ОЗУ на 56 байт, пиши в него сколько хошь..
(кстати этот вариант мы неоднократно обсуждали на форуме, ищите) Спасибо, Хоть по каким ключевым словам искать
Начинает доходить почему необходимо измерять напряжение именно с использованием прерывания.
Первые семь битов первого байта образуют адрес ведомого. Восьмой, младший бит, определяет направление пересылки данных. «Ноль» означает, что ведущий будет записывать информацию в выбранного ведомого. «Единица» означает, что ведущий будет считывать информацию из ведомого.(C) Wikipedia
В вашем случае 0x57 - адрес, а 0/1 справа - направление данных. Приписывать его к адресу не надо, библиотека сама добавит этот бит в зависимости от выбранной операции