24254

[i] GPIO - Настройка портов ввода-вывода

Дата последнего изменения: 25.12.2025 09:12:31

GPIO (General Purpose Input/Output, вход/выход общего назначения) - тип выводов, которые не имеют конкретной фиксированной функции. Функция вывода GPIO может быть настроена и контролироваться программным обеспечением.

Порты ввода-вывода общего назначения могут выполнять следующие функции:

  • Работать как программно управляемый вход (чтение логических уровней внешнего напряжения) или выход (формирование высокого или низкого логического уровня).

  • Выполнять цифровые функции различных интерфейсов, таких как UART, SPI и т.д.
  • Выполнять аналоговые функции, например, для работы с АЦП или ЦАП (при этом аналоговые функции выводов активны постоянно).

Количество портов 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 для работы с портами все равно можно использовать в качестве справочной информации о порядке настройки регистров портов.

Порядок настройки порта включает в себя следующие этапы:

  1. включение тактирования порта (если оно не было включено ранее);
  2. объявление структуры настройки порта и инициализация её требуемыми значениями;
  3. опционально - деинициализация всех выводов порта;
  4. инициализация порта на основе заданной в структуре конфигурации.

1. Включение тактирования порта

Первым действием перед инициализацией портов GPIO является включение тактирования (включение частоты PCLK) для конкретного порта. Гейтированная (программно включаемая) частота PCLK используется для тактирования регистров периферийных блоков, поэтому без неё чтение и запись регистров порта невозможны (по умолчанию PCLK для всех портов отключена).

RST_CLK_PCLKcmd (RST_CLK_PCLK_PORTD, ENABLE);

Фрагмент кода 1. Включение частоты PCLK для порта D.

2. Объявление и инициализация структуры

Поскольку выводы портов в 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_Pin, в отличие от остальных, является комбинацией (через побитовое ИЛИ) масок номеров выводов. Например, для настройки выводов 0 и 1 используется PORT_Pin = (PORT_Pin_0 | PORT_Pin_1).
  • При настройке вывода в аналоговый режим отдельная инициализация после деинициализации порта не требуется — выводы после деинициализации становятся аналоговыми входами (а аналоговая функция активна постоянно), но конкретный режим работы (например, вход или выход) определяется периферийным блоком, с которым связана эта аналоговая функция.

3. Деинициализация выводов порта

Перед применением новых настроек иногда требуется вернуть все выводы порта в состояние, соответствующее сбросу (например, при перезапуске программы без аппаратного сброса). Деинициализация гарантирует, что все выводы порта работают как аналоговые входы (состояние по умолчанию).

PORT_DeInit(MDR_PORTD);

Фрагмент кода 5. Деинициализация выводов порта D.

У некоторых микросхем, например, у К1986ВЕ8Т и К1986ВК01 регистры порта по умолчанию защищены от записи. Поэтому для разблокировки записи предварительно нужно записать значение ключа в регистр KEY.

4. Инициализация порта

После включения тактирования и инициализации структуры можно применить настройки к порту:

PORT_Init(MDR_PORTD, &GPIOInitStruct);

Фрагмент кода 6. Применение настроек порта D.

У некоторых микросхем, например, у К1986ВЕ8Т и К1986ВК01 регистры порта по умолчанию защищены от записи. Поэтому для разблокировки записи предварительно нужно записать значение ключа в регистр KEY.

В драйвере 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 закомментировано, что нужно учитывать при разработке ПО.


Сохранить статью в PDF

Программное обеспечение

Software pack для Keil MDK 5 + Standard Peripherals Library
Software pack для Keil MDK 5 + Standard Peripherals Library

Теги

Была ли статья полезной?