Регистры портов
Регистры портов разрешают низкоуровневые высокоскоростные манипуляции с выводами микроконтроллера. Используемые в Arduino чипы имеют три порта:
B (цифровые выводы от 8 до 13)
C (аналоговые входы)
D (цифровые выводы от 0 до 7)
Каждый порт контроллируется тремя регистрами, каждый из которых отвечает за определенное состояние. Регистр DDR определяет, какой вывод входной, а какой выходной (INPUT OUTPUT). Регистр PORT устанавливает вывод в соответствующее состояние HIGH или LOW, и регистр PIN читает состояние входного вывода.
Регистры DDR и PORT могут быть как прочитаны, так и записаны. Регистр PIN отвечает за состояние входных портов, поэтому может быть лишь прочитан.
PORTD отвечает за выводы 0 - 7
DDRD - Регистр направления порта D -чтение/запись
PORTD - Регистр данных порта D - чтение/запись
PIND - Регистр входных данных порта D - чтение/запись
PORTB отвечает за выводы 8 - 13 Два старших бита (6 и 7), отвечающие за выводы кварца незадействованы.
DDRB - Регистр направления порта B -чтение/запись
PORTB - Регистр данных порта B - чтение/запись
PINB - Регистр входных данных порта B - чтение/запись
PORTC отвечает за аналоговые выводы 0 - 5. Выводы 6 & 7 доступны только на Arduino Mini
DDRC - Регистр направления порта C -чтение/запись
PORTC - Регистр данных порта C - чтение/запись
PINC - Регистр входных данных порта C - чтение/запись
Каждый бит в этих регистрах отвечает за соответствующий вывод, т.е. младший бит у DDRB, PORTB, и PINB ссылается на вывод PB0 (цифровой вывод 8). Для полного соответствия регистровых битов выводам МК посмотрите назначение выводов вашего МК.
Примеры:
Следует помнить, что выводы 0 и 1 задействованы последовательным портом и работа с ними возможна только в том случае, если отладки и последовательный порт не требуются.
DDRD это регистр направления выводов для порта D (Arduino цифровые выводы 0-7). Биты этого регистра контролируют, как вывод регистра PORTD будет сконфигурирован - input или output, например:
DDRD = B11111110; // устанавливает выводы от 1 до 7 как выходные, вывод 0 - входной
//Ознакомьтесь с битовыми операциями
PORTB это регистр для установки выходных портов;
PORTD = B10101000; // устанавливает цифровые выводы 7,5,3 HIGH
Вы сможете видеть только 5В на выводе всегда, не вжно, использовали ли вы регистр DDRD или функцию pinMode().
PINB это регистр состояния входных выводов. Он может прочесть одновременно прочесть состояние всех выводов порта.
Конечно, с одной стороны данный мометод работы с портами имеет ряд мутных недостатков:
Программный код становится более сложным для поиска ошибок и менее понятным для остальных людей. Эти операции выполняются за считанные такты микропроцессора, однако вам может потребоваться несколько часов, чтобы найти, что рабоотает неправильно и исправить это!.
Код становится менее переносимым - сказывается привязка к конкретному микроконтроллеру. Используя функции digitalRead() и digitalWrite(), очень просто перенести код на другой микроконтроллер. Одним из способов решения могут стать макроопределения #ifdef, с помощью которых возможно написание универсального кода, который, в зависимости от МК, будет сам решать - как ему компилироваться.
При прямом доступе к портам можно совершить ошибки. Например,строка DDRD = B11111110; оставит вывод 0 как входной. Мы помним, что на нем у нас висит приемная линия последовательного порта. Вы представляете что может случиться если мы возьмем и сделаем его как выходной? Мы нарушим работу нашего порта.
Разумеется, чтобы работать с прямым доступом к портам надо разбираться, как это работает. Ведь прямой доступ имеет определенные преимущества:
Вы можете изменить состояние сразу всех портов одновременно, не прибегая ко всяким изощренным циклам и проч. Если вы посмотрите на исходники Arduino в lib/targets/arduino/wiring.c, вы увидите, что digitalRead() и digitalWrite() представляют собой кучу строк кода, которые буду скомпилированы в несколько команд процессора. Каждая команда процессора требует один такт тактового генератора 16Мгц. Прямой доступ в портам позволяет выполнить те же операии за много меньшее количество тактов, обеспечивая высокое быстродействие.
Иногда требуется одновременно изменить состояние каких-то выводов и любая задержка, обеспечиваемая функцией digitalWrite() может привести к каким-либо проблемам. Используя регистры прямого доступа вы избегаете этих проблем.
Если вас стесняют рамки имеющейся памяти программ, то можно использовать трюки, уменьшающие итоговый размер программы. Описание цикла, изменяющего состояние портов требует большого количества строк кода. Иногда подобные вещи критичны, и именно из-за них зависит - влезет программа в МК или нет.
Дата добавления: 2015-03-23; просмотров: 4273;