Если ваш мастер-контроллер это STM32F103 и аналогичные ему, то когда вам нужно считать из ведомого устройства всего ОДИН байт, после сброса флага ADDR (а сбрасывается он чтением регистра I2Cx->SR2, что совсем не очевидно, но описано в документации), сразу же выставляйте флаги генерации NACK и STOP:
dummy = I2C1->SR2; /* Clear ADDR flag by reading SR2 register */ I2C1->CR1 &= ~(I2C_CR1_ACK); // NACK (this is last byte) I2C1->CR1 |= I2C_CR1_STOP; // generate stop after current byte transfer
Иначе (если, например, сначала дожидаться передачи байта) флаг NACK не сгенерируется и принимающее устройство будет тщетно надеяться на продолжение транзакции. А вот дожидаться срабатывания условия останова нужно ПОСЛЕ передачи байта (что логично).
А если ваше ведомое устройство сделано на STM32F030, то там модуль I2C работает...хмм... не совсем так. Поэтому в простейшем виде транзация "ведомого передатчика" выглядит так:
1) совпал адрес? Если да, переходим к (2). Если нет, ничего не делаем.
2) сбрасываем флаг ADDR. Смотрим на флаг DIR. Если он установлен, от нас хотят данные - переходим к (3). Иначе переходим к (4)
3) Записываем байт данных в регистр передатчика TXDR (в 030 у передатчика и приёмника i2c два разных регистра, в отличие от 103), дожидаемся установки флага TXE ("передача завершена"). Так как это однобайтовая транзакция, то тут же дожидаемся установки флага NACK (и сбрасываем его), затем STOP (и тоже сбрасываем). Возвращаемся к (1)
4) дожидаемся установки флага RXNE ("приёмный буффер заполнен"). Т.к. мы щас рабоаем только с однобайтовыми транзакциями, генерируем NACK, читаем байт из RXDR, что-то с ним интересное делаем, возвращаемся к (1)
Вот, теперь я могу пересылать однобайтовые данные между 103 и 030. Полдела сделано ;)
Теперь прикрутить пересылку длинных пакетов и, собсно, готов обычный I2C протокол.
Но даже в таком куцем виде он ужде пригоден для использования в контроллере небольшой матричной клавиатуры, ибо пересылать больше одного байта за раз тут просто не нужно.
Судя по различиям, серия 030 появилась позже, чем 103 - работа с периферией сделана более продуманно, кмк. При всём уважении к почтенному 103, многие вещи в нём сделаны через жопу. Оно, конечно, работает, но осадочек постоянно какой-то есть.