Пытаюсь работать с I2C EEPROM при помощи STM32F0. Почти получилось. Чтение работает без проблем (вроде как), а вот запись не работает. Причем так: если пройтись отладчиком - записывается, а если просто запустить - нет.
Если под отладчиком работает, а при обычном прогоне нет, то нужно вставить где нибудь паузу методом научного тыка. Обычно после команды записи байта/страницы нужна пауза.
Про EEPROM. - Страница начинается только с адреса кратного размеру страницы. - Цикл записи начинается по STOP условию. - Запись длится около 3 мс, отслеживать состояние готовности после записи лучше постоянно опрашивая EEPROM: START+адрес, пока идет запись не будет ACK'а.
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
В надежде на то, что библиотеки облегчают жизнь, два дня мучился для написания кода чтения и записи EEProm памяти с помощью библиотеки LL (Low layer libraries). Не помогло. Пришлось читать документацию и запоминать какой бит какого регистра за что отвечает. Нафига тогда библиотека, если она не облегчает написание кода? Даже примеров толком нет.
Короче, все таки набил код для записи, а потом чтения памяти. Без прерываний, просто, чтобы кто-то потратил на 2 дня меньше времени на освоение этой дури.
Код:
MX_I2C1_Init();
После базовой инициализации:
Код:
uint8_t slave_address = 0xA0; // Адрес ведомого устройства в шине I2C (микросхема памяти EEprom) uint16_t write_address = 0x0007; // Адрес в памяти EEprom, по которому будем записывать байт uint8_t wr_byte = 0xA4; // Записывать будем такой байт
/* Запись байта. * Номер I2C, по которому передавать данные, адрес ведомого устройства, к которому обращаемся, режим адресации 7 бит, * количество передаваемых байт 3, после завершения передачи сгенерировать СТОП-сигнал, * перед началом сгенерировать СТАРТ-сигнал с признаком записи байта */ LL_I2C_HandleTransfer(I2C1, slave_address , LL_I2C_ADDRSLAVE_7BIT, 3, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); while(!(LL_I2C_IsActiveFlag_TXE(I2C1))); LL_I2C_TransmitData8(I2C1, (uint8_t)(write_address >> 16)); while(!(LL_I2C_IsActiveFlag_TXE(I2C1))); LL_I2C_TransmitData8(I2C1, (uint8_t)(write_address)); while(!(LL_I2C_IsActiveFlag_TXE(I2C1))); LL_I2C_TransmitData8(I2C1, wr_byte); // Передача закончилась, автоматически сгенерирован СТОП-сигнал
HAL_Delay(3); // Ждем 3 мс, пока микросхема памяти прожует полученное.
uint16_t read_address = 0x0000; // Адрес в памяти EEprom, с которого начнем считывать байты (начнем с нуля)
/* Чтения байтов начиная с заданного адреса. * Номер I2C, по которому передавать данные, адрес ведомого устройства, к которому обращаемся, режим адресации 7 бит, * количество передаваемых байт 3, после завершения передачи НЕ генерировать СТОП-сигнал, * перед началом сгенерировать СТАРТ-сигнал с признаком записи байта (ДА, ЗАПИСИ, сначала отправляем адрес в памяти, * с которого хотим начать чтение) */ LL_I2C_HandleTransfer(I2C1, slave_address, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_SOFTEND, LL_I2C_GENERATE_START_WRITE); while(!(LL_I2C_IsActiveFlag_TXE(I2C1))); // Флаг означает, что Выходной буфер свободен и можно записывать следующее значение LL_I2C_TransmitData8(I2C1, (uint8_t)(read_address >> 16)); while(!(LL_I2C_IsActiveFlag_TXE(I2C1))); LL_I2C_TransmitData8(I2C1, (uint8_t)(read_address));
while(!(LL_I2C_IsActiveFlag_TC(I2C1))); // Флаг означает, что все (два) байта переданы // Передача закончилась, но СТОП-сигнал не генерируется (такой формат общения с памятью)
/* * Генерируем СТАРТ-сингал с признаком чтения байта. Будем принимать 13 байт, после окончания приема сгенерировать * СТОП-сигнал. */ LL_I2C_HandleTransfer(I2C1, slave_address, LL_I2C_ADDRSLAVE_7BIT, 13, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
uint8_t i; uint8_t receive_buf[32] = {0}; // Массив для записи принятых байт
for(i=0; i<13; i++){ while(!(LL_I2C_IsActiveFlag_RXNE(I2C1))); // Флаг означает, что в Приемном буфере появились данные receive_buf[i] = LL_I2C_ReceiveData8(I2C1); // Списываем байт из Приемного буфера } // Все байты приняты, автоматически генерируется СТОП-сигнал
Как выглядит Запись в анализаторе:
Как выглядит чтение 13 байт начиная с адреса 0x0000:
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Странные вы ребята, на HAL есть встроенные функции специально для чтения записи ЕЕПРОМ - работают без проблем.
При использовании HAL например на STM32F030F4 с 16 кб, оный сожрет 2\3 флэша, после чего вы откроете референс мануал, обматерите HAL LL SPL, и сделаете все руками. При этом скажите большое спасибо человеку выложившему свои наработки!
С cmsis я ничего не настраивал в проекте, I2C заработал, пишет и читает во все и отовсюду (до чего руки дотянулись) и лишнего не жрет. Какой смысл делать себе нервы халом?
_________________ Астролябия-сама меряет, было бы что мерять!!!
Короче, все таки набил код для записи, а потом чтения памяти. Без прерываний, просто, чтобы кто-то потратил на 2 дня меньше времени на освоение этой дури.
Поправьте меня если я не прав, но код содержит ошибки. После сдвига 16-битного значения на 16 Вы всегда получаете 0 Иными словами, программа пишет и читает 0ю ячейку памяти вне зависимости от введенного адреса.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 18
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения