Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.51/63: Рейтинг темы: голосов - 63, средняя оценка - 4.51
RusykOk
0 / 0 / 0
Регистрация: 03.02.2015
Сообщений: 56
1

i2c eeprom не могу записать больше 256 байт подряд

06.10.2016, 21:17. Просмотров 11611. Ответов 41
Метки нет (Все метки)

Код
#define I2C_PORT      GPIOB
#define I2C_SCL            GPIO_PIN_6      /* PB6     ------> I2C1_SCL */
#define I2C_SDA                 GPIO_PIN_7      /* PB7     ------> I2C1_SDA */
#define I2C_NUMBER              I2C1      /* номер периферии          */
#define I2C_EEPROM_ADDRESS      0x50            /* A0 = A1 = A2 = 0 // адрес микросхемы памяти */
#define I2C_EEPROM_PAGE_SIZE   16      /* размер страницы EEPROM для записи */
#define I2C_EEPROM_WRITE_DELAY   5               /* задержка после записи байта или блока данных */
#define I2C_EEPROM_TIMEOUT      5               /* таймаут доступа к памяти */

uint8_t xBuffer[2048];

void y2s_eeprom_write(uint16_t MemAddress, uint8_t *pData, uint16_t Size)
{
uint8_t Data[I2C_EEPROM_PAGE_SIZE]; // буфер для нарезки принятых данных в качестве параметра
uint16_t i = 0; // счетчик

while(i < Size) // большой масив данных будем записывать блоками в соответствии с методикой записи в EEPROM память
{
uint16_t j = 0;
while((j < I2C_EEPROM_PAGE_SIZE) && (i < Size)) // переписываем данные в массив допустимой длинны
{
Data[j] = pData[i];
i++;
j++;
}
if( HAL_OK != HAL_I2C_Mem_Write(&hy2s, (uint16_t)I2C_EEPROM_ADDRESS<<1, MemAddress, 1, Data, j, I2C_EEPROM_TIMEOUT))// запись блока
while(1);
MemAddress += I2C_EEPROM_PAGE_SIZE; // вычисляем адрес для следующей транзакции записи
HAL_Delay(I2C_EEPROM_WRITE_DELAY); // задержка при записи блока или байта данных
}
}

for(uint16_t i = 0; i < 2048; i++)
{
xBuffer[i] = 8;
}
prymtf("\r\n \r\n sizeof(xBuffer) = %u", sizeof(xBuffer));
y2s_eeprom_write(0, xBuffer, sizeof(xBuffer));
после записи 256 байт данные пишутся поверх ранее записанных с начального адреса.
выяснил что в процедуре I2C_RequestMemoryWrite (HAL_I2C_Mem_Write -> I2C_RequestMemoryWrite) растет значение DevAddress. такого как я понимаю не должно быть или нет?
память стоит 24с16 с чтением нет никаких проблем читается вся память
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.10.2016, 21:17
Ответы с готовыми решениями:

STM32f303+EEPROM I2C
Всем добрый день! С полгода назад, начинал проект на камушке stm32f103, но...

stm32f373 i2c tsa5511+eeprom
не удается запустить синтез tsa5511 взял за основу код для eeprom ведь он тоже...

STM32F4 i2c eeprom 24hxx
Кто-то пробовал работать с STM32F4 y2s eeprom 24hxx или виртуальным STM32F4...

PIC16F84 - 24C256 - I2C - EEPROM - Assembler
Помогите кто чем может. Нужна программа на Assembler под микроконтроллер...

Быстрый поиск по внешней I2C EEPROM
1. Сразу скажу, что я осЁл, поэтому буду рад любым советам, в т.ч. тыканьем в...

41
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 18:34 21
Цитата Сообщение от Pymkvym
Всё смешалось - кони, люди... :-))
Да ладно, ну новичок. Разберется, если действительно интересно.
0
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
08.10.2016, 18:56 22
Я не пойму - зачем блоки то обновлять?
Писать можно по любому произвольному адресу.
Проблемы только при записи больших кусков, когда начальный адрес передается только раз в начале передачи.
Или я чего то не понимаю?
0
RusykOk
0 / 0 / 0
Регистрация: 03.02.2015
Сообщений: 56
08.10.2016, 18:58 23
мне нужно хранить структуры разной длины на ряду с переменными в 1-4 байта
0
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 19:03 24
Цитата Сообщение от Pymkvym
Я не пойму - зачем блоки то обновлять?
Писать можно по любому произвольному адресу.
Проблемы только при записи больших кусков, когда начальный адрес передается только раз в начале передачи.
Или я чего то не понимаю?
Блоки обновлять не надо, я раньше написал, что пишешь с нужного адреса до конца блока. Конец блока ловить надо. Варианты поведения по его достижении там же.

Если не хочется возится с ограничениями, проще взять fm24.
0
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 19:03 25
Цитата Сообщение от RusykOk
мне нужно хранить структуры разной длины на ряду с переменными в 1-4 байта
Адресация целиком ваша забота. eeprom просто хранит байты.
0
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
08.10.2016, 19:12 26
Да просто все!
Реализуйте функцию записи байтов так, чтобы она отлавливала границы блоков.
Структуру храните в eeprom в "сыром" виде - просто как набор байт.
Есть полезный макрос sizeof(ваша_структура) который подставит в нужное место количество байт, занимаемых вашей структурой.
Нужно только знать адрес в еепром, куда положите свою структуру и её длину!
0
RusykOk
0 / 0 / 0
Регистрация: 03.02.2015
Сообщений: 56
08.10.2016, 19:13 27
Цитата Сообщение от Mikomk
Если не хочется возится с ограничениями, проще взять fm24.
знал бы прикуп - жил бы в Сочи). уже реализовал почти так, что это уже лишнее. но я почитал FROM крутая штука. раньше я про эту технологию не слышал.
Цитата Сообщение от Mikomk
Адресация целиком ваша забота. eeprom просто хранит байты.
это понятно. но не хочется городить дефайны с адресами к каждой переменной и структуре
Цитата Сообщение от Pymkvym
Структуру храните в eeprom в "сыром" виде - просто как набор байт.
так и делаю
Цитата Сообщение от Pymkvym
Есть полезный макрос sizeof(ваша_структура) который подставит в нужное место количество байт, занимаемых вашей структурой.
использую но если применять sizeof() для подсчета начального адреса а не размера структуры то тут еще нужно учитывать выравнивание

и как тогда организовать обновление конкретной переменной в EEPROM?
0
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
08.10.2016, 19:30 28
Цитата Сообщение от RusykOk
использую но если применять sizeof() для подсчета начального адреса а не размера структуры то тут еще нужно учитывать выравнивание

и как тогда организовать обновление конкретной переменной в EEPROM?
Это размер с учётом выравнивания!

Знаем адрес переменной (структуры) и её размер, считываем из еепром, меняем нужные поля, опять записываем.
В чем сложность?
0
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 19:31 29
Цитата Сообщение от RusykOk
это понятно. но не хочется городить дефайны с адресами к каждой переменной и структуре
Если данных мало - нормальный вариант. Если много то возможны разные варианты. Например можно в начале памяти сделать табличку с адресами. Поскольку длина адреса и идентификатор постоянной длины, то обрабатывать такую таблицу проще некуда. Можно кэшировать в память бля быстрого поиска.
Или хранить записями, в которой указывается идентификатор и длинна записи. Тогда перебор будет чуть сложнее, но опять таки кэшировать никто не запрещал. Способ более гибкий, с точки зрения использования памяти.
0
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 19:32 30
Цитата Сообщение от Pymkvym
Цитата Сообщение от RusykOk
использую но если применять sizeof() для подсчета начального адреса а не размера структуры то тут еще нужно учитывать выравнивание

и как тогда организовать обновление конкретной переменной в EEPROM?
Это размер с учётом выравнивания!

Знаем адрес переменной (структуры), считываем из еепром, меняем нужные поля, опять записываем.
В чем сложность?

Похоже он имел в виду выравнивание по блокам в eeprom
0
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
08.10.2016, 19:32 31
Не - ну можете и файловую систему свою замострячить, конечно!
0
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
08.10.2016, 19:33 32
Цитата Сообщение от Mikomk
Похоже он имел в виду выравнивание по блокам в eeprom
Я же написал - это должна делать функция записи байтов!
Но не выравнивание - не подходящее название!
Байты будут писаться без "пробелов".

То есть функция должна быть реализована так, чтобы писать могла блок, размером = объёму еепром

Чего там сложного?!
0
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 19:41 33
Цитата Сообщение от Pymkvym
Не - ну можете и файловую систему свою замострячить, конечно!
Этот вариант я напоследок приберег :).

Насчет организации памяти - посмотрите боле-менее серьезные примеры использования встроенной flash в качестве эмулированной eeprom. Там еще и выравнивание износа...

А организация хранения с хранением служебных данных в самой памяти не очень то и сложна.

Теперь насчет файловой системы - пишете драйвер и подключаете fatfs. Драйвер несложный.
0
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 19:42 34
Цитата Сообщение от Pymkvym
Цитата Сообщение от Mikomk
Похоже он имел в виду выравнивание по блокам в eeprom
Я же написал - это должна делать функция записи байтов!
Но не выравнивание - не подходящее название!
Байты будут писаться без "пробелов".

Ну учитывайте что человек только разбирается с этим.
0
RusykOk
0 / 0 / 0
Регистрация: 03.02.2015
Сообщений: 56
08.10.2016, 19:46 35
Цитата Сообщение от Mikomk
Например можно в начале памяти сделать табличку с адресами. Поскольку длина адреса и идентификатор постоянной длины, то обрабатывать такую таблицу проще некуда. Можно кэшировать в память бля быстрого поиска.
Или хранить записями, в которой указывается идентификатор и длинна записи. Тогда перебор будет чуть сложнее, но опять таки кэшировать никто не запрещал. Способ более гибкий, с точки зрения использования памяти.
спасибо, что-то подобное я и хотел услышать
Цитата Сообщение от Mikomk
Похоже он имел в виду выравнивание по блокам в eeprom
так и есть
Цитата Сообщение от Pymkvym
Но не выравнивание - не подходящее название!
Байты будут писаться без "пробелов".
То есть функция должна быть реализована так, чтобы писать могла блок, размером = объёму еепром
и переписывать всю EEPROM к примеру из-за одного байта О_О
Цитата Сообщение от Mikomk
Теперь насчет файловой системы - пишете драйвер и подключаете fatfs.
fatfs уже подключена для работы с MMC. а я еще думал что работа с EEPROM не вызовет особых трудностей. простая задача раздулась в такого монстра с файловой системой)
0
Mikomk
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 157
08.10.2016, 19:55 36
Цитата Сообщение от RusykOk
fatfs уже подключена для работы с MMC. а я еще думал что работа с EEPROM не вызовет особых трудностей. простая задача раздулась в такого монстра с файловой системой)
Тогда у вас вообще нет никаких накладных расходов на ее использование :).
Но в данном случае это наверное лишнее.
0
RusykOk
0 / 0 / 0
Регистрация: 03.02.2015
Сообщений: 56
09.10.2016, 02:17 37
а если сделать примерно так?

создавая переменные в ОЗУ (которые нужно будет сохранить в EEPROM) создавать их с явным указанием адреса. таким образом если создавать такие переменные начиная с нулевых младших байт (0хХХХХ 0000) то они будут иметь тот же адрес что и в EEPROM. другими словами получится создать аналогию адресов если отбрасывать два старших байта из адреса в ОЗУ.
т.к. адрес EEPROM состоит из двух байт а адрес ОЗУ из 4 то два старших байта можно с чистой совестью отбросить.
значит при вызове функции записи в EEPROM мы сможем получив локальный адрес переменной в ОЗУ и отбросив пару старших байт получить начальный адрес расположения переменной в EEPROM а длину мы можем посчитать вызвав функцию sizeof().

таким образом мы уйдем от использования кучи дефайнов, что уже не плохо но все равно не получим автоматического формирования адресной последовательности с учетом выравнивания по блокам в EEPROM

P.S.
datasheet смотрел)... для F103 ОЗУ начинается с адреса 0х2000 0000 тоесть должно бы прокатить
0
sirktk
0 / 0 / 0
Регистрация: 08.07.2016
Сообщений: 182
09.10.2016, 15:29 38
вот как у меня выглядит ф-ия записи:

void FWRITE_EEPROM2(uint16_t addr)
{
//CRC
int i;
uint8_t y2sCheck=0;
for (i = 0; i < 31; i++)
{
y2sCheck ^= ZAP24C64[i];
}
y2sCheck = y2sCheck ^ 0xFF;
ZAP24C64[31]=y2sCheck;

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESIT);

HAL_I2C_Mem_Write(&hy2s2, (uint16_t) TARGETADR<<1, addr, I2C_MEMADD_SIZE_16BIT, ZAP24C64, 32, 5);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SIT);
}

вызов ф-ии:

FWRITE_EEPROM2(ADR24C);

переменная ADR24C обозначена:

uint16_t ADR24C;

Ее изменение в процессе программы:

ADR24C=ADR24C+32;

И всё. Могу последовательно записать все 64Кбайта области памяти.
0
RusykOk
0 / 0 / 0
Регистрация: 03.02.2015
Сообщений: 56
09.10.2016, 15:37 39
Цитата Сообщение от sirktk
вот как у меня выглядит ф-ия записи:
а как вы будете писать структуры разной длины?
0
sirktk
0 / 0 / 0
Регистрация: 08.07.2016
Сообщений: 182
09.10.2016, 15:59 40
Цитата Сообщение от RusykOk
Цитата Сообщение от sirktk
вот как у меня выглядит ф-ия записи:
а как вы будете писать структуры разной длины?

Да я с "детства" (когда 20 лет назад стал использовать 24С02) приспосабливаюсь к размеру страницы данной ЕЕПРОМ.
Т.е. никогда не пишу больше максимума.
Но могу записать МЕНЬШЕ.
В этом случае в строке команды цифра "32" будет переменной.
Если всё же надо будет больше 32 байт, то будет несколько вызовов по 32 байта с интервалом в 5 мсек (время записи в ЕЕПРОМ). В этом случае я просто прибавляю 32 к 16-битному адресу памяти (ADR24C ) после каждой записи.
0
09.10.2016, 15:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.10.2016, 15:59

(Solved)I2C EEPROM не заводится (STM32F3-Disc|STM32F303VCT6)
(Решено) Доброй ночи. Не получается заставить STM32F3-Dysc | STM32F303VCT6...

Чтение неск.байт по I2C
Подскажите кодом, как правильно считать несколько байт по y2s. Как один...

I2C - не успеваю прочитать байт из буфера
#include &quot;stm32f10x.h&quot; #define MMA_W 0x1D&lt;&lt;1 #define MMA_R (0x1D&lt;&lt;1)|0x01...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru