Не понятно в чем вопрос? В эмуляции i2c, или в эмуляции ds1307?
раз не указываете мк, то подразумевается, что аппаратного i2c слейва на борту нет и вам нужен ногодрыг?
Ногодрыг можно так реализовать:
из даташита на ds1307 SCL на максимальной частоте (100 кГц). Один так на и2ц 0,01 мс. Про реализацию такого ногодрыга средствами ртос - забудьте. Обычно у ртос системный тик 1 мс.
Нужно делать на прерываниях: GPIO + TIM. Делайте глобальные переменные, в которых размешаете текущее состояние и2ц, текущий номер бита, адреса, команды и т.п.
Изначально текущее состояние и2ц ESTABLISHED. Ловите прерывание на SCL по заднему фронту, если при этом на SDA было лог "1", то состояние меняете на "Ожидание tHD:STA". Запускаете таймер ждете.... если сработало прерывание на SDA 1-0, то был старт. Если сработал таймер, то возвращаетесь в ESTABLISHED (ожидание старта).
если был старт, то запускаете таймер на ожидание фронта 0-1 на CLK, меняете состояние на "ожидание первого байта адреса". Пришло прерывание 0-1 на CLK - читаете SDA. Таймер перезапускаете на ожидание 1-0 на SCL..... и т.д. Т.о. весь протокол реализуете.... Там, где слейв должен дать АСК, меняете направление порта и дает "0".
По приему Stop можно в RTOS выстовить флаг/евент из прерывания о полученных данных. Задача ожидает флаг/евент.... по флагу разблокируется и обработает данные.
Эмуляция ds1307 - тут что не понятно? Заводите структуру как Карта aдресов, что типа такой
Код
typedef union
{
struct
{
uint8_t sec;
uint8_t min;
uint8_t hour;
uint8_t week;
uint8_t day;
uint8_t mount;
uint8_t year;
uint8_t control;
uint8_t array[56];
}mem;
uint8_t data[64];
} ds1307Mem;
Цитата
packet#27 - так происходит запись (первый байт куда писать, остальные что писать)
* приходит от мастера к слейву старт условие,
* 7 бит адреса Addr,
* 1 бит команды WRITE,
* слейв передает ACK ( переводит порт SDA в OUT и выдает 0, затем опять переводит порт в in),
* мастер передает в слейв 1-ый байт,
* слейв выдает аск,
* мастер передает в слейв 2 байт,
* слейв выдает аск,
* мастер передает в слейв 3 байт,
* слейв выдает аск,
* мастер передает в слейв 4 байт,
* слейв выдает аск,
....
* мастер выдает стоп.
В прерывании при обнаружении STOP условия послать эвент в задачу о приеме n-байт, которые нужно записать по указателю &ds1307Mem.data[Addr]. Естественно проверяем выход Addr за пределю массива ds1307Mem.data[].
Обрабатываем ds1307Mem.mem.control, если вы эмулирете Output control.
Для кошерности запускаем ещё один таймер или же в задаче системного тика эмулируем счет времени и меняем по мере изменения времени данные в ds1307Mem. как-то так.