|
Информационный портал технической поддержки Центра проектирования интегральных микросхем |
GPIO (General Purpose Input/Output, вход/выход общего назначения) - тип выводов, которые не имеют конкретной фиксированной функции. Функция вывода GPIO может быть настроена и контролироваться программным обеспечением.
Порты ввода-вывода общего назначения могут выполнять следующие функции:
Работать как программно управляемый вход (чтение логических уровней внешнего напряжения) или выход (формирование высокого или низкого логического уровня).
Количество портов GPIO (A, B, C и так далее), как и распределение по ним дополнительных функций, различается в зависимости от микроконтроллера. Точную информацию о количестве портов и распределении функций необходимо смотреть в спецификации микроконтроллера (в разделе "Описание выводов").
Работа порта подробно рассмотрена в статье "[i] Схемотехника портов GPIO".
Для настройки выводов GPIO рекомендуется использовать библиотеку SPL, в которой реализованы все необходимые для этого функции. В драйвере GPIO в библиотеке SPL настройка и управление портами реализованы через именованные поля, структуры и значения. Каждый параметр настройки имеет отдельное поле в структуре, обычно с перечислимым типом и кратким описанием в комментариях. Кроме того, одна и та же функция SPL обеспечивает идентичное поведение для всех поддерживаемых данной библиотекой микроконтроллеров (что применимо, например, в SPL MDR32Fx(QI) для микросхем семейств К1986ВЕ1x, К1986ВЕ9x, микросхемы К1901ВЦ1x, и в SPL MDR32VF0xI для микросхем К1986ВК025, MDR1206(A)FI). То есть, хотя адреса регистров и их структура могут отличаться, вызов функции с одинаковыми аргументами приведет к одному и тому же результату. Таким образом, достигается единообразие программного интерфейса при различиях в аппаратной реализации.
Далее настройка порта с помощью SPL рассмотрена на примере вывода 7 порта D (обозначение PD7). Этот вывод используется в программе "[i] Проект "Hello, World" для МК К1986ВЕ92QI (К1986ВЕ92FI, К1986ВЕ92F1I, К1986ВЕ94GI) и К1986ВЕ1QI (К1986ВЕ1FI, К1986ВЕ1GI)".
Если по каким-то причинам использовать SPL невозможно (например, программа пишется целиком на ассемблере), функции SPL для работы с портами все равно можно использовать в качестве справочной информации о порядке настройки регистров портов.
Порядок настройки порта включает в себя следующие этапы:
Первым действием перед инициализацией портов GPIO является включение тактирования (включение частоты PCLK) для конкретного порта. Гейтированная (программно включаемая) частота PCLK используется для тактирования регистров периферийных блоков, поэтому без неё чтение и запись регистров порта невозможны (по умолчанию PCLK для всех портов отключена).
RST_CLK_PCLKcmd (RST_CLK_PCLK_PORTD, ENABLE);
Фрагмент кода 1. Включение частоты PCLK для порта D.
Поскольку выводы портов в SPL настраиваются с помощью структуры, её необходимо объявить:
PORT_InitTypeDef GPIOInitStruct;
Фрагмент кода 2. Объявление структуры, содержащей параметры настройки порта.
При объявлении поля структуры не инициализированы и содержат произвольные данные из ОЗУ. Применение неинициализированных структур может привести к выходу изделия из строя (например, настройка вывода как цифрового выхода при наличии внешнего напряжения и отсутствии токоограничивающих резисторов может вызвать короткое замыкание). Поэтому все поля нужно инициализировать вручную или с помощью функции, задающей значения по умолчанию (соответствующие состоянию после сброса).
PORT_StructInit(&GPIOInitStruct);
Фрагмент кода 3. Инициализация структуры значениями по умолчанию.
В Фрагменте кода 4 приведено тело функции PORT_StructInit() из библиотеки SPL MDR32FxQI (код может отличаться между версиями). Её поля практически соответствуют регистрам периферийного блока, что подробно разобрано в статье "[i] Схемотехника портов GPIO". В SPL для других микроконтроллеров поля и их названия могут отличаться. Соответствие полей регистрам можно узнать, открыв заголовочный файл драйвера PORT и найдя там структуру PORT_InitTypeDef — обычно там есть описание каждого поля.
void PORT_StructInit(PORT_InitTypeDef* PORT_InitStruct)
{
/* Reset PORT initialization structure parameters values */
PORT_InitStruct->PORT_Pin = PORT_Pin_All;
PORT_InitStruct->PORT_OE = PORT_OE_IN;
PORT_InitStruct->PORT_PULL_UP = PORT_PULL_UP_OFF;
PORT_InitStruct->PORT_PULL_DOWN = PORT_PULL_DOWN_OFF;
PORT_InitStruct->PORT_PD_SHM = PORT_PD_SHM_OFF;
PORT_InitStruct->PORT_PD = PORT_PD_DRIVER;
PORT_InitStruct->PORT_GFEN = PORT_GFEN_OFF;
PORT_InitStruct->PORT_FUNC = PORT_FUNC_PORT;
PORT_InitStruct->PORT_SPEED = PORT_OUTPUT_OFF;
PORT_InitStruct->PORT_MODE = PORT_MODE_ANALOG;
}
Фрагмент кода 4. Тело функции PORT_StructInit() из библиотеки SPL MDR32FxQI
Заполнение выбранных полей в основной пользовательской программе аналогично показанному в функции.
Некоторые пояснения об использовании структуры:
Перед применением новых настроек иногда требуется вернуть все выводы порта в состояние, соответствующее сбросу (например, при перезапуске программы без аппаратного сброса). Деинициализация гарантирует, что все выводы порта работают как аналоговые входы (состояние по умолчанию).
PORT_DeInit(MDR_PORTD);
Фрагмент кода 5. Деинициализация выводов порта D.
У некоторых микросхем, например, у К1986ВЕ8Т и К1986ВК01 регистры порта по умолчанию защищены от записи. Поэтому для разблокировки записи предварительно нужно записать значение ключа в регистр KEY.
После включения тактирования и инициализации структуры можно применить настройки к порту:
PORT_Init(MDR_PORTD, &GPIOInitStruct);
Фрагмент кода 6. Применение настроек порта D.
В драйвере PORT, в частности в функции PORT_Init, реализована защита от изменения настроек выводов GPIO, совмещенных с отладочным интерфейсом JTAG. Это применимо, например, для микросхем семейства К1986ВЕ9x и микросхем MDR1206(A)FI, но не применимо для микросхем семейства К1986ВЕ1x, где выводы отладочного интерфейса не совмещены с выводами GPIO и защита не требуется. Этот функционал заключается в маскировании настроек для совмещенных с активным отладочным интерфейсом выводов. Поскольку отладочный интерфейс может быть неактивен или использоваться другой (например, в К1986ВЕ9x есть JTAG_A и JTAG_B), этот функционал можно включать или отключать. Например, в библиотеке SPL MDR32Fx(QI) в файле MDR32F9Qx_config.h/MDR32FxQI_config.h для этого объявлены определения USE_JTAG_A и USE_JTAG_B. Если определение объявлено, то активно маскирование выводов, совмещенных с функцией соответствующего отладочного интерфейса. По умолчанию объявлено определение USE_JTAG_B, а определение USE_JTAG_A закомментировано, что нужно учитывать при разработке ПО.
| Сайт: | https://support.milandr.ru |
| E-mail: | support@milandr.ru |
| Телефон: | +7 495 221-13-55 |