Микроконтроллеры семейства LPC оснащены одним или несколькими 32-разрядными портами ввода-вывода. Начиная в определённой модели, в состав микроконтроллеров заложен усовершенствованный набор регистров для быстрого управления портами общего назначения. В документации на конкретную модель их легко узнать по начальной букве "F” в имени регистра от англ. fast –быстрый, например: FIO0DIR, FIO0SET, FIO0CLR.
Для включения поддержки "быстрых регистров” необходимо установить нулевой бит регистра SCS:
#include <LPC23xx.H>
SCS |= 0x01; // Включение доступа к портам 0 и 1 через шину AHB.
Если этого не сделать, то обращаться к портам необходимо через обычный набор регистров IODIR0, IOSET0, IOCLR0 и т. д. , что обеспечивает поддержку старого программного обеспечения, написанного без использования регистров FGPIO:
#include <LPC23xx.H>
SCS &= ~0x01; // Доступ к портам 0 и 1 через шину APB.
Направление выводов порта.
Каждый из выводов портов общего назначения может быть настроен как вход или выход с помощью регистра FIOnDIR (здесь и далее n-номер порта). Для настройки вывода на выход соответствующий разряд регистра необходимо установить в единицу, на вход – в ноль (по умолчанию для всех портов):
#include <LPC23xx.H>
FIO1DIR|= (1<<26); // Вывод 26 порта 1 настроить на выход.
FIO1DIR&=~(1<<26); // Вывод 26 порта 1 настроить как вход.
Помимо 32-х разрядных регистров FIOnDIR, можно использовать четыре восьмиразрядных регистра для отдельных байтов порта - FIOnDIR0, FIOnDIR1, FIOnDIR2, FIOnDIR3, задающих направления для разрядов 0-7, 8-15, 16-23 и 24-31 соответственно. Или два шестнадцатиразрядных – FIOnDIRL и FIOnDIRU, определяющих направления выводов 0-15 и 16-31. При использовании указанных регистров настройка вывода 26 порта 1 будет выглядеть следующим образом:
FIO1DIR3 |= (1<<2); // Вывод 26 порта 1 настроить на выход (бит №2 в последнем байте порта).
FIO1DIRU |= (1<<10); // Вывод 26 порта 1 настроить на выход (бит №10 во второй половине порта).
Установка и сброс выводов порта.
Устанавливать и сбрасывать выводы портов можно при помощи специально предназначенных для этого регистров SET и CLR. Для установки нужного вывода порта в соответствующий разряд регистра FIOnSET необходимо записать единичный бит, для сброса вывода необходимо установить в единицу соответствующий бит в другом регистре - FIOnCLR:
FIO1SET = (1<<26); // Установить вывод 26 порта 1.
FIO1CLR = (1<<26); // Сбросить вывод 26 порта 1.
Очень удобная особенность регистров этого типа в том, что при записи в них сбрасываются или устанавливаются только те разряды, в которые записываются единичные биты. При этом запись нулевых битов в разряды регистров FIOnSET и FIO1CLR не изменяет состояние соответствующих выводов порта. Благодаря этому, вместо конструкции типа чтение-модификация-запись:
FIO1PIN = FIO1PIN | (1<<26);
используемой для защиты от изменения состояния других выводов порта, можно применить запись:
FIO1SET = (1<<26);
которая выполняется в три раза быстрее.
Также доступны четыре однобайтовых и два двухбайтовых регистра установки и сброса:
FIOnSET0, FIOnSET0, FIOnSET0, FIOnSET0 и FIOnSETL, FIOnSETU.
Запись и чтение порта.
Для записи данных в порт и чтения фактического состояния выводов порта предназначены 32-разрядные регистры FIOnPIN:
FIO1PIN=0xFFFFFFFF; // Записать единицы во все разряды порта.
FIO1PIN= FIO1PIN ^ (1<<26); // Изменить состояние вывода 26 на противоположное.
Регистры записи/чтения порта с одно- и двухбайтовой адресацией: FIOnPIN0, FIOnPIN1, FIOnPIN2, FIOnPIN3 и FIOnPINL, FIOnPINL.
Регистры защитных масок.
Ещё одна интересная особенность работы с портами микроконтроллеров LPC – возможность защитить конкретные выводы портов от изменений командами FIOnPIN, FIOnSET и FIOnCLR с помощью регистров защитных масок FIOnMASK.
Если один или несколько разрядов регистра FIOnMASK установить в единицу, то он будет защищён от изменений командами записи, установки и сброса. Это очень удобно для записи необходимых числовых значений в группу разрядов порта, без воздействия на окружающие выводы.
FIO1MASK=~((1<<4)| (1<<5)| (1<<6)| (1<<7)); // Разрешить старшую тетраду первого байта.
FIO1PIN = 0x0000 00A0; // Записать в тетраду число 0x0A.