Работа с портами ввода-вывода GPIO из ESP-IDF
Добрый день, уважаемый читатель! В этой статье обсудим методы работы со встроенными портами ввода-вывода GPIO в цифровом режиме.
Если вы создавали скетчи для Arduino IDE, то наверное, знаете, как осуществляется работа с GPIO для Arduino:
pinMode(10, OUTPUT); // Настраиваем PIN10 на выход digitalWrite(10, HIGH); // Записываем в PIN10 высокий уровень
В данном случае pinMode настраивает порт ввода-вывода на режим “выход”, а digitalWrite служит для записи в ранее настроенный порт логической единицы (или нуля). Это унифицированные функции Arduino, которые “внешне” не зависят от аппаратной платформы, а вот их внутренняя реализация будет зависеть от того, какой микроконтроллер вы используете. Это позволяет сравнительно легко переносить код с одного микроконтроллера на другой без адаптации (на самом деле это не всегда прокатывает, но тем не менее, разработчики платформы Arduino к этому стремятся).
На ESP-IDF необходимости в такой унификации нет, поэтому используются более специфичные функции. Их мы сегодня и обсудим.
【電子工作】ラズベリーパイ4BのCPUをペルチェ素子で冷却!! | Thermoelectric Cooling for Raspberry Pi. Peltier.
Какие выводы GPIO можно использовать для ввод и вывод
Давайте вспомним, какие выводы можно использовать на ESP32 (я буду рассматривать линейки ESP32-WROOM или ESP32-WROVER).
Чип ESP32 имеет 34 физических контакта GPIO. Каждая контактная площадка может использоваться как вход/выход общего назначения (GPIO) или может быть подключена к внутреннему периферийному сигналу. Мультиплексоры IO_MUX, RTC IO_MUX и матрица GPIO отвечают за маршрутизацию сигналов от периферийных устройств к контактам GPIO. Вместе эти системы обеспечивают гибко настраиваемый ввод-вывод.
Порты ввода-вывода для ESP32-DevKitC V4
- На ввод и выводдля ESP32-WROOM можно смело использовать следующие 18 выводов GPIO: 2, 4, 5, 12, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33. Все указанные выводы имеют встроенные программно-подключаемые резисторы подтяжки 45 кОм (в документации это называется “слабая подтяжка”). Я буду называть эти порты “универсальными”, для простоты понимания. Некоторые из них можно назначить для использования различных интерфейсов: I2C, SPI и т.д. Примечания: выводы 5, 12, 14, 15 использовать следует с осторожностью; для ESP32-WROVER выводы 16 и 17 использовать нельзя.
- Выводы GPIO 34, 35, 36, 39 можно использовать только на ввод, и у них отсутствуют встроенные резисторы слабой подтяжки. На эти же выводы выведен канал ADC1.
- Можно ещё использовать GPIO 0, но так как он используется в схеме сброса контроллера после прошивки, его нельзя подтягивать его к питанию через резистор.
На все эти выводы можно подключить обработчики прерываний для отслеживания изменения уровня извне микроконтроллера, но прерывания обсудим в следующей статье.
Хочу обратить ваше внимание только на то, что, согласно спецификации, выводы GPIO допускают ток аж до 40 mA “высокого” уровня и до 28 mA “низкого” уровня. Это позволяет управлять различными слаботочными устройствами типа светодиодов напрямую, без применения коммутирующих транзисторов, нужно только учитывать напряжение на выводе не более 3.3В.
Настройка порта GPIO
Для работы с портами GPIO необходимо подключить модуль “driver/gpio.h”:
Как и в Arduino IDE, прежде чем начинать работу с GPIO, его нужно настроить (сконфигурировать). Каждый “универсальный” порт можно настроить:
- направление: на вход или выход
- слабая подтяжка (45 КОм) к +3,3В или к “земле”
- прерывание (если необходимо)
ESP-IDF предлагает два метода конфигурации:
- Пакетная конфигурация сразу нескольких портов: с помощью функции gpio_config (constgpio_config_t* pGPIOConfig) . Эта функция позволяет за один вызов настроить все параметры для нескольких выбранных портов: направление, подтяжки, прерывания. Соответственно это чуть более быстрый способ.
- С помощью набора функций gpio_set_direction,gpio_set_pull_mode , и т.д. Это более “детализированные” функции и работают они только для одного выбранного порта. Я чаще использую именно этот способ, скорее всего “по привычке” (так как они более похожи на способ из Arduino IDE).
Выбор вывода для работы в режиме GPIO
Прежде всего необходимо настроить GPIO для использования в режиме ввода-вывода (так как GPIO на ESP32 могут быть использованы для разных целей с помощью мультиплексора выводов IO_MUX). Разработчики ESP32 не гарантируют, что после аппаратного сброса микроконтроллера все его выводы установятся в режим ввода-вывода. Поэтому операцию перевода нужных выводов в режим GPIO желательно делать всегда.
Сделать это можно с помощью функции:
- gpio_num – номер вывода GPIO
Эта функция настраивает IOMUX для этого вывода на работу с GPIO, включает встроенную слабую подтяжку и отключает режимы работы на вход и на выход (то есть устанавливается режим GPIO_MODE_DISABLE – см. следующий раздел).
Для этой же цели можно воспользоваться другой функцией, которая просто перенастраивает IOMUX для этого вывода на работу с GPIO:
- gpio_num – номер вывода GPIO
Режимы работы портов ввода-вывода
ESP32 поддерживает несколько режимов GPIO:
- GPIO_MODE_DISABLE – порт отключён
- GPIO_MODE_INPUT – порт работает только на вход
- GPIO_MODE_OUTPUT – порт работает только на выход
- GPIO_MODE_OUTPUT_OD – порт работает только на выход в режиме “открытый коллектор” (open-drain)
- GPIO_MODE_INPUT_OUTPUT_OD – порт может работать одновременно и на вход и на выход с открытым коллектором
- GPIO_MODE_INPUT_OUTPUT – порт может работать одновременно и на вход и на выход
В режимах с открытым коллектором (OD) микроконтроллер управляет только низким логическим уровнем, при установке на GPIO логической единицы вывод отключается и остается “болтаться в воздухе”. Этот режим удобно использовать для датчиков типа DHT11-22 или для управления светодиодами “по низкому уровню” (катодом к выводу, анодом к +3,3В).
Для выбора режима порта используйте функцию
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
- gpio_num – идентификатор GPIO
- mode – режим работы
Переключить режим работы порта можно в любой момент, не обязательно делать это только при старте прошивки.
Встроенная подтяжка
Большинство портов имеют встроенные резисторы слабой подтяжки. Чтобы их задействовать, существует несколько функций.
Универсальная функция:
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
- gpio_num – идентификатор GPIO
- pull – режим подтяжки
Режим gpio_pull_mode_t может принимать одно из нескольких значений:
- GPIO_PULLUP_ONLY – подтяжка к питанию +3,3В
- GPIO_PULLDOWN_ONLY – подтяжка к “земле”
- GPIO_PULLUP_PULLDOWN – подтяжка одновременно к питанию +3,3В и “земле”
- GPIO_FLOATING – подтяжка отключена
Однако можно использовать и несколько более простых функций:
- esp_err_tgpio_pullup_en(gpio_num_tgpio_num) – включить подтяжку к питанию +3,3В
- esp_err_tgpio_pullup_dis(gpio_num_tgpio_num) – отключить подтяжку к питанию +3,3В
- esp_err_tgpio_pulldown_en(gpio_num_tgpio_num) – включить подтяжку к “земле”
- esp_err_tgpio_pulldown_dis(gpio_num_tgpio_num) – отключить подтяжку к “земле”
Какой метод использовать – выбирайте на свой вкус.
Настройка допустимого выходного тока
Для GPIO, работающих на выход, ESP32 позволяет задать максимальный ток через выход. Это может быть полезно в некоторых случаях, например можно ограничить ток через светодиод без использования резистора. Для этого воспользуйтесь функцией:
esp_err_t gpio_set_drive_capability (gpio_num_t gpio_num , gpio_drive_cap_t strength)
- gpio_num – идентификатор GPIO
- strength – максимально допустимый ток
Режим gpio_drive_cap_t может принимать одно из нескольких значений:
- GPIO_DRIVE_CAP_0 – слабый, до ~5мА
- GPIO_DRIVE_CAP_1 – сильнее, до ~10мА
- GPIO_DRIVE_CAP_2 – средний (по умолчанию), до ~20мА
- GPIO_DRIVE_CAP_3 – максимальный, до ~40мА
Как видите, по умолчанию ток высокого уровня ограничен на уровне 20мА. В большинстве случаев вызывать данную функцию при настройке порта не требуется. Но если ваше устройство на ESP32 требует большего тока (например при управлении мощным биполярным транзистором), то вы можете столкнуться с “неправильным” поведением.
Запись логического уровня в GPIO
Для записи данных в выходной порт необходимо воспользоваться функцией:
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
- gpio_num – идентификатор GPIO
- level – логический уровень, 0 (низкий) или 1 (высокий)
Ничего сложного, всё предельно просто.
Чтение логического уровня из GPIO
Для чтения данных из порта необходимо воспользоваться другой функцией:
uint32_t gpio_get_level(gpio_num_t gpio_num)
- gpio_num – идентификатор GPIO
Если GPIO не настроен для ввода (или ввода и вывода), возвращаемое значение всегда равно 0.
Практическое использование GPIO в режиме вывода – мигаем светодиодом
Допустим, мы хотим использовать светодиод, подключенный к одному из выводов через токоограничительный резистор, например это GPIO12. Классика жанра.
Источник: Яндекс Картинки
Светодиод можно подключить двумя способами:
- С управлением по высокому уровню. Анод через резистор к GPIO, катод – к общему проводу. В этом случае следует использовать режим GPIO_MODE_OUTPUT.
- С управлением по низкому уровню. Анод к +3,3В, катод через резистор к GPIO. В этом случае лучше использовать режим GPIO_MODE_OUTPUT_OD.
Для ESP32 наверное оптимальнее использовать первый способ, так как ток GPIO для высокого уровня может достигать до 40мА, а для низкого – только 28мА. Хотя для светодиода вполне достаточно 10мА, в крайнем случае – 20мА (для старых советских светодиодов зеленого цвета).
Настройка вывода будет выглядеть так:
Для мигания светодиодов создадим задачу. Функция задачи для мигания светодиодом будет выглядеть примерно так:
Использование GPIO для пробуждения микроконтроллера
Если вы используете в своих разработках режим глубокого сна (например при питании от батарей), то вы можете использовать вывод GPIO для пробуждения микроконтроллера по внешнему сигналу. Задействовать данную функцию можно с помощью функции:
esp_err_t gpio_wakeup_enable (gpio_num_t gpio_num, gpio_int_type_t intr_type)
- gpio_num – идентификатор GPIO
- intr_type – логический уровень на GPIO для пробуждения. Можно использовать только GPIO_INTR_LOW_LEVEL или GPIO_INTR_HIGH_LEVEL.
Отключить пробуждение можно с помощью функции gpio_wakeup_disable (gpio_num_t gpio_num).
Ну вот и всё, о чем я хотел рассказать в данной статье. Пример вы можете посмотреть на GitHub.
Прерывания по изменению уровня на GPIO мы обсудим в следующей статье, так как это отдельная большая тема.
Источник: kotyara12.ru
AMD GPIO Driver — что это за драйвер? (AMD GPIO Controller)
Драйвер интерфейса ввода/вывода (чипсет).
Простыми словами — нужен для корректной работы чипсета (набор логики) на материнской плате.
Без драйвера скорее всего тоже все будет работать, но функции будут только базовые, дополнительные — работать не будут. Всякие технологии, заложенные в чипсет, в том числе которые теоретически могут ускорить работу Windows — будут работать только после установки этого драйвера. Например регулировка частоты в Windows (в настройках Электропитания), автоматическое ее снижение в простое — не будет работать без этого драйвера. Также могут не работать порты USB 3.0/3.1 (точнее работать будут, но как версия 2.0) или некоторые технологии ускорения передачи данных по USB.
Также вы можете встретить драйвер с названием AMD GPIO Driver Promontory — это просто версия для чипсетов серии 300, 400 и X570.
Сам драйвер входит в состав пакета AMD Chipset Drivers. Поэтому можно сделать вывод, что он точно нужен для чипсета. Также в пакет входят и другие — AMD PCI driver, PSP driver, AMD SMbus, Promonotory GPIO Driver. И еще — после установки пакета можно перейти в эту папку (в нее распаковываются дрова):
И установить оттуда схему электропитания Ryzen balanced PowerPlan, которая тоже оптимизирует работу ПК.
После корректной установки драйверов у вас в диспетчере появится устройство AMD GPIO Controller:
Надеюсь информация оказалась полезной. Удачи и добра, до новых встреч друзья!
Источник: 990x.top
Изучаем STM32. Урок 2. Изучаем порты ввода-вывода GPIO (ч1)
Добрый день, итак, пока есть время между редактированиями кодов и пайками)) напишу ещё одну статейку. На этот раз мы будем знакомиться с нашими ножками (нет не теми что внизу), а теми которые находятся на микроконтроллере и за счёт чего он воспринимает сигналы из внешнего мира и соответственно передаёт сигналы в него.
Итак, давайте посмотрим на блок — схему порта ввода-вывода контроллера
Тут у нас справа расположены защитные диоды, дальше внизу расположен регистр вывода и на нём мы видим два полевичка один из которых N-канаьный, второй P-канальный. Именно они нам выдают либо лог. единицу, либо лог. ноль.
Вверху нарисован регистр ввода, в котором мы видим триггер шмидта, перед ним мы видим резисторы подтяжки
Ну кому более интересно это, тот может найти feference manual и выучить всё от корки до корки, мы же в данной части урока просто разберёмся что значат разные режимы работы наших портов
Итак, помните в прошлом уроке мы настраивали чем у нас будет ножка контроллера — Входом, Выходом. Но это не все параметры. Ещё ножка может быть сконфигурирована как аналоговый входвыход для допустим работы с АЦП, или с ЦАП, у кого он есть на «борту»))
Давайте рассмотрим все режимы работы
1)Input floating — по простому это вход безо всяких подтяжек (Hi-Z состояние, плавающий). По простому вход у нас ни к чему не подключён (привет помехи))))
2)Input pull-up — режим входа, в котором он чрез подтягивающий резистор подключён к питанию (номинал резистора несколько десятков килоОм)
3)Input-pull-down — режим входа, в котором он чрез подтягивающий резистор подключён к земле (массе) (номинал резистора несколько десятков килоОм)
4)Analog — режим работы, который включаем если желаем работать с АЦП или ЦАП
5)Output open-drain with pull-up or pull-down capability — выход с «открытым коллектором»
6)Output push-pull with pull-up or pull-down capability — самый используемый режим, в котором наш пин может выдавать как лог. ноль так и лог. единицу (это будут работать те самые полевые тарнзисторы о которых писал выше)
7)Alternate function push-pull with pull-up or pull-down capability — альтернативная функция (двухтактный вывод)
8)Alternate function open-drain with pull-up or pull-down capability — альтернативная функция (открытый
коллектор)
Теперь опишу как работаем с этими параметрами в нашей среде программирования.
Вот смотрите, кусочек кода, который отвечает за настройку параметров выхода
GPIO_InitStruct.Pin = GPIO_PIN_0; — данная строчка кода указывает что конфигурировать мы будем ножку 0
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; — Данная строчка указывает что режим работы — Вход
У данной строчки могут быть вот такие параметры
GPIO_MODE_INPUT
GPIO_MODE_OUTPUT_PP
GPIO_MODE_OUTPUT_OD
GPIO_MODE_AF_PP
GPIO_MODE_AF_OD
Следующая строчка GPIO_InitStruct.Pull = GPIO_PULLDOWN; — Указывает что у нас подтяжка к массе. У данной строчки ещё могут быть вот такие варианты
GPIO_NOPULL
GPIO_PULLUP
GPIO_PULLDOWN
Ну и последняя строчка указывает нам с каким портом нашего контроллера мы вообще только что разговаривали) — HAL_GPIO_Init(GPIOA,
Здесь мы рассмотрели настройку нашего пина к которому подключена кнопка. PA0.
А давайте теперь рассмотрим настройку нашего порта, куда подключены светодиоды
/*Configure GPIO pins : PD12 PD13 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOD,
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13; — эта строчка указывает какие пины настраиваем
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; — эта строка указыввает нам режим работы — ВЫХОД двухтактный (push-pull) . Возможные варианты конфигурации описаны чуть выше.
GPIO_InitStruct.Pull = GPIO_PULLUP; — данная штука указывает что включена подтяжка к питанию
Возможные варианты конфигурации описаны чуть выше.
GPIO_InitStruct.Speed = GPIO_SPEED_LOW; — данная строчка настраивает скорость работы выхода
Возможны вот такие варианты
GPIO_SPEED_LOW — низкая скорость 2MHz
GPIO_SPEED_MEDIUM — средняя скорость 25MHz
GPIO_SPEED_FAST — повышеная скорость 50MHz
GPIO_SPEED_HIGH -высокая скорость до 100MHz
Также, чтобы работал наш порт, и мы что то могли с ним делать — нам нужно включить тактирование порта. Так как мы создаём проект в CubeMX, то он за нас это всё делает, но на будущее, мало ли, может кто то захочет использовать старые библиотеки- не забывайте подавать тактирование на нужные вам порты.
В нашем случае тактирование наших портов включается вот таким образом
/* GPIO Ports Clock Enable */
__GPIOA_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
Если поищем дальше, что обозначают эти строки то вот что найдём. Функция включения тактирования нашего порта A.
#define __HAL_RCC_GPIOA_CLK_ENABLE() do <
__IO uint32_t tmpreg;
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
UNUSED(tmpreg);
> while(0)
Ну а теперь код, с помощью которого мы управляем нашими пинами.
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET); — сбрасывает пин в НОЛЬ
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET); — устанавливает пин в ЕДИНИЦУ
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); — изменяет состояние пина на противоположное. Если было 0, то станет единица, и наоборот.
Ну и добавлю сюда ещё одну функцию — функция задержки Delay. Мы её часто использовали в CAVR, и тут она тоже есть. Задаётся она в милисекундах и выглядит вот так — HAL_Delay(100);
Это означает задержка в 100 милисекунд.
Можете теперь поиграться светодиодами на плате, выставив задержку и используя HAL_GPIO_TogglePin. Ваши светодиоды будут по очереди перемигиваться.
Жмём палец вверх, и читаем, читаем, читаем мануалы, и уже в голове придумываем что мы сделаем на STM32! STM — мечты сбываются)))
Ну и не забываем про хорошую музычку, да погромче! Пока писал — наслаждался вот этим шедевральным концертом. С ним как то и светодиоды по другому перемигиваются))
Источник: www.drive2.ru
Работа через GPIO в Raspberry Pi 3
Одна из основных функций одноплатных компьютеров семейства Raspberry Pi — обеспечивать взаимодействие с разнообразной периферией. Это могут быть датчики, реле и двигатели, лампочки и прочие исполнительные модули и блоки. За такое «общение» отвечает встроенный в платы Raspberry Pi GPIO — интерфейс ввода-вывода. Рассмотрим его подробнее на примере RPi 3 B.
Что такое колодка GPIO
GPIO — сокращение, означающая General-Purpose Input-Output, или общий интерфейс ввода/вывода. Он содержит цифровые входы и выходы для подключения датчиков, разнообразных контроллеров, дисплеев, реле и прочей электронной периферии. Внешне GPIO похож на «гребенку» из штырьков-пинов. В Raspberry Pi 3 его внешний вид таков (в верхней части платы):
Колодка GPIO Raspberry чем-то напоминает интерфейс подключения жестких дисков IDE.
Для правильной работы через GPIO необходимо знать конфигурацию пинов. В Raspberry Pi распиновка такова:
Разъемов питания 4. Прочие пины способны выступать в роли входа или выхода. Кроме того, некоторые из них многофункциональны и могут работать как интерфейс UART, I2C, SPI или ШИМ.
Рассмотрим более подробно устройство «гребенки».
Устройство GPIO
Число пинов на колодке GPIO Raspberry Pi 3 равняется 40. Они пронумерованы и делятся на три группы:
- питающие (power на схемах);
- заземляющие (GND, Ground);
- порты (часто обозначаются как BCM).
Первые необходимы для подачи электричества разных напряжений — 3.3 и 5 В. Разница между ними была рассмотрена выше. Вторые обеспечивают безопасность работы платы, отводя электричество. А третьи выступают в качестве интерфейсов, принимая и отдавая данные. Именно к ним пользователь подключает свои модули и приборы.
Схема пинов Raspberry Pi 3 Model B:
На данной схеме pinout выводы пронумерованы по следующему принципу:
- 1 — левый в первом верхнем ряду;
- 2 — второй в верхнем ряду, и так далее.
Выходы 1 и 17 обеспечивают питание 3.3 В, 2 и 4 — для 5 В. «Земля» расположена на 9, 25 и 39, и на 6, 14, 20, 30, 34. Прочие контакты — интерфейсные порты.
Особенности GPIO «малинки»
При работе необходимо учитывать несколько важных моментов:
- на обоих выводах 3.3 В суммарный ток равен 50 мА. Поэтому напрямую к ним можно подключать устройства с общим потреблением до 50 миллиампер;
- 5-вольтовые выводы поддерживают в сумме до 500 мА, что позволяет подсоединять к ним более мощную периферию, включая устройства ввода (мышки, клавиатуры и так далее);
- GPIO допускает подачу напряжения только до 3.3 В. Если превысить это значение, велик шанс сжечь вход или весь контроллер;
- 14-15 пины по умолчанию работают как RXD и TXD UART-интерфейса и сразу после включения выдают напряжение в 3.3 В;
- также по умолчанию почти все конфигурируемые выводы «малинки» являются входами с высоким сопротивлением. Исключение — GPIO0 и GPIO1 (SDA и SCL соответственно);
- работая в режиме INPUT, пин автоматически переводит подаваемую на него информацию в цифровой вид. При этом отметим, что RPi3 исходно работает только с цифровым сигналом, а для обработки аналоговых используется специальный преобразователь ЦАП/АЦП.
Важно помнить: все «ножки» колодки соединены с процессором напрямую, некорректные операции и неверное подключение способно привести к полной неработоспособности платы.
Поэтому при правильном проектировании приспособлений с большим количеством используемых выводов GPIO схема должна предусматривать дополнительные меры безопасности. Желательно делать защитные развязки электронными ключами, через трансформаторы напряжений и различные буферы.
Как правило, RPi3 работает под управлением ОС семейства Linux (Raspbian или другой). Сразу после загрузки системы напряжение на пинах низкое и остается таковым до изменения запустившимся скриптом или программой. Но в промежуток от подачи электропитания до инициализации системных драйверов пины в произвольном порядке способны выдавать высокое напряжение. Это следует учитывать и изолировать по питанию входы-выходы в процессе запуска системы.
Особые порты
Внешние модули можно подсоединять к любым портам «гребенки» GPIO. Но есть два особенных, которые плата резервирует для специфических задач. На обычной схеме их номера — 27 и 28. Они предназначены для плат расширения, и желательно не использовать их без необходимости.
Нумерация
Выше рассматривались номера пинов. Но важно понимать, что заложенная в центральный процессор логическая нумерация отличается от приведенной на схеме физической. Ее особенности:
- не исполняющие функций ввода-вывода «штырьки» номеров не имеют;
- контакт 3 является портом, но имеет логический номер BCM2.
Этот принцип следует учитывать при создании кода, поскольку ПО ориентируется именно на логические номера. Их схема:
У новичков это может вызвать недоумение и путаницу. Для помощи в решении проблемы существует программная библиотека Wiring Pi с собственной альтернативной нумерацией. Так, логический GPIO2 в ней определен как WIringPI 8. Это может показаться непонятным, но после освоения библиотеки ее принцип нумерования становится привычным и удобным.
Способы взаимодействия с интерфейсом GPIO
Интерфейсная гребенка позволяет работать с собой несколькими путями:
- встроенными инструментами Linux (через интерпретатор bash и средства файловой системы);
- посредством языков программирования.
Управление на bash
Если использовать Raspbian, «баш» доступен по умолчанию. Пример отправки логического «1» на пин номер 25:
sudo su —
echo 25 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio25/direction
echo 1 > /sys/class/gpio/gpio25/value
echo 0 > /sys/class/gpio/gpio25/value
Чтение данных со входа номер 24:
echo 24 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio24/direction
cat > /sys/class/gpio/gpio24/value
Управление через Python
Питон — один из самых популярных языков разработки под Raspberry, и в нем создан богатый инструментарий. В последних дистрибутивах ОС Raspbian уже присутствует и сама среда Python, и необходимая для работы библиотека RPi.GPIO. Если же таковой нет, ее можно загрузить из репозитория:
sudo apt-get install python-rpi.gpio
Далее необходимо подгрузить этот модуль в программу:
import RPi.GPIO as GPIO
Далее следует определиться с порядком нумерации — брать ли «физический» по номерам портов на микрокомпьютере, или использовать принцип обращения по номерам процессорных каналов (BCM):
GPIO.setmode (GPIO.BOARD)
GPIO.setmode (GPIO.BCM)
Преимущество первого пути — универсальность: он будет работать с любой ревизией контроллера. BCM обращается непосредственно к каналам процессора на более низком уровне.
На следующем шаге выбирается режим работы портов input или output.
GPIO.setup(channel, GPIO.IN)
GPIO.setup(channel, GPIO.OUT)
Сразу же можно определить начальное состояние выходов RPi3:
GPIO.setup(channel, GPIO.OUT, GPIO.LOW)
GPIO.setup(channel, GPIO.OUT, GPIO.HIGH)
Команда на чтение информации со входа:
Запись значения на выход GPIO:
Пример работы
Рассмотрим пример взаимодействия RPi3 и простой схемы со светодиодом через написанную на Python программу.
Для начала понадобится «малинка» с установленным ПО и средой разработки, макетная плата, диод, кнопка и резисторы. Схема подключения приведена ниже:
Здесь R1 имеет сопротивление 10 кОм, R2 — 1 кОм, а резистор R3 — 220 кОм.
Что обеспечивает подобная модель:
- без нажатия кнопки на входе пина возникает напряжение 3.3 В;
- при нажатии кнопки через нее и резистор R1 начнет подаваться ток 0.33 мА, а на входе схема обеспечит 0 В;
- при неверном подключении пинов по схеме потечет ток безопасных значений, предохраняя систему от повреждения.
Написанный на Python скрипт включения-выключения лампочки:
Import RPi.GPIO as GPIO
GPIO.setmode (GPIO.BCM)
GPIO.setup (4, GPIO.OUT)
GPIO.output (4, 1)
GPIO.cleanup ()
Для «моргания» диодом:
import RPi.GPIO as GPIO #импорт библиотеки дл¤ работы с GPIO
import time #импорт библиотеки дл¤ ожидани¤
GPIO.setmode(GPIO.BCM) #»запуск» GPIO
GPIO.setup(4, GPIO.OUT) #объ¤вл¤ем 4 порт как выход
while True: #цикл
GPIO.output(4, 1) #вкл светодиода
time.sleep(1) #пауза 1 с
GPIO.output(4, 0) #выкл светодиода
time.sleep(1) #пауза 1 с
Включение лампочки с кнопки:
import RPi.GPIO as GPIO #импорт библиотеки дл¤ работы с GPIO
GPIO.setmode(GPIO.BCM) #»запуск» GPIO
GPIO.setup(4, GPIO.OUT) #объ¤вл¤ем 4 порт как выход
GPIO.setup(3, GPIO.IN) #объ¤вл¤ем 3 порт как вход
while True: #цикл
if GPIO.input(3) == False: #если кнопка нажата
GPIO.output(4, 1) #вкл светодиода
else:
GPIO.output(4, 0) #выкл светодиода
Пример управления выходами с клавиатуры:
import RPi.GPIO as GPIO #импорт библиотеки дл¤ работы с GPIO
GPIO.setmode(GPIO.BCM) #»запуск» GPIO
GPIO.setup(4, GPIO.OUT) #объ¤вл¤ем 4 порт как выход
while True: #цикл
str = input(«Enter — вкл, другое — выход «);
if str != «»:
break
else:
GPIO.output(7, 1)
str = input(«Enter — выкл, другое — выход «)
if str != «»:
break
else:
GPIO.output(7, 0)
GPIO.cleanup()
Готовую программу следует сохранить в удобную папку и запустить командой Питона:
sudo python путь_к_исполняемому_файлу/имя_программы.py
Python предоставляет широкое поле возможностей для программирования «Распберри» и позволяет реализовывать гораздо более сложные схемы. Кроме того, с платой можно взаимодействовать на практически любом распространенном языке — одном из семейства C, Perl, Erlang и другое. Существуют даже реализации проектов на Java и HTML5.
Заключение
GPIO — удобное и универсальное решение, позволяющий подключать к RPi 3 разнообразную периферию и программировать ее поведение на одном из привычных языков. Логика взаимодействия довольно проста, а GPIO, как и сама «малинка», хорошо документирован, что обеспечивает легкий вход в программирование с использованием этого интерфейса даже новичкам в мире IT.
Начинающим можно порекомендовать язык Python, как несложный в освоении и логичный. В нем присутствуют все необходимые библиотеки работы с GPIO, ускоряющие и упрощающие процесс разработки.
Где купить
Видео по теме
Источник: vashumnyidom.ru
Raspberry Pi. Работа с портами ввода-вывода GPIO.
В сегодняшней статье мы рассмотрим основные нюансы и механизмы управления портами ввода-вывода GPIO платы Raspberri Pi. И, конечно же, как обычно, все проверим на практическом примере.
Все версии Raspberry Pi оснащены штыревым разъемом, на который выведены порты GPIO. Начиная с 2014-го года разъем стал 40-пиновым (ранее было 26). На версиях Pi Zero и Pi Zero W присутствует посадочное место для разъема, но физически он не распаян:
В любом случае, как и с любой другой платой, расположение сигналов на этом разъеме для конкретной модификации лучше всего проверить по официальному даташиту. Хотя на разных версиях плат 40-пиновые разъемы для совместимости идентичны. Распиновка и сам разъем выглядят следующим образом:
Порты можно разделить на несколько категорий:
Разберем по очереди. Пины 3.3V и 5V могут использоваться для питания внешних устройств, подключенных к плате. При этом ограничение по току выглядит так:
- Максимальный ток для вывода 5V определяется по формуле:
I_ = I_ medspace — medspace I_
где I_ — это входной ток источника, который мы используем для питания платы. А I_ — это ток, потребляемый самой платой, а также внешними устройствами, подключенными по USB. То есть мы подаем входной ток, часть его потребляют узлы платы, а то, что остается мы можем использовать для дополнительных устройств, подключенных к пину 5V.
- Для выводов 3.3V все проще — максимальный ток составляет 50 мА и на этом точка.
В итоге за вычетом выводов 3.3V, 5V и Ground остаются 28 пинов GPIO, помеченных на схеме зеленым. GPIO0 и GPIO1 можно считать зарезервированными (их назначение обязательно обсудим в отдельной статье). Таким образом, остается 26 выводов, которые можно использовать по-своему усмотрению. Каждый из них может быть сконфигурирован на работу в том или ином режиме. Вот, к примеру, возможные функции портов для платы Raspberry Pi 4:
То есть любой из портов ввода-вывода может выполнять до 6-ти различных функций, в зависимости от конфигурации. В частности, GPIO2 может быть использован как сигнал SDA для I2C1 (SDA1), либо, к примеру, как сигнал MOSI для интерфейса SPI3 (SPI3_MOSI).
Об I2C и SPI поговорим в ближайших статьях, а сегодня нас интересует использование GPIO в качестве «обычных» входов и выходов. В режиме выхода на пин может быть выведен высокий (3.3 В) или низкий (0 В) уровень напряжения. А, соответственно, в режиме входа мы можем проанализировать, какой уровень подан на пин — высокий или низкий — 3.3 В или 0 В. Тут важно обратить внимание, что порты не являются толерантными к 5 В, то есть подавать на вход 5 В категорически нельзя.
В режиме входа для любого из GPIO можно активировать внутреннюю подтяжку к питанию или земле (pull-up/pull-down). Если вывод настроен на использование подтяжки вверх, то это означает, что при отсутствии сигнала со входа будет считываться высокий уровень. С pull-down ситуация обратная — на входе в данном случае будет низкий уровень.
Исключением являются пины GPIO2 и GPIO3. Они имеют фиксированную подтяжку вверх, без вариантов.
В режиме выхода мы снова возвращаемся к ключевому параметру, а именно к ограничению по току. Максимальный ток для одного вывода составляет 16 мА. При этом, если используются несколько выходов, то суммарный ток не должен превышать 50 мА. Превышение допустимых значений с большой вероятностью приведет к выгоранию порта.
Собственно, давайте рассмотрим практический пример. Задействуем два вывода GPIO — один в качестве входа, второй в качестве выхода. На вход подключим кнопку, а на выход — светодиод. И реализуем программу, которая будет опрашивать сигнал на входе и по нажатию кнопки зажигать светодиод.
Выберем GPIO3 для светодиода и GPIO4 для кнопки. Схема подключения будет такой:
Давайте в двух словах разберем, что, как и зачем подключено. Начнем с кнопки. Программно активируем для GPIO4 подтяжку вверх, поэтому если кнопка не нажата мы получим на входе высокий уровень (логическую единицу). Соответственно, для того, чтобы определить нажатие кнопки, подключим ее к земле. В итоге при нажатой кнопке на входе будет низкий уровень (логический ноль).
Поскольку используем внутреннюю подтяжку, в этом примере ставить дополнительный внешний резистор подтяжки не будем.
Резистор R_ — токоограничительный. Как вытекает из названия он нужен для ограничения тока ) Рассмотрим, что произойдет, если вывод GPIO4 будет ошибочно настроен не как вход, а как выход и на нем будет 3.3 В. При нажатии кнопки произойдет короткое замыкание 3.3 В на землю, что приведет к безвозвратному повреждению порта платы. Это в случае отсутствия резистора.
А при наличии резистора ток будет ограничен величиной:
I = frac = 3.3 medspace мА
В данном случае получаем 3.3 мА, что вполне допустимо, и позволит сохранить порту жизнь в случае возникновения замыкания.
Итак, переходим к диоду, который подключен через резистор R_ . Каждому диоду соответствует своя собственная вольт-амперная характеристика (ВАХ), определяющая возможные значения прямого напряжения и тока. Рассмотрим первый попавшийся под руку светодиод, например такой — ссылка:
Открываем даташит на него и находим зависимость тока от напряжения при прямом включении:
Максимальный ток для GPIO в режиме выхода, как мы уже выяснили, составляет 16 мА. Чтобы не превысить это значение подадим на светодиод, например, 10 мА. Этому току, исходя из графика, соответствует напряжение 2 В. Теперь по закону Ома нам остается только определить величину резистора. На выходе GPIO у нас 3.3 В, на диоде должно падать 2 В, значит на резисторе остается:
U_ = 3.3 medspace В medspace — medspace 2 medspace В = 1.3 medspace В
При этом ток в цепи должен быть равен 10 мА, тогда сопротивление резистора:
R_ = frac = 130 medspace Ом
Если точной величины под рукой нет, можно взять резистор номиналом чуть больше. В общем, суть тут одна — обеспечить режим работы, при котором ток через выход не превышает допустимые 16 мА. Для большинства светодиодов в документации просто приводятся конкретные типовые значения напряжения и тока, например 2.5 В и 15 мА. Расчет будет выглядеть точно так же, как и рассмотренный, просто значения другие.
В общем, с подключением разобрались, время переходить к программной реализации. Существует огромное многообразие возможных способов для управления GPIO, мы же сегодня остановимся на использовании python.
И для работы с портами ввода-вывода используем библиотеку/модуль RPi.GPIO. В Raspberry Pi OS он включен по умолчанию, но в случае отсутствия команда для установки такая:
sudo apt-get install python-rpi.gpio
Создаем файл gpio_test.py и добавляем в него следующий код:
import RPi.GPIO as GPIO import time GPIO_LED = 3 GPIO_BUTTON = 4 DELAY_TIME = 0.5 GPIO.setmode(GPIO.BCM) GPIO.setup(GPIO_LED, GPIO.OUT) GPIO.output(GPIO_LED, GPIO.LOW) GPIO.setup(GPIO_BUTTON, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: while True: time.sleep(DELAY_TIME) if GPIO.input(GPIO_BUTTON) == 0: GPIO.output(GPIO_LED, GPIO.HIGH) print(‘led on’) else: GPIO.output(GPIO_LED, GPIO.LOW) print(‘led off’) except KeyboardInterrupt: GPIO.cleanup() print(‘exiting’)
Пройдемся подробнее, прямо по всем строкам последовательно. Делаем import модулей для работы с GPIO и для использования временной задержки:
import RPi.GPIO as GPIO import time
Добавим переменные для хранения номеров портов и величины задержки. У нас светодиод на GPIO3, а кнопка на GPIO4. Так и определим:
GPIO_LED = 3 GPIO_BUTTON = 4 DELAY_TIME = 0.5
Далее настроим режим нумерации портов, чтобы номера соответствовали названию сигнала (например, GPIO3), а не порядковому номеру на разъеме:
GPIO.setmode(GPIO.BCM)
Настраиваем GPIO3 на работу в режиме выхода и гасим светодиод, подав низкий уровень:
GPIO.setup(GPIO_LED, GPIO.OUT) GPIO.output(GPIO_LED, GPIO.LOW)
GPIO4 — в режиме входа с подтяжкой вверх:
GPIO.setup(GPIO_BUTTON, GPIO.IN, pull_up_down=GPIO.PUD_UP)
Далее организуем вечный цикл while True, в котором и будем проверять состояние кнопки и мигать светодиодом. Только обернем его в блок try, чтобы отловить исключение, возникающее, когда пользователь завершает процесс (нажав Ctrl + C). В случае завершения выполнения программы вызываем GPIO.cleanup():
try: while True: time.sleep(DELAY_TIME) if GPIO.input(GPIO_BUTTON) == 0: GPIO.output(GPIO_LED, GPIO.HIGH) print(‘led on’) else: GPIO.output(GPIO_LED, GPIO.LOW) print(‘led off’) except KeyboardInterrupt: GPIO.cleanup() print(‘exiting’)
Ну и, конечно, здесь же у нас вся полезная работа. Если кнопка нажата (а в нашей схеме этому соответствует низкий уровень/логический ноль на GPIO4), то зажигаем светодиод и выводим сообщение «led on». При отпускании кнопки — обратный процесс. Проверять кнопку будем каждые 0.5 с (DELAY_TIME).
Запускаем программу командой:
python gpio_test.py
И теперь, нажимая кнопку, можем наблюдать включение и выключение светодиода, как мы и планировали
Источник: microtechnics.ru