Перейти к содержанию

I2C Память И Битые Байты


Рекомендуемые сообщения

Привет!

Есть у меня один проект на pic24, который использует EEPROM 24LC256.

И все бы хорошо, но иногда данные записываются некорректно.

Чаще всего такое происходит при записи 4х байтовых чисел, хотя они в основном и пишутся, так что не удивительно. И чаще всего повреждается последний байт числа. Повреждается примерно один из нескольких десятков байт.

Память висит на довольно короткой шине ~1.5 см от контроллера, подтяжки на линиях 4.7кОм. С памятью работаю на частоте 400 кГц, снижение частоты не дало никакого эффекта. Повторяется бага на нескольких одинаковых платах. Закономерности выявить не удалось. Выяснил только что мой код пытается записать правильные данные, то есть повреждаются они именно в процессе записи.

Привожу фрагмент кода для роботы с eeprom:

unsigned char ee_adress(int adr)
{
 unsigned char cmd;
 cmd = 0xA0; // | ((adr >> 7)&0xE);
 while (1)
 {
   StartI2C(); IdleI2C();
   // send command and address msb(3)
   MasterWriteI2C(cmd + WRITE_CMD); IdleI2C();
   if (I2CSTATbits.ACKSTAT == 0)
     break;
   StopI2C(); IdleI2C();
 } // while waiting for ACK
 // 3. send address lsb
 MasterWriteI2C(adr >> 8); IdleI2C();
 MasterWriteI2C(adr & 0xFF); IdleI2C();
 // 4. exit returning the cmd byte
 return cmd;
}

void ee_wrDword(int adr, unsigned long data)
{
 // 1. select address
 ee_adress(adr);
 // 2. stream data out
 MasterWriteI2C((data >> 24) & 0xFF); IdleI2C();
 MasterWriteI2C((data >> 16) & 0xFF); IdleI2C();
 MasterWriteI2C((data >> 8 ) & 0xFF); IdleI2C();
 MasterWriteI2C((data >> 0 ) & 0xFF); IdleI2C();
 // 3. terminate the command sequence
 StopI2C(); IdleI2C();
}

Может кто то сталкивался с подобным? В какую сторону копать? Я уже все на что фантазии хватило перепробовал.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Возможно не корректно пишется, когда страница записи меньше рекомендованной.

Хотя протокол допускает запись единичного байта. ( с 24LC256 не работал )

Возможно, что время отпускаемое на запись меньше допустимого.

Мыши кололись, плакали, но продолжали жрать кактус.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

У EEPROM не страничная организация, там есть только буфер записи в 64 байта. Перед записью проверяется опустошение этого самого буфера, то есть завершение процесса записи (цикл в функции ee_adress()) в полном соответствии с Datasheet. Да и задержки я пробовал добавлять, не помогает :(

Изменено пользователем alkom
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

И этот буфер по какой-то случайности назвали Page!

Даже. если буфер не опустошился, то новая запись в буфер убьёт предыдущее состояние.

Да, мы всё равно не можем проконтролировать это.

Может тайминги не соблюдаются?

А ты WP не дёргаешь?

Мыши кололись, плакали, но продолжали жрать кактус.

Ссылка на комментарий
Поделиться на другие сайты

WP не дергаю, не надо оно мне. Выяснил тут новые подробности. Ошибка повторяется на конкретных адресах памяти, раньше не заметил, т. к. запись ведется со смещением. Некоторые ячейки читаются всегда одинаково, в не зависимости от того что в них записали. Пока нашел 2 таких, одна читается как 0 другая как 0x67. Вроде как похоже на битую память, но блин на тестовой прошивке, которая забивает всю память какими либо числами и делает верификацию всё работает, ни одной ошибки блин!

Я уже прилепил чтение и верификацию прямо в процедуру записи - фиг, читается всё тот же мусор, то есть ни в каком другом месте программы ячейки эти не перезаписываются. Мистика блин!

Ссылка на комментарий
Поделиться на другие сайты

Мне попадались 24с02 с битыми байтами, но это были старые, поработавшие чипы.

Мыши кололись, плакали, но продолжали жрать кактус.

Ссылка на комментарий
Поделиться на другие сайты

Память точно целая.

Вот два куска кода для примера:

Просто проверка всех адресов микросхемы:

unsigned long read, write;
 unsigned int adr;
 write = 0xAAAAAAAA;
 for(adr = 0; adr < 0x7FFF; adr+=4)
 {
  if(!(adr%100))
  {
   sprintf(debug_txb, "Adr: %u\r\n", adr);
   U1TXREG = debug_txb[0];
  }
  ee_wrDword(adr, write);
  read = ee_rdDword(adr);
  if (read != write)
  {
   sprintf(debug_txb, "Adr: %u Write: %lu Read: %lu", adr, write, read);
   U1TXREG = debug_txb[0];
  }
 }

это работает без запинки.

А вот код который должен бы работать:

for(i = 0; i < 8; i++)
{
if((RtccTimeDate.f.hour == DEC2BCD(ctrl_points[i])) && (RtccTimeDate.f.min == 0))
{
 int j;
 int pointer = ee_rdInt(ADDR_POINTER);
 for (j = 0; j < COUNTERS; j++)
 {
  ee_wrDword(pointer + j*4 + i*24, counters[j].total_value);
 }
}
}

Но не работает( Отладчиком захожу в функцию записи - все параметры передаются правильно, вроде как записывается, а читается фигня.

Ссылка на комментарий
Поделиться на другие сайты

Я писал протокол на ассемблере, поэтому не понимай ничего другого.

Попробуй записать чип программатором, а верификацию сделай в устройстве.

Потом наоборот. Тогда точно будет известно где ошибка - может при чтении возникает.

Тестовую программу не используй, сначала запиши весь объём FFами , потом нулями.

Тогда траблу можно увидеть просто глазом.

А ты в PICе модуль I2C используешь?

А у тебя адресация идёт по четыре байта?

В смысле запись и чтение по четыре байта?

Попробуй читать память полностью - sequential read весь объём, а записывать page write по 64 байта.

Изменено пользователем ГОГА рижский

Мыши кололись, плакали, но продолжали жрать кактус.

Ссылка на комментарий
Поделиться на другие сайты

В общем там действительно страничная организация памяти и если во время последовательной записи упираемся в конец страницы то все что дальше просто игнорируется. Хотя в их даташите я так этого и не нашел, видимо мое знание английского не дотягивает. Теперь маленькие объемы пишу просто побайтово, а большие страницами. Пока все работает, спасибо за помощь!

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...