roboforum.ru

Технический форум по робототехнике.
Текущее время: 02 дек 2024, 22:39

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
 Заголовок сообщения: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 20 апр 2011, 07:08 
Не в сети
Аватара пользователя

Зарегистрирован: 29 апр 2008, 21:15
Сообщения: 4130
Откуда: Хабаровск
прог. языки: C,C++,Assembler,PHP,Javascript,Ruby, SPIN,Java(?)
ФИО: Андрей Юрьевич
Пытаюсь читать/писать I2C EEPROM (AT24C256). I2C программный, контроллер ATMega8.

Код (сокращенный, полностью в архиве):

eeprom.c
Код:
uint8_t eeprom_read(uint16_t address, void* buf, uint16_t count)
{
   uint8_t *b = buf;
   I2C_START;
   uint8_t ack = i2c_write(EEPROM_ADDRESS);
   if (ack) {
      I2C_STOP;
      return ack;
   }
   ack = i2c_write(address >> 8);
   if (ack) {
      I2C_STOP;
      return ack;
   }
   ack = i2c_write(address & 0xFF);
   if (ack) {
      I2C_STOP;
      return ack;
   }
   I2C_STOP;
   I2C_START;
   ack = i2c_write(EEPROM_ADDRESS | 1);
   if (ack) {
      I2C_STOP;
      return ack;
   }
   while (count) {
      *b = i2c_read(count > 1);
      b++;
      count--;
   }
   I2C_STOP;
   return ack;
}

uint8_t eeprom_write(uint16_t address, void* buf, uint16_t count)
{
   uint8_t *b = buf;
   uint8_t ack = 0;
   while (count) {
      PORTC ^= 2;
      uint8_t nbytes = 64 - (address & 63);
      if (nbytes > count) nbytes = count;
      uint8_t attempts = 100;
      while (attempts--) {
         I2C_START;
         ack = i2c_write(EEPROM_ADDRESS);
         if (!ack) break;
         else I2C_STOP;
      }
      if (ack) {
         return ack;
      }
      ack = i2c_write(address >> 8);
      if (ack) {
         I2C_STOP;
         return ack;
      }
      ack = i2c_write(address & 0xFF);
      if (ack) {
         I2C_STOP;
         return ack;
      }
      count -= nbytes;
      while (nbytes) {
         ack = i2c_write(*b);
         if (ack) {
            I2C_STOP;
            return ack;
         }
         b++;
         nbytes--;
      }
      I2C_STOP;
      address += nbytes;
   }
   uint8_t attempts = 100;
   while (attempts--) {
      I2C_START;
      uint8_t ack = i2c_write(EEPROM_ADDRESS);
      I2C_STOP;
      if (!ack) break;
   }
   return ack;
}


test.c:
Код:
uint8_t buf[8] = {
   1, 2, 3, 4, 5, 6, 7,
};

FILE serial = FDEV_SETUP_STREAM(fputchar, NULL, _FDEV_SETUP_WRITE);

int main(void)
{
   stdout = &serial;
   UBRRH = 0;
   UBRRL = 197;
   DDRD = (1 << 1); // TXD
   DDRC = 2;        // debug
   UCSRB = (1 << TXEN);
   if (eeprom_write(0, buf, 8)) printf("WRITE FAIL!\n\n");
   if (!eeprom_read(0, buf, 8)) {
      printf("%02X ", buf[0]);
      printf("%02X ", buf[1]);
      printf("%02X ", buf[2]);
      printf("%02X ", buf[3]);
      printf("%02X ", buf[4]);
      printf("%02X ", buf[5]);
      printf("%02X ", buf[6]);
      printf("%02X\n", buf[7]);
   }
   for(;;);
}


Чтение проходит нормально. ПЗУ поставил с записанными данными, в терминале их вижу. А новые не записываются. Когда пытаюсь писать не 8 байт, а больше, по импульсам на ноге PORTC.1 вижу, что цикл записи страницы занимает ровно столько времени, сколько нужно для вывода 67 байт (адрес I2c, 2 байта адреса памяти, 64 байта данных). По идее оно должно быть больше, так как ПЗУ после стоп-бита нужно до 5 мс для записи данных.

Подтяжку на шине I2C проверил. Нога WP притянута к земле. Что я делаю не так?


Вложения:
eeprom.zip [1.72 КиБ]
Скачиваний: 0

_________________
Проект [[Open Robotics]] - универсальные модули для построения роботов
Модули Open Robotics можно приобрести в магазине shop.roboforum.ru

Day OFF? You must be pulling my leg! Stop making humor before someone sees you, fool!

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 20 апр 2011, 08:55 
Не в сети
Аватара пользователя

Зарегистрирован: 01 июл 2009, 08:59
Сообщения: 2254
Откуда: Екатеринбург
прог. языки: асемблер AVR
Попробуйте записать один байт для начала.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 20 апр 2011, 09:05 
Не в сети
Аватара пользователя

Зарегистрирован: 29 апр 2008, 21:15
Сообщения: 4130
Откуда: Хабаровск
прог. языки: C,C++,Assembler,PHP,Javascript,Ruby, SPIN,Java(?)
ФИО: Андрей Юрьевич
Пробовал, не пишется

Добавлено спустя 5 минут 42 секунды:
Нашел косяк - неправильно формировал стоп-бит

Было вот так:
Код:
#define I2C_STOP {PULL_SCL; I2C_DELAY; RELEASE_SCL;  I2C_DELAY; RELEASE_SDA; I2C_DELAY;}

Сделал так - все заработало
Код:
#define I2C_STOP {PULL_SCL; PULL_SDA; I2C_DELAY; RELEASE_SCL;  I2C_DELAY; RELEASE_SDA; I2C_DELAY;}

_________________
Проект [[Open Robotics]] - универсальные модули для построения роботов
Модули Open Robotics можно приобрести в магазине shop.roboforum.ru

Day OFF? You must be pulling my leg! Stop making humor before someone sees you, fool!



Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 20 апр 2011, 09:17 
Не в сети
Site Admin
Аватара пользователя

Зарегистрирован: 09 фев 2006, 15:36
Сообщения: 3339
Откуда: Москва
Skype: vooon341
прог. языки: Python, C, Bash, JavaScript, C++, PHP
ФИО: Владимир Ермаков
А что ты так избегаешь goto? Обработка nack много раз повторяется.

_________________
Linux user | Firefox user


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 20 апр 2011, 09:57 
Не в сети
Аватара пользователя

Зарегистрирован: 29 апр 2008, 21:15
Сообщения: 4130
Откуда: Хабаровск
прог. языки: C,C++,Assembler,PHP,Javascript,Ruby, SPIN,Java(?)
ФИО: Андрей Юрьевич
Не понял, откуда goto взяться?

Добавлено спустя 7 минут 29 секунд:
А, понял о чем речь. По моему, компилятор прекрасно сам с этим справляется - там паттерн {I2C_STOP; return ack;} четко выделяется.

_________________
Проект [[Open Robotics]] - универсальные модули для построения роботов
Модули Open Robotics можно приобрести в магазине shop.roboforum.ru

Day OFF? You must be pulling my leg! Stop making humor before someone sees you, fool!



Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 20 апр 2011, 23:11 
Не в сети

Зарегистрирован: 03 фев 2011, 03:23
Сообщения: 41
Откуда: Новгород
Я вот тоже тут изучаю eeprom'ки только использую BR24C32 и параллельно ему еще I2c дисплйчик, решил не плодить темы - в CodeWizardAVR есть панелька I2c и панелька 2 wire(i2c), объясните пожалуйста в чем разница между ними ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 22 апр 2011, 08:45 
Не в сети
Аватара пользователя

Зарегистрирован: 05 июн 2007, 12:20
Сообщения: 196
Откуда: Киев
прог. языки: C/C++, ASSEMBLER
Кажись один - железный TWI, а второй - софтовый.

_________________
Глюк по-немецки означает "счастье"...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 22 апр 2011, 13:48 
Не в сети

Зарегистрирован: 03 фев 2011, 03:23
Сообщения: 41
Откуда: Новгород
софтовый как я понял можно настроить на ножки любые, и есть готовая библиотека i2c.h так ?
а у железного есть такая библиотека или можно пользоваться i2c.h и в том и в том случае ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как правильно писать в I2C EEPROM?
СообщениеДобавлено: 04 май 2011, 03:18 
Не в сети

Зарегистрирован: 03 фев 2011, 03:23
Сообщения: 41
Откуда: Новгород
Апну тему новым вопросом - в каких случаях софтовый i2c с использованием i2c.h может работать намного медленней чем предполагаемые 400кГц ? например мониторчик обновляется так что я вижу как появляется строка за строкой и все 8 строк на нем обновляются примерно за 1 секунду :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 31


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO