Заметим, что сигналы SCL совершенно необязательно должны представлять собой равномерный меандр со скважностью 2 — период их следования в принципе ничем не ограничен, кроме «терпения» приемника, который, естественно, ждет сигнала какое-то ограниченное время (иначе при нарушении протокола программа может зависнуть). Более подробно мы разбирать протокол не будем, так как вы легко можете найти его изложение в описании любого устройства, которое этот протокол поддерживает (в том числе и в описаниях AVR, изложенных по-русски в книге [2]).
Как видим, организовать обмен по протоколу I 2С непросто, но это есть цена за универсальность и простоту электрической схемы. Большинство современных устройств с интерфейсом I 2С могут работать с тактовой частотой до 400 кГц, но в силу не слишком высокой помехоустойчивости такой линии максимальные частоты лучше использовать только тогда, когда микросхемы установлены на одной плате недалеко друг от друга. При соединении проводами (например, МК с каким-нибудь датчиком) лучше ограничиться частотами до 100 кГц, а при длинных линиях связи (провода в полметра длиной и более) частоту обмена стоит снижать до 10–30 кГц.
Организовать обмен по интерфейсу I 2С можно различными способами, и еще недавно это была исключительно программная эмуляция протокола. AVR семейства Mega (и только этого семейства) имеют I 2С (TWI), реализованный аппаратно. Реализация эта, впрочем, не очень удобна, потому что не избавляет от необходимости «ручного» отслеживания различных этапов обработки сигнала, в результате чего программа получается не менее громоздкой, чем при программной эмуляции. Еще один способ — использование прерывания, которое связано с TWI, тогда можно разгрузить контроллер от многочисленных задержек (передача одного байта длится примерно 0,1 мс). В дальнейшем, чтобы не распыляться, мы будем применять более универсальную программную эмуляцию, которая имеет и некоторые преимущества: позволяет произвольно выбирать выводы для соединения (какие удобно, а не какие заданы аппаратной реализацией) и годится для абсолютно всех МК AVR, а не только для тех Mega, что имеют встроенный TWI. Единственное, чего мы лишимся — возможности «будить» контроллер, находящийся в «спящем» режиме (см. главу 17 ) обращением к нему через TWI, но нам это будет не нужно, т. к. контроллер всегда у нас находится в режиме ведущего. В фирменных Application Notes есть изложение процедуры программной эмуляции, но, как водится, с ошибкой в реализации.
Программная эмуляция протокола I 2С
Наша задача будет формулироваться так: есть контроллер, и есть некое (одно или более) внешнее устройство. Нам надо прочесть/записать данные. Контроллер тут всегда будет выступать, как Master, а устройство — как Slave. Для того чтобы программно эмулировать протокол I 2С, нам тогда придется сначала решить вопрос о том, как формировать тактирующую последовательность на линии SCL.
В принципе это можно сделать с помощью таймера, но на самом деле это неудобно: и таймеры обычно заняты более полезными делами, и нет туг у нас каких-то жестких требований ни к стабильности, ни к форме сигнала. Потому мы воспользуется древним, как сами микропроцессоры, способом формирования временной задержки с помощью пустого цикла. Так как время выполнения всех команд точно известно, то этот способ для формирования импульса определенной длительности ничуть не хуже любого другого, а когда в МК еще не было никаких таймеров, он вообще был единственным доступным способом для таких целей.
Для формирования импульса воспользуемся счетчиком cnt(пусть это будет регистр из числа старших — от r16до r31). Пустой цикл, повторенный NNраз, тогда запишется так:
ldi cnt,NN
cyk_delay: dec cnt
brne cyk_delay
Посчитаем, чему должно равняться число NN. Пусть мы хотим обеспечить скорость передачи для I 2С около 100 кГц, тогда длительность одного импульса (полпериода тактовой частоты) должна равняться примерно 5 мкс. Сам цикл занимает 3 такта (команда dec1 такт + команда brneс переходом — 2 такта), т. е., например, при частоте кварцевого генератора 4 МГц он будет длиться 0,75 мкс. Итого, чтобы получить при этой частоте импульс в 5 мкс, нам надо повторить цикл 6–7 раз. Точно подогнать частоту не удастся, но нам это, как мы говорили, и не требуется: опыт показывает, что при ошибке даже в два-три раза работоспособность I 2С практически не нарушается.
Чтобы не отводить отдельный регистр только для такой частной задачи, как счет циклов в задержке, стоит дополнить цикл процедурами сохранения в стеке значения счетчика, тогда этот регистр можно безопасно использовать где-то еще. И вся процедура будет выглядеть так:
Читать дальше
Конец ознакомительного отрывка
Купить книгу