GPIO — порты ввода/вывода общего назначения — это группы выводов (пинов) микропроцессорного устройства, которые не имеют специального назначения, и могут быть использованы для связи с различными периферийными устройствами по усмотрению разработчика. Эти порты имеют специальный программный интерфейс, который позволяет управлять их состояниями и конфигурацией. Собственно, интерфейс GPIO позволяет выполнять две функции — либо считывать состояние выводов, либо, наоборот, устанавливать. Благодаря этим двум возможностям, GPIO могут быть использованы:

  1. Для включения/выключения различных устройств, как внутренних, так и внешних (относительно использующей МК конструкции), — микросхем, светодиодов, осветительных, нагревательных приборов, насосов, вентиляторов и тому подобного.
  2. Управления мощностью различных устройств — яркостью осветительных приборов, скоростью вращения двигателей, температурой электронагревателей и т.д. Делается это через ШИМ.
  3. Считывания состояний электрических линий — отслеживания изменения логических уровней, нажатия кнопок, срабатывания защит, датчиков, отсутствия/наличия напряжения и т.д.
  4. Организации коммуникационных протоколов связи с внешними устройствами — как программной реализации стандартных протоколов, таких как I2C, SPI, 1WIRE и так далее, аппаратная реализация которых может отсутствовать, либо недостаточно присутствовать в конкретном МК (понадобился, например, дополнительный интерфейс, того же I2C) , так и для реализации протоколов собственной разработки.

Помимо этого пины GPIO могут быть сконфигурированы для связи встроенной периферии МК с внешними компонентами. Подобный режим работы составляет альтернативу классической работе пинов GPIO, когда мы сами программно считываем/устанавливаем их состояния, и функции, которые пин может выполнять при конфигурации такого режима называются альтернативными функциями.

МК серии STM32F407V имеют 82 линии ввода/вывода, объединённые в 6 портов. Пять портов содержат по 16 линий и один порт имеет только две линии. На плате STM32F4DISCOVERY 30 линий уже занято — как для связи с установленной на плате демонстрационной периферией, так и для служебных целей, включая прошивку и отладку. Причём, занято так, что не остаётся ни одного полностью свободного порта из 16 линий. Какие-то из задействованных линий можно будет использовать и для других целей, какие-то, при желании и необходимости отпаять, другие же, лучше не трогать. За решением вопроса об использовании пинов GPIO обращаться к упомянутому ранее документу — UM1472: Discovery kit with STM32F407VG MCU.

Порты GPIO обозначаются латинскими буквами. Пять портов МК серии STM32F407V (далее, просто МК) по 16 линий — A, B, C, D, E, и один порт из 2-х линий — H. Выводы портов обозначаются буквой порта, которой предшествует буква P — порт, и за которой следует цифра, обозначающая номер линии в порту. PA0 — первая линия порта A. PB15 — шестнадцатая линия порта B.

Электрические характеристики

Структурную электрическую схему вывода GPIO можно увидеть на рис. 25 параграфа 8.3 СР(Справочное Руководство, оно же Reference Manual RM0090, параграф 8.3), а так же внизу этого абзаца. Главное отличие, которым один вывод может отличаться от другого это его терпимость (толерантность) к входному напряжению 5 В (5 V tolerant). Эта особенность может проявляться как при работе выводов в режиме входа, дающая возможность подавать на вход МК выход пятивольтовой логики, так и в режиме выхода, при присоединении подтягивающих резисторов к линии питания, с напряжением выше напряжения питания МК, о чём речь пойдёт ниже. Узнать о том, какие выводы 5 В толерантны, можно из таблицы 7 раздела 3 датащита (ДШ ds8626). В столбце I/O structure толерантные к 5 В выводы помечены как FT — five-volt tolerant. Вот ещё страница хорошим рисунком STM32F4DISCOVERY, по которому можно быстро получить информацию о выводах платы.

gpio_bit_structure

И толерантные, и не толерантные выводы имеют по два защитных диода, один соединяется в обратном подключении — анодом — к нулю, второй, для 5 В не толерантных — катодом — к положительной линии питания VDD, для толерантных же, к положительной линии специально вырабатываемого встроенным преобразователем повышенному напряжению VDD_FT. Если напряжение на выводе опускается ниже нуля, или повышается выше напряжения на катоде диода, подсоединённого к положительной линии напряжения, то один из диодов открывается, и через него начинает идти ток, защищая тем расположенные далее элементы. Диоды маломощные, рассчитаны на кратковременные превышения, например, в результате различных наводок, для работы в качестве стабилизаторов напряжения совсем не предназначены, и подавать на выводы напряжение, на которое они не рассчитаны, например, 5 В на не толерантный к 5 В вывод, не стоит.

Максимальный допустимый ток выводов в режиме вывода 25 mA. Но это максимально допустимый. В параграфе 5.3.16 ДШ Output Driving Current сказано, что выходы общего назначения могут принимать/получать ток до 8 мА, и до 20 мА при чередовании высокого/низкого уровня. Кроме выводов PC13, PC14, PC15, которые могут принимать/получать до 3 мА, и для них разрешена максимальная частота тактирования 2 МГц (см. ниже) и максимальная ёмкостная нагрузка 30 pF. Типовой ток маломощного светодиода — 10 — 20 мА, для индикации может хватить и меньше, есть и светодиоды рассчитаные на работу при ещё более слабом токе, от 1 мА. Значить, подключать светодиоды через токоограничительные резистор к выводам МК, без дополнительных транзисторов и драйверов мощности, можно, но нужно рассчитывать, какую нагрузку для вывода они создадут, будут ли гореть постоянно или мигать. Так же следует учитывать, что максимальный ток на линиях питания не должен превышать 240 mA. Подробнее почитать об электрических характеристиках МК можно в разделе 5 ДШ. Ещё одна информативная страница, на которой собрана в таблицу информация по выводам МК, включая электрические характеристики, а также информация по плате STM32F4DISCOVERY.

Управление тактированием

Связь портов GPIO с ядром микроконтроллера осуществляется через одну из внутренних шин AHB — Advanced High-performance Bus — Развитая высокопроизводительная шина — AHB1. Через неё ядро МК может управлять и обмениваться информацией с подключёнными к нему периферийными устройствами (с точки зрения ядра — GPIO — периферийные устройства). После старта порты GPIO находятся в неактивном состоянии. Чтобы они активировались — чтобы можно было устанавливать и снимать на них значения, на соответствующий порт должно быть подано тактирование, то есть, на его синхронизирующие линии должны начать поступать импульсы, в такт которым будут осуществляться требуемые операции.

Для управления тактированием портов GPIO существует три регистра, относящиеся к группе регистров RCC — Reset and Clock Control — Контроля сброса и тактирования.

RCC_AHB1RSTR

RCC AHB1 peripheral reset register (RCC_AHB1RSTR) — регистр сброса периферии, каждый бит которого отвечает за отдельное периферийное устройство. Помимо портов GPIO, в этом регистре содержатся и биты других устройств, подробнее, каких именно, можно прочитать в СР 6.3.5. Запись 1 в соответствующие биты сбрасывает тактирование периферийного устройства к настройкам по умолчанию. То есть, так как тактирование GPIO по умолчанию отключено, запись 1 в бит соответствующего порта будет приводить к прекращению его тактирования и отключению.

RCC_AHB1ENR

RCC AHB1 peripheral clock enable register (RCC_AHB1ENR) — (СР 6.3.10) — регистр разрешения тактирования периферии — каждый его бит отвечает за разрешение тактирования соответствующего периферийного устройства. При его установке (записи 1) тактирование соответствующего периферийного устройства разрешается, сбросе (записи 0) — запрещается.

RCC_AHB1LPENR

RCC AHB1 peripheral clock enable in low power mode register (RCC_AHB1LPENR) — (СР 6.3.15) — регистр разрешения тактирования периферии в режиме пониженного энергопотребления. МК STM32F407 имеют три режима пониженного энергопотребления. Режимы описаны в СР 5.3. По русски о них пожно прочитать здесь. Биты регистра RCC_AHB1LPENR определяют, будет ли соответствующее периферийное устройство тактироваться в самом неглубоком из режимов пониженного энергопотребления, режиме Sleep.

Если программирование связанное с установкой значений регистра RCC_AHB1LPENR может пригодится только в случаях, когда надо обеспечить работу устройства в режиме пониженного энергопотребления, регистра RCC_AHB1RSTR может и вообще не пригодится никогда, то без установки бит регистра RCC_AHB1ENR работа ни с портами GPIO, ни с другой периферией, подключённой к AHB1, будет невозможна. Однако, при программировании на Си, непосредственно с этим регистром, или с другими регистрами, дел можно и не иметь, так как функции библиотеки STM32F4 DSP and standard peripherals library, от STMicroelectronics, реализующей стандарт CMSIS, компоненты которой применяются при создании проектов в CoIDE, могут выполнять подобную работу без привязки к конкретным регистрам и их битам, нужно лишь знать, что мы хотим сделать, и соответствующие функции, структуры, поля, предопределённые константы, при помощи которых мы можем сделать это. Вот как, например, выглядит строка кода для разрешения тактирования порта A:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

Возможности конфигурации

Через регистры группы RCC_AHB1 может быть разрешено/запрещено тактирование, и, тем самым, работа определённого порта GPIO. Особенности же работы самого порта, а так же установка/чтение данных могут быть осуществлены через регистры, связанные непосредственно с портом. Параграф 8.1 СР поясняет, что каждый порт GPIO имеет 4 конфигурационных регистра — GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, GPIOx_PUPDR, где x — буква порта, два регистра данных — GPIOx_IDR, GPIOx_ODR, регистр сброса/установки бит — GPIOx_BSRR, регистр блокировки — GPIOx_LCKR, два регистра выбора альтернативных функций — GPIOx_AFRH, GPIOx_AFRL.

А параграф 8.2 СР описывает, какие именно свойства могут управляться перечисленными выше регистрами:

  • Контроль до 16 линий ввода/вывода. Мы можем считывать/устанавливать состояния, а так же настраивать режим работы для каждой линии ввода/вывода в отдельности.
  • Состояния выхода: двухтактный каскад (push-pull) или каскад с открытым стоком (open drain) + подтяжка к высокому или низкому уровню (pull-up/down). Двухтактный каскад представляет собой схему из двух транзисторов, соединённых так, что если мы установим линию GPIO в 1, то откроется транзистор, соединяющий выход с положительной линией питания МК, если 0, то с нулевой. Таким образом, выход двухтактного каскада всегда соединён с одной из линий питания. В каскаде с отрытым стоком используется только один транзистор. При сбросе линии в 0, он соединяет выход с нулём питания. При установке же в 1 выход как бы подвисает в воздухе, представляя для подключённых к нему устройств просто разрыв цепи. Чтобы обеспечить на нём наличие устойчивого логического уровня, иначе он может устанавливаться в результате различных сетевых наводок, его присоединяют, через резистор, к одной из линий питания, что и называется подтяжкой. Если к положительному напряжению — подтяжка вверх, к нулю — вниз. Эта схема выхода даёт две возможности:
    1. Использовать для уровня логической 1 напряжение более высокого уровня, чем напряжение питания МК. Можно соединить вывод МК, питающегося от 3.3 В через резистор к положительной линии питания 5 В. При этом, когда выход установлен в 1 и транзистор каскада с открытым коллектором закрыт, на выходе будет 5 В. Когда же он будет сброшен в ноль, транзистор откроется и выход соединится с нулём цепи питания. Надо только следить, чтобы ток через открывшийся транзистор не превышал максимально допустимый, и вывод был толерантен к 5 вольтам. Если подключить подтяжку 5 В не толерантного вывода через резистор к 5 В, то диод откроется и ток пойдёт через него на положительную линию питания МК, при этом падая на выводе до величины равной напряжению питания МК + прямое падение напряжения на диоде.
    2. Использовать для организации линий связи с периферийными устройствами по типу Монтажного И. Данное решение позволяет соединять одной физической линией несколько устройств так, что логическая 1 на линии будет только в том случае, если выходы всех подключённых к ней устройств установлены в 1. Стоит любому из выходов перейти в 0, и 0 установится на всей линии.
  • Вывод данных из регистра выходных данных GPIOx_ODR или из другой периферии МК (использование альтернативных функций). Мы можем выводить данные, которые установили в регистре GPIOx_ODR, так и подключать GPIO вывод к другим периферийным устройствам МК — таймерам, модулям коммуникационных протоколов: USB, I2C, SPI, CAN и тд, что и определяет альтернативные функции работы вывода GPIO.
  • Выбор частоты тактирования отдельно для каждой линии ввода/вывода. Меньше частота тактирования, меньше наведение помех, меньше энергопотребление. Этот параметр может быть установлен для выводов, сконфигурированных на выход, не на вход. Он определяет скорость нарастания выходного напряжения — то, как быстро изменяется напряжение на выходе после изменения соответствующих бит регистра выходных данных. От этого параметра зависит максимальная частота, которую можно получить на выходе и длительность фронтов.
  • Состояния входа: высокоимпедансный вход (Z-состояние), вход с подтяжкой к высокому или низкому уровню, аналоговый вход. Высокоимпедансный вход — Input floating — ведёт себя по отношению к подключённой к выводу цепи так, будто он от неё отключён, не оказывая на неё влияния. Или же внутри МК к входу может быть подключён резистор, соединяющий его с уровнем логической 1 (подтяжка вверх), или нуля (подтяжка вниз).
  • Входные данные подаются в регистр входных данных или в регистры периферии МК (использование альтернативных функций). То есть, данные с входа GPIO могут изменять состояние регистра входных данных порта GPIO, либо они могут служить источником данных для встроенной периферии МК.
  • Регистр сброса установки бит GPIOx_BSRR для битового доступа к GPIOx_ODR. Регистр GPIOx_BSRR позволяет осуществлять побитные атомарные операции. То есть, если классическая схема изменения состояния выходных данных выглядит как чтение-изменение-запись, причём, читаются, изменяются и записываются данные для всего регистра целиком, и процесс этот может быть прерван прерыванием, в обработчике которого состояние порта может быть изменено, а после операция будет продолжена, ничего не зная о том, что выходные данные порта уже изменились. И тут возможны странные состояния, когда мы получим на порте не то, что ожидали. GPIOx_BSRR же позволяет устанавливать отдельные биты GPIOx_ODR не затрагивая остальные, обходясь без предварительного чтения данных порта, и осуществлять эту операцию за один такт ядра МК, исключая возможность того, что эта операция будет прервана.
  • Механизм блокировки, поддерживающий замораживание конфигурации порта, через регистр блокировки GPIOx_LCKR. Для безопасности работы управляемого МК оборудования, через регистр GPIOx_LCKR конфигурационные регистры порта GPIO могут быть заблокированы. Регистр GPIOx_LCKR имеет защиту от случайной записи, чтобы изменения блокировки конфигурационных регистров порта вступили в силу на бит регистра GPIOx_LCKR LCKK должна быть подана специальная последовательность.
  • Аналоговые функции. Выводы GPIO могут служить входами аналого-цифрового (АЦП, Analog-to-digital converter, ADC), и выходами цифро-аналогового (ЦАП, digital-to-analog converter, DAC) преобразователей.
  • Альтернативные функции ввода/вывода выбираемые через регистры GPIOx_AFRH, GPIOx_AFRL. До 16 альтернативных функций на линию ввода/вывода. То, о чём уже говорилось — возможность использования выводов GPIO для подсоединения внешних устройств к встроенной периферии МК.
  • Способность изменять состояние каждые два такта. То есть максимальная скорость переключения выводов GPIO равна половине частоты тактирования ядра.
  • Мультиплексирование выводов, позволяющее использовать каждую линию как линию GPIO или как вывод нескольких альтернативных функций периферии.

Более подробные описания перечисленных выше функциональностей можно прочитать в разделе 8.3 СР, а здесь ниже дано краткое описание регистров GPIO.

Регистры

GPIOx_MODER

GPIO port mode register (GPIOx_MODER) — (СР 8.4.1) — регистр, поочерёдно идущие пары бит которого конфигурируют режим направления работы каждой линии порта, определяя один из четырёх возможных режимов:

  • 00 — Ввод.
  • 01 — Выход общего назначения.
  • 10 — Режим альтернативной функции.
  • 11 — Аналоговый режим.

GPIOx_OTYPER

GPIO port output type register (GPIOx_OTYPER) — (СР 8.4.2) — регистр, младшие 16 бит которого поочерёдно определяют тип выхода для каждой линии порта:

  • 0 — Двухтактный каскад.
  • 1 — Каскад с открытым стоком.

GPIOx_OSPEEDR

GPIO port output speed register (GPIOx_OSPEEDR) — (СР 8.4.3) — регистр скорости нарастания выходного напряжения, от значения поочерёдно расположенных пар бит которого зависит, какую максимальную частоту напряжения может развить выход и ширина фронтов. Конкретные значения зависят от установленного значения в GPIOx_OSPEEDR, напряжения питания МК, ёмкостной нагрузки вывода порта, конкретные зависимости можно узнать из таблицы 50 параграфа 5.3.16 ДШ.

  • 00 — Низкая скорость (2 MHz).
  • 01 — Средняя скорость (25 MHz).
  • 10 — Высокая скорость (50 MHz).
  • 11 — Очень высокая скорость (100 MHz).

GPIOx_PUPDR

GPIO port pull-up/pull-down register (GPIOx_PUPDR) — (СР 8.4.4) — регистр управления подтяжкой. Значения определяются парами бит.

  • 00 — Подтяжка отсутствует.
  • 01 — Подтяжка вверх.
  • 10 — Подтяжка вниз.
  • 11 — Зарезервировано.

GPIOx_IDR

GPIO port input data register (GPIOx_IDR) — (СР 8.4.5) — порт входных данных, содержащий данные. Младшие 16 бит регистра содержат входные данные порта. Регистр доступен только на чтение и может быть прочитано только целое слово.

GPIOx_ODR

GPIO port output data register (GPIOx_ODR) — (СР 8.4.6) — регистр выходных данных. Младшие 16 бит регистра содержат значения, которые будут выводится каждой линией порта. Доступен на чтение и запись. Запись изменяет логические урыводах порта.

GPIOx_BSRR

GPIO port bit set/reset register (GPIOx_BSRR) — (СР 8.4.7) — регистр установки/сброса бит регистра GPIOx_ODR. При записи 1 в старшие 16 бит порта происходит сброс соответствующего бита в регистре GPIOx_ODR. При записи 1 в младшие 16 бит порта происходит установка соответствующего бита GPIOx_ODR. При записи 0 изменения бит GPIOx_ODR не происходит. При одновременной установки в 1 бита, соответствующему одному и тому же биту GPIOx_ODR в старшей и младшей частях GPIOx_BSRR, приоритет имеет младшая часть, то есть, установка. Биты GPIOx_BSRR доступны только на запись в режиме слова, полуслова и байта. При чтении возвращает 0.

GPIOx_LCKR

GPIO port configuration lock register (GPIOx_LCKR) — (СР 8.4.8) — регистр блокировки конфигурации порта. Запись 1 в любую из 16 бит — LCKx — младшей части регистра служит для блокировки конфигурации соответствующей линии порта. Бит 16 — LCKK — служит для ввода ключевой последовательности, которая ведёт к применению устанавливаемого значения. Доступ к регистру осуществляется только целым словом (машинное слово — 32 бит). Установка блокировки замораживает состояние соответствующих бит в портах: GPIOx_MODER, GPIOx_OTYPER,
GPIOx_OSPEEDR, GPIOx_PUPDR, GPIOx_AFRL и GPIOx_AFRH.

Ключевая последовательность:

WR LCKR[16] = ‘1’ + LCKR[15:0]
WR LCKR[16] = ‘0’ + LCKR[15:0]
WR LCKR[16] = ‘1’ + LCKR[15:0]
RD LCKR

Если RD LCKR[16] = 1 — значить блокировка активна.

GPIOx_AFRL

GPIO alternate function low register (GPIOx_AFRL) — (СР 8.4.9) — младший регистр альтернативных функций. Идущие последовательно тетрады бит этого регистра определяют выбор альтернативной функции для младших восьми линий соответствующего вывода порта.

  • 0000 — AF0 — Альтернативная функция 0
  • 0001 — AF1
  • 0010 — AF2
  • 0011 — AF3
  • 0100 — AF4
  • 0101 — AF5
  • 0110 — AF6
  • 0111 — AF7
  • 1000 — AF8
  • 1001 — AF9
  • 1010 — AF10
  • 1011 — AF11
  • 1100 — AF12
  • 1101 — AF13
  • 1110 — AF14
  • 1111 — AF15

Узнать, какие именно функции скрываются за обозначениями AF0-AF15 для конкретного вывода, можно из таблицы 9 раздела 3 ДШ.

GPIOx_AFRH

GPIO alternate function high register (GPIOx_AFRH) — (СР 8.4.10) — старший регистр альтернативных функций. Аналогичен GPIOx_AFRL, за исключением того, что его биты служат для конфигурации альтернативных функций старших 8 линий порта GPIO.

Если смотреть описание соответствующих регистров в СР, то видно, что там приводится значение — Reset values — состояние бит регистра после сброса. Не для всех портов эти состояния одинаковые. В разделе СР 8.4.11 приведена таблица 39 с собранными в ней значениями Reset values регистров GPIO. Так же из таблицы 9 раздела 3 ДШ видно, что некоторые пины после сброса настроены как альтернативные функции, например, пины PA13, PA14, PA15 — как выводы интерфейса тестирования и отладки JTAG.

Неиспользуемые выводы

В завершении заметки о том, что делать с неиспользуемыми выводами. По умолчанию большинство выводом после сброса сконфигурированы как высокоимпедансные дискретные входы, но такое состояние не является оптимальным, так как наличие высокого сопротивления создаёт и возможность появления на выводе высокого потенциала в результате статических и электромагнитных наводок, хотя у нас и стоят на входе защитные диоды, но диоды эти маломощные. И колебание уровня в результате помех на высокоимпедансном входе может приводить к некоторому увеличению энергопотребления, за счёт вызываемых ими переключений стоящего на входе триггера Шмитта.

Поискав, обнаружул, что существуют разные мнения об их последующей конфигурации. В примере работы с GPIO к STM32 Standard Peripheral Library для МК серии stm32f10x до версии V3.4.0 включительно, можно увидеть код, в котором тактирование всех портов сперва разрешается, потом их выводы инициализируются как аналоговые входы, затем тактирование для неиспользуемых портов запрещается. Этим действием триггер Шмитта отключается от входной цепи. Но примеры из версии библиотеки 3.5.0 для этой же серии МК, и последних версий для других МК, включая и STM32F4, которые можно в настоящий момент найти по указанной выше ссылке на библиотеку, начальной инициализации пинов всех портов не содержат. Не знаю причин, по которым это сделано, возможно, либо при составлении примеров решили не загромождать код лишними подробностями, либо сочли, что подобная практика устарела, и современные МК в подобных настройках не нуждаются.

Чтобы справиться со всплесками напряжения от наводок, вполне может хватить и защитных диодов. Но проблема увеличения энергопотребления остаётся. Насколько она существенна? Ответить сейчас не могу, возможно, кто-то и проводил подобные измерения, ради интереса, думаю, провести их со временем самому. Как вариант, для решения этой проблемы, настроенные как входы выводы можно подтянуть к нулю или единице. По некоторым рекомендациям, как оптимальное решение, неиспользуемые выводы советуют подтягивать к нулю используя внешние резисторы, порядка 10 кОм, но понятно, что из-за дизайна такое решение не оптимально, и следовать ему, возможно, стоит только при проектировании устройств, работающих в условиях жёстких электромагнитных наводок. Настраивать же неиспользуемые выводы на выход, как это иногда рекомендуется, особенно во время изучения, лучше не стоит, так как это может привести к нежелательным последствиям из-за случайных замыканий.

Добавить комментарий