Пытаюсь работать с I2C EEPROM при помощи STM32F0. Почти получилось. Чтение работает без проблем (вроде как), а вот запись не работает. Причем так: если пройтись отладчиком - записывается, а если просто запустить - нет.
Если под отладчиком работает, а при обычном прогоне нет, то нужно вставить где нибудь паузу методом научного тыка. Обычно после команды записи байта/страницы нужна пауза.
Про EEPROM. - Страница начинается только с адреса кратного размеру страницы. - Цикл записи начинается по STOP условию. - Запись длится около 3 мс, отслеживать состояние готовности после записи лучше постоянно опрашивая EEPROM: START+адрес, пока идет запись не будет ACK'а.
Любая разработка начинается с чтения документации и изучения доступных средств разработки. Данный материал целиком посвящен средствам разработки, включая детальные инструкции по запуску вашего первого приложения на BlueNRG-LP. Описана работа с отладкой STEVAL-IDB011V1, набором инструментов и пакетом ПО позволяющим разработчику быстро войти в курс дела.
В надежде на то, что библиотеки облегчают жизнь, два дня мучился для написания кода чтения и записи 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:
Что привлекает в SiC по сравнению с кремнием, и какие особенности делают компоненты SiC часто используемыми, несмотря на более высокую стоимость в сравнении с кремниевыми высоковольтными устройствами? – Объясняет специалист ведущего разработчика силовых приборов из карбида кремния, компании Infineon.
Странные вы ребята, на HAL есть встроенные функции специально для чтения записи ЕЕПРОМ - работают без проблем.
При использовании HAL например на STM32F030F4 с 16 кб, оный сожрет 2\3 флэша, после чего вы откроете референс мануал, обматерите HAL LL SPL, и сделаете все руками. При этом скажите большое спасибо человеку выложившему свои наработки!
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения