Таки да, ответ вам должен быть. А то я попутал по кучке ответов.
а код либы - да, по мотивам ДиХальта. Там половина копипасты, я там что то под себя вроде переписывал.. Заголовок, судя по всему, ДиХальтов. Может и всё его - 7 лет прошло, не помню.
Я тогда изучал АВРки и их ассемблер.
И большинство чужих либ изучал и переписывал под себя.
Добавлено after 42 minutes 58 seconds:
a1000, по обработке прерывания от i2c - у того же ДиХальта был развесистый такой алгоритм обработки прерывания в зависимости от статусного байта.
Для спортивного интересу - да, можно i2c обрабатывать прерыванием. но выигрыш от этого?
1 байт на 400 кГц передается за 8+1 тактов. Или за 2.5 мкс * 9 = 22,5 мкс.
За 22.5 мкс МК на частоте 8 МГц выполняет условно 180 команд. Это если не считать условных и безусловных переходов и двухсловных команд.
Из которых вы потратите, (если мне не изменяет память) по 4 такта на вход в прерывание и выход из него. Потом нужно сохранить SREG и какой то из регистров. Еще 3 такта. Еще сохранить ZL:ZH - это указатель для ваших сохранений данных из TWDR. Т.е. 5 тактов сохранения, 5 восстановления регистров.
Дальше реализация этапов чтения - у не думаю, что менее 20-30 тактов уйдет... Т.е. на обработку прерывания будет тратиться ну не менее 40-50 тактов. Из 180.
Т.е. при 8 МГц у вас между прерываниями будет 12-15 мкс.
Ради спортивного интереса - да, можно работать с прерыванием.
А так - я бы не заморачивался и сделал на ожиданиях. Обычно i2c-устройства - это не plug'n'play, а запаянные на плату конкретные устройства. И при исправности всех устройств обмен по шине не должен выдавать ошибки. Соответственно, цикл обработки упрощается.
В ожиданиях, если вдруг что, можно сделать не бесконечное ожидание, а конечный цикл, однобайтовый, от 0xFF до 0x00. И отдавать флаг ошибки, если цикл досчитал до 0. Ибо передача/прием байта занимают 180 или 360 тактов (8 или 16 МГц тактовой). а цикл ожидания будет длиться дольше.
Если уже параллельно процессу обмена нужно что то выполнять, то можно делить обмен по i2c на этапы - старт, отправка адреса записи, отправка стартового адреса, повстарт, отправка адреса чтения, чтение байта 1, чтение байта 2, ...., чтение байта 7, стоп.
И выполнять эти этапы раздельно, а между этапами параллельные операции.
Касательно 18B20 - я думаю, что при правильном подходе там обмен уложится байт в 200-300-400. Там же важно выдерживать только 3 тайминга - резет 480 мкс и чтение presence / чтение-запись бита - 15+45 мкс.
Опять же, если не не использовать UART, то проще всего эти задержки делать на тупых циклах.





