эффективный вывод многобитных значений. Для этого нам нужна сущность
объединяющая группу линий В/В – своеобразный список линий В/В.
Поскольку и порты и отдельные линии у нас представлены различными
классами, то логично реализовывать список линий с помощью шаблонов. Но
здесь есть одна проблема: список линий может содержать различное число
линий, а шаблоны в Си++ имеют фиксированное число параметров (а
стандарте Cxx03, в следующей версии появятся Variadic templates). Нам
поможет библиотека Loki, написанная Андреем Александреску. В ней
реализовано множество шаблонных алгоритмов для манипуляций со
списками типов произвольной длинны. Это нам подойдёт – списки типов
превращаются в списки линий ввода-вывода. Что, собственно, такое списки
типов лучше всего почитать у их автора Андрея Александреску в книге
Современное проектирование на С++. Очень рекомендую прочитать, хотя-бы
мельком, главу «Списки типов» в этой книге. Без этого будет мало понятно,
что происходит дальше.
Не во всех МК предусмотрены команду для манипуляций с отдельными
битами в портах В/В. В семействе MegaAVR тоже есть порты для которых
недоступны битовые операции. Поэтому чтобы сделать операции с портами
максимально эффективными нам нужно отказаться от побитового вывода –
одно чтение, модификация значения и запись.
То есть нужно записать N битов из входного значения в N битов произвольно
расположенных в нескольких портах В/В. Или по другому говоря,
сгруппировать записываемые биты по портам и вывести их за раз.
В упрощенном виде алгоритм записи значения в произвольный список линий
В/В будет выглядеть так:
1. Определить список портов к которых подключены линии из списка.
2. Для каждого порта:
•
Определить список линий к нему подключенный.
•
По этому списку сгенерировать битовую маску для битов, которые не
нужно менять.
•
Спроецировать биты из входного значения на соответствующие им
места в регистре порта во временный буфер.
•
Наложить битовую маску на регистр порта (т.е. очистить в нем те биту,
куда будем записывать новое значение)
•
Записать значение из временного буфера в регистр порта.
Выглядит всё это очень сложно. Когда мы пишем реализацию виртуальных
портов на Си, то все эти операции проделываем вручную, а сейчас наша
задача заставить компилятор выполнять эту работу. Для этого в нашем
распоряжении есть списки типов и техника шаблонного