======GPIO - Настройка портов ввода-вывода====== GPIO - General Purpose Input Output это выводы микроконтроллера, которые можно настраивать под свои цели. Они могут использоваться просто как порты на вывод и вход, например логических "0" и "1". Могут иметь дополнительные, например аналоговые функции для работы с АЦП. Могут использоваться аппаратно для реализации различных интерфейсов взаимодействия, например UART, SPI и т.д. Количество портов в каждом процессоре разное, как и распределение по ним дополнительных функций. Информацию по данному вопросу необходимо смотреть в спецификации в разделе "Порты ввода вывода MDP_PORTx" Работа порта ближе к схемотехнике рассмотрена в [[doc:doclist:gpio_schm|"Схемотехника портов GPIO"]]. =====Управление портами на примере функций SPL.===== Функции SPL реализуют настройку и управление портами через именованные поля, структуры и значения. Каждый параметр настройки имеет свое отдельное поле в структуре, в большинстве своем имеет перечислимый тип значения этого поля и краткое описание в комментариях. Это очень удобно и позволяет избежать ошибок при работе. Кроме этого, одна и та же функция SPL реализует одинаковое поведение для всех поддерживаемых SPL процессоров. То есть поля в регистрах или сами регистры, их адреса могут отличаться, от процессора к процессору, но функция вызванная с одинаковым аргументом выполнит одинаковое действие. Таким образом реализуется стандартное поведение функций при различии реализации в железе. Минусом использования SPL является больший размер программы (прошивки) и сниженное быстродействие. Зато сводится к минимуму возможность совершить ошибку. Поэтому для освоения программирования рекомендуется начинать работу с функциями SPL, добиваться работоспособности проекта, а затем модифицировать критические куски кода к регистровому исполнению. Настройку порта рассмотрим на примере использования порта PORT_C вывод pin_0, сокращенно PC0. Этот вывод используется в программе [[PROG:Start:HelloWord|"Hello World - светодиод"]]. ==== Инициализация порта ==== // Включаем тактирование порта C RST_CLK_PCLKcmd (RST_CLK_PCLK_PORTC, ENABLE); Первым действием всегда включается тактирование. Подробнее - [[doc:doclist:core_clock|Тактирование процессора]]. // Инициализируем структуру конфигурации вывода(-ов) порта значениями по умолчанию PORT_StructInit(&GPIOInitStruct); Функция PORT_StructInit заполняет структуру конфигурации порта значениями по умолчанию. 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; } === PORT_Pin === Это маска выбора выводов для которых будет применена данная конфигурация. Возможны варианты PORT_Pin_0 .. PORT_Pin_15, PORT_Pin_All и всевозможные варианты масок из этих значений. Например, для применения конфигурации к выводам 0 и 1 используется PORT_Pin = PORT_Pin_0 | PORT_Pin_1. В процессоре 1986ВЕ92У есть 6 портов ввода вывода (A, B, C, D, E, F). Обычно каждый порт имеет по 16 выводов (ножек), которые можно настроить по отдельности. Но количество выводов у микросхемы может быть сокращено в целях экономии, например у данного процессора в корпусе LQFP64 порт А имеет только выводы PA0 - PA7. Название вывода берется из названия порта и номера вывода. === PORT_OE === Это поле настраивает порт на вывод данных или на вход. Возможные варианты PORT_OE_OUT и PORT_OE_IN, в первом случае мы будем писать в порт, а во втором считывать из порта. === PORT_PULL_UP и PORT_PULL_DOWN === Эти параметры задают подтяжку вывода к линии питания или земли. Обычно это используется когда вывод используется как вход. Резистор подтяжки составляет порядка ~50КОм, точное значение необходимо уточнять в спецификации на микропроцессор. Возможные варианты значений для PORT_PULL_UP это PORT_PULL_UP_OFF и PORT_PULL_UP_ON, а для PORT_PULL_DOWN соответственно PORT_PULL_DOWN_OFF и PORT_PULL_DOWN_ON. Важно не путать эти значения, нельзя например сделать так PORT_PULL_DOWN = PORT_PULL_UP_OFF. Очень часто значения являются определенными битовыми масками, которые в итоге должны расположиться в по нужному смещению в регистре. Поэтому PORT_PULL_UP_OFF не равно PORT_PULL_DOWN_OFF, и важно их не путать. === PORT_PD_SHM === Этот параметр включает - выключает использование триггера Шмитта. Этот триггер известен тем, что имеет гистерезис и при некотором отклонении напряжения dU от заданного логического уровня на входе сохраняет текущее логическое значение на выходе. Например, если если ножка настроена на вход и напряжение на ней равно напряжению питания, то микроконтроллер трактует это, как наличие логической "1" на входе. Если в какой-то момент на линии появится помеха, или наводка такая, что напряжение на входе просядет меньше чем на dU, то микропроцессор будет по прежнему трактовать это как логическая "1". С логическим нулем ситуация аналогичная. Это поле может принимать следующие значения, при PORT_PD_SHM_OFF dU = 200 мВ, а при PORT_PD_SHM_On = 400 мВ. === PORT_PD === Параметр определяет подключение вывода как управляемый драйвер PORT_PD_DRIVER, либо как открытый сток - PORT_PD_OPEN. PORT_PD_DRIVER - обычный режим работы, его еще называют тяни-толкай (push-pull). Это режим с двумя устойчивыми состояниями "0" и "1". Когда мы пишем "1" то вывод через полевые транзисторы подключается к цепи питания и отключается от земли, таким образом на выходе появляется напряжение питания. Когда записывается в порт логический "0", то отключается питание и подключается земля, так формируется 0 на выводе. В режиме PORT_PD_OPEN вывод отключается от транзистора коммутирующего его с цепью питания, то есть мы может только просаживать внешнюю линию на 0, а при записи 1 это "просаживание" отключается. В таком режиме подразумевается, что используется внешняя подтяжка к питанию, как это происходит например на шине I2C. === PORT_GFEN === Режим работы входного фильтра PORT_GFEN_OFF - выключен и PORT_GFEN_ON - фильтрация импульсов до 10 нс. ===PORT_MODE=== Параметр определяет в каком режиме будет работать вывод контроллера в аналоговом PORT_MODE_ANALOG или в цифровом PORT_MODE_DIGITAL. Аналоговый режим используется, например, когда через ножку заводится аналоговый сигнал для оцифровки внутренним АЦП. При выводе аналогового сигнала от встроенного ЦАП используется такой же режим. Назначение ножек при использовании в аналоговом режиме следует смотреть в спецификации раздел "Порты ввода - вывода". Например, в семействе 1986ВЕ9х вывод РЕ9 (Port_E, вывод порта 9) является выводом встроенного DAC1. ===PORT_FUNC=== Данный параметр задает какую функцию будет исполнять порт в цифровом режиме. Есть четыре варианта значений этого параметра. Основная функция это PORT_FUNC_PORT - вывод используется как стандартный порт ввода-вывода. В этом режиме мы сами пишем и читаем состояние вывода микроконтроллера. В остальных режимах PORT_FUNC_MAIN, PORT_FUNC_ALTER, PORT_FUNC_OVERRID вывод используется в аппаратно реализованных алгоритмах, например UART, SPI и прочих. Как будет использоваться вывод при задании определенной функции необходимо смотреть в спецификации раздел "Порты ввода - вывода". Например, для 1986ВЕ9х вывод РЕ12 в функции MAIN является 28-й линией шины адреса, в функции ALTER - линией RXD в аппаратной реализации SPI, в функции OVERRID - линией RXD в аппаратной реализации UART1. ^ Вывод ^ Analog ^ DIGITAL ^^^^ ^ ::: ^ ::: ^ PORT ^ MAIN ^ ALTER ^ OVERRID ^ | РЕ12 | - | РЕ12 | ADDR28 | SSP1_RXD | UART1_RXD | В аналоговом режиме данный порт не имеет применения. Если для разных выводов выбрать одну и ту же функцию, например, TMR2_CH2, то реально будет задействован только один вывод, причём выбор активного осуществляется в порядке приоритета по названию порта, т.е. сначала порт А, далее порт B и т.д. ===PORT_SPEED=== Параметр определяет время переключения логических состояний, по существу длительность фронтов. Возможные варианты * PORT_OUTPUT_OFF - Порт выключен * PORT_SPEED_SLOW - Медленный фронт, порядка 100нс * PORT_SPEED_FAST - Быстрый фронт, порядка 20нс * PORT_SPEED_MAXFAST - Максимально быстрый фронт, порядка 10нс. При быстрых фронтах возрастает потребление микроконтроллера, но зато можно увеличить скорость работы с подключенной периферией. Для мигания светодиодом скорость не важна и лучше использовать вариант с PORT_SPEED_SLOW. Работа порта ближе к схемотехнике рассмотрена в [[doc:doclist:gpio_schm|"Схемотехника портов GPIO"]]. =====Управление портами через регистры.===== SPL делает настройку портов более читаемой, и предохраняет нас от случайных ошибок. В конечном итоге функции SPL задают наши параметры в регистры настроек выводов портов. Эти регистры представлены на следующей картинке, описание же находится в [[doc:doclist:gpio_schm|"Схемотехника портов GPIO"]]. {{doc:doclist:pad_scheme.png}}