slava68: (Default)
slava68 ([personal profile] slava68) wrote2017-11-07 10:59 pm

5 часов пухнущей головы

пишу код для ATmega328 (в ардуиновском IDE )

надо сохранять данные во внешний I2C EEPROM , потом считать всё (постранично) и загрузить на SD-карту.

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

Первая, из-за которой не спал прошедшую ночь - пишу в EEPROM постранично - всё отлично, но страница имеет размер 32 байта, а буфер библиотеки 30 байт, поэтому решил дописывать два байта "ручками". И вот они, то пишутся, то не пишутся. Никакой закономерности.
Полное заполнение I2C EEPROM каким-нибудь байтом тоже не работает. Записывает этот байт по случайным адресам :-(((
Так и лёг спать в 06:20. Уже в постели пришла в голову мысль, поставить задержку между обращениями к памяти... утром сделал - заработала "адская машина", даже _delay_ms(1); оказалось достаточно (пауза на одну микросекунду). Микросхема просто не успевает за "скоростным" I2C интерфейсом ATmega :-(

Вторая проблема - при чтении полностью забитого каким-либо байтом (байтами) EEPROM - всё отлично, но если читаю что-то осмысленное, то что я туда записал - после какого-то момента начинает "мести пургу", всегда разную.
Чтение непосредственно адресованной ячейки показывает именно те данные, которые я туда и записал, но при формировании считанного массива в строку - появляется мусор (не полицай, а случайные данные) :-(
За 5 часов вечернего секса сеанса программирования я уже понял, что проблему вызывает "сборище нулей" в считанных из EEPROMа данных и их последующее преобразование в String.

Ну , кто уже догадался ?


Форумы не помогли, помогла Википедия :-))) статья про таблицу ASCII

цитатка:

Примечание: далее в списке — коды символов записаны в шестнадцатеричной системе счисления, после названий символов.
NUL, 00 — null («пустой»). Символ null всегда игнорировался. На перфолентах, цифра «1» обозначалась отверстием, а цифра «0» — отсутствием отверстия. Участки перфоленты, на которых не была записана информация — не содержали отверстий (то есть содержали символы null); такие участки располагались в начале и в конце ленты. Символ null по сей день используется во многих языках программирования (как признак конца строки) и обозначается «\0». (Термин «строка» обозначает последовательность символов.) В некоторых операционных системах, null — последний символ любого текстового файла.


Считывая "ноль" и преобразовывая его в \0 я получаю "конец строки" в середине строки и дальше строка начинает заполняться своими собственными символами вперемешку с дополнительно считанными из EEPROM.

if (!ee_buffer[j]) ee_buffer[j] = 0x20; (если считанное число равно 0, то нарекаем его "пробелом" )

вот такая строчка решила всю проблему.

Надо будет подумать, как это поправить в консерватории сразу, при записи данных в EEPROM.

[personal profile] q33 2017-11-08 01:49 pm (UTC)(link)
мда......................... хрен что понял ну мож уважать надо как косманавта? или лучше завидовать- был бы таким умным сам бы свалил)