GPIO STM32: порты ввода-вывода STM32F1 и STM32F4
Как устроен вывод STM32 и как им управлять: восемь режимов и их коды в регистрах STM32F1 и STM32F4, атомарная запись через BSRR, альтернативные функции и ремап, скорость выходного каскада, допустимые токи и уровни по даташитам, выводы, выдерживающие 5 В, и примеры на CMSIS.
Обновлено Редакция GAW
GPIO (General-Purpose Input/Output) — порты ввода-вывода общего назначения. У STM32 выводы объединены в порты по 16: GPIOA, GPIOB и дальше по алфавиту, до GPIOG у старших STM32F103 и до GPIOK у STM32F42x/43x. Каждый вывод настраивается отдельно: цифровой вход с подтяжкой или без, двухтактный выход или открытый сток, выход периферии — альтернативная функция — или аналоговый вход для АЦП.
Ниже — два поколения портов, на которых держится большинство проектов: STM32F1 с регистрами CRL и CRH, где режим вывода задаётся четырьмя битами, и STM32F4 с отдельными регистрами MODER, OTYPER, OSPEEDR и PUPDR. Порты новых семейств — F0, F3, G0, G4, L4 и H7 — устроены как у F4, поэтому почти всё, что сказано о нём, к ним тоже относится. Электрические параметры приведены для STM32F103x8/B и STM32F405/407 по их даташитам; у других микроконтроллеров числа свои, но смысл тот же.
Коротко
- Восемь режимов: вход без подтяжки, с подтяжкой вверх или вниз, аналоговый вход, двухтактный выход, открытый сток и те же два варианта для альтернативной функции.
- Регистры: у STM32F1 — CRL и CRH (по 4 бита на вывод), у STM32F4 — MODER, OTYPER, OSPEEDR, PUPDR и AFRL/AFRH. Данные — в IDR и ODR, атомарная запись — через BSRR.
- Ток: до 25 мА на вывод (абсолютный максимум), нормированные уровни при ±8 мА; сумма всех выводов — 150 мА у STM32F103 и 240 мА у STM32F407.
- 5 В: только на выводы FT, без внутренних подтяжек и при включённом питании.
- Скорость — это крутизна фронтов, а не частота порта: от 2 до 50 МГц у F1, от Low до Very high у F4.
- После сброса все выводы — входы без подтяжки, кроме выводов отладчика JTAG и SWD.
Как устроен вывод
У каждого вывода есть выходной каскад, входной триггер Шмитта, две отключаемые подтяжки и защитные диоды. Схема одинакова у STM32F1 и STM32F4 (RM0008, рисунки 13–14; RM0090, рисунок 25), различаются только регистры, которые ей управляют.
- Выходной каскад — пара транзисторов P-MOS и N-MOS. В двухтактном режиме (push-pull) единица в регистре ODR открывает P-MOS и подтягивает вывод к VDD, ноль открывает N-MOS и прижимает его к земле. В режиме открытого стока P-MOS не включается никогда: ноль по-прежнему тянет линию вниз, а единица оставляет вывод в высокоимпедансном состоянии.
- Источник сигнала для каскада — либо регистр ODR, либо выход периферии (альтернативная функция): в режиме AF выходной регистр от вывода отключается.
- Входной триггер Шмитта работает во всех цифровых режимах, в том числе на выходе: состояние вывода попадает в регистр IDR на каждом такте шины — APB2 у STM32F1 и AHB1 у STM32F4. Поэтому по IDR можно проверить, что на самом деле происходит на линии с открытым стоком.
- Подтяжки вверх и вниз — резисторы 30–50 кОм, типовое значение 40 кОм (DS5319, таблица 36; DS8626, таблица 48). У STM32F407 исключение — PA10 и PB12, выводы ID интерфейсов USB OTG: 7–14 кОм.
- Аналоговый режим отключает и выходной каскад, и подтяжки, и триггер Шмитта. Вход триггера больше не болтается между порогами и не потребляет ток, а IDR в этом режиме читается как 0 (RM0008, 9.1.10; RM0090, 8.3.12).
Режимы и их коды
| Режим | STM32F1: CNF, MODE | STM32F4: MODER, OTYPER, PUPDR |
|---|---|---|
| Вход без подтяжки | CNF = 01, MODE = 00 | MODER = 00, PUPDR = 00 |
| Вход с подтяжкой вверх | CNF = 10, MODE = 00, бит ODR = 1 | MODER = 00, PUPDR = 01 |
| Вход с подтяжкой вниз | CNF = 10, MODE = 00, бит ODR = 0 | MODER = 00, PUPDR = 10 |
| Аналоговый | CNF = 00, MODE = 00 | MODER = 11 |
| Выход, двухтактный | CNF = 00, MODE = 01, 10 или 11 | MODER = 01, OTYPER = 0 |
| Выход, открытый сток | CNF = 01, MODE = 01, 10 или 11 | MODER = 01, OTYPER = 1 |
| Альтернативная функция, двухтактный | CNF = 10, MODE = 01, 10 или 11 | MODER = 10, OTYPER = 0, номер AF в AFRL или AFRH |
| Альтернативная функция, открытый сток | CNF = 11, MODE = 01, 10 или 11 | MODER = 10, OTYPER = 1 |
Таблица составлена по RM0008 (таблицы 20 и 21) и RM0090 (таблица 36). У STM32F1 поле MODE одновременно выбирает направление и скорость: 00 — вход, 01 — выход до 10 МГц, 10 — до 2 МГц, 11 — до 50 МГц. Подтяжка входа у F1 выбирается не отдельным битом, а битом ODR того же вывода: единица — вверх, ноль — вниз. В выходных режимах STM32F1 подтяжки выключены, а у STM32F4 их можно включить и для выхода — например, открытый сток с внутренней подтяжкой вверх.
У STM32F1 четыре бита на вывод — 32 бита на восемь выводов, поэтому регистров два: CRL для выводов 0–7 и CRH для 8–15. После сброса в обоих 0x4444 4444: CNF = 01 и MODE = 00, то есть все выводы — входы без подтяжки. У STM32F4 на вывод приходится по два бита в MODER, OSPEEDR и PUPDR и один бит в OTYPER. Поля всех регистров с кодами и значениями после сброса разобраны на страницах GPIO STM32F1 и GPIO STM32F4, там же — конструктор значения регистра.
Какой режим выбрать для периферии
У STM32F4 всё просто: вывод периферии переводится в режим альтернативной функции (MODER = 10), а номер функции записывается в AFRL или AFRH; вход АЦП и выход ЦАП — в аналоговый режим. У STM32F1 номера функции нет, и для входов периферии используется обычный режим входа. RM0008 (раздел 9.1.11) даёт настройки для каждого блока, основные из них:
| Сигнал | Режим у STM32F1 |
|---|---|
| USART TX, SPI SCK и MOSI ведущего, выходы таймеров, CAN TX, MCO | альтернативная функция, двухтактный |
| USART RX, CAN RX, SPI MISO ведущего | вход без подтяжки или с подтяжкой вверх |
| входы захвата таймеров, ETR, BKIN, SPI SCK ведомого | вход без подтяжки |
| I²C SCL и SDA | альтернативная функция, открытый сток |
| входы АЦП, выходы ЦАП | аналоговый |
| линии внешних прерываний EXTI | вход без подтяжки, с подтяжкой вверх или вниз |
Двунаправленные сигналы периферии — например, SDA шины I²C — настраиваются как выход альтернативной функции: входной триггер при этом продолжает работать и передаёт уровень линии в периферию (RM0008, 9.1.4).
Состояние после сброса и выводы отладчика
Во время сброса и сразу после него альтернативные функции выключены, а все выводы — входы без подтяжки. Исключение — выводы отладочного порта, которые сразу после сброса принадлежат отладчику и имеют подтяжки (RM0008, 9.1.1; RM0090, 8.3.1):
| Вывод | Сигнал | Подтяжка после сброса |
|---|---|---|
| PA13 | JTMS / SWDIO | вверх |
| PA14 | JTCK / SWCLK | вниз |
| PA15 | JTDI | вверх |
| PB3 | JTDO / TRACESWO | нет |
| PB4 | NJTRST | вверх |
У STM32F4 это видно прямо в значениях регистров после сброса (RM0090, 8.4): GPIOA_MODER = 0xA800 0000 — PA13, PA14 и PA15 в режиме альтернативной функции, GPIOB_MODER = 0x0000 0280 — PB3 и PB4 тоже; GPIOA_PUPDR = 0x6400 0000 и GPIOB_PUPDR = 0x0000 0100 — подтяжки из таблицы выше; GPIOA_OSPEEDR = 0x0C00 0000 и GPIOB_OSPEEDR = 0x0000 00C0 — у PA13 и PB3 самая высокая скорость. Отсюда частая ошибка: запись GPIOA->MODER = значение целиком переводит PA13 и PA14 в другой режим, и отладчик теряет связь с микроконтроллером. Меняйте только поля нужных выводов.
У STM32F1 выводы JTAG освобождаются полем SWJ_CFG регистра AFIO_MAPR: 001 — без NJTRST, 010 — JTAG выключен, SWD работает (освобождаются PA15, PB3 и PB4), 100 — выключен и SWD (RM0008, 9.4.2 и 31.4.4). Перед записью в регистры AFIO нужно включить тактирование AFIO битом AFIOEN в RCC_APB2ENR, а биты SWJ_CFG только записываются — при чтении их значение не определено. AN4899 (раздел 6.6) добавляет: если вывод отладчика используется для другой цели, не прижимайте к нулю вывод с подтяжкой вверх и наоборот, пока подтяжка включена, — через неё потечёт лишний ток.
Ещё несколько выводов зависят от других блоков. PC14 и PC15 — это и выводы кварца 32,768 кГц OSC32_IN и OSC32_OUT: портами они работают, пока генератор LSE выключен (RM0008, 9.3.1; RM0090, 8.3.13). Выводы основного кварца у STM32F103 в корпусах на 36, 48 и 64 вывода можно превратить в PD0 и PD1 битом PD01_REMAP регистра AFIO_MAPR, но внешних прерываний на них не будет (RM0008, 9.3.2).
Чтение и запись: IDR, ODR, BSRR
- IDR — только чтение: младшие 16 бит показывают уровни выводов.
- ODR — выходные данные. Писать в него можно, но изменение одного бита — это чтение, изменение и запись. Если между чтением и записью произойдёт прерывание, которое меняет другой вывод того же порта, его изменение пропадёт.
- BSRR — атомарная установка и сброс. Единица в бите n (0–15) устанавливает бит n регистра ODR, единица в бите n + 16 сбрасывает его, нули ничего не делают. Это одна запись по шине: прерывание её не разорвёт, а остальные выводы порта не затрагиваются. Если в одной записи задать и установку, и сброс одного вывода, победит установка (RM0008, 9.2.5; RM0090, 8.3.5).
- BRR — только у STM32F1: 16-битный регистр сброса, единица в бите n сбрасывает вывод n. У STM32F4 для сброса пишут в старшую половину BSRR.
Есть и различие в доступе: регистры GPIO STM32F1 читаются и пишутся только 32-битными словами (RM0008, 9.1 и 9.2), а у STM32F4 допустимы слова, полуслова и байты (RM0090, 8.3).
Драйверы ST пишут в порты так же. HAL_GPIO_WritePin записывает в BSRR маску вывода или маску, сдвинутую на 16 бит. LL_GPIO_SetOutputPin пишет в BSRR, LL_GPIO_ResetOutputPin — в BRR у STM32F1 и в старшую половину BSRR у STM32F4. HAL_GPIO_TogglePin и LL_GPIO_TogglePin сначала читают ODR, а потом одной записью в BSRR сбрасывают выводы, которые были в единице, и устанавливают остальные: соседние выводы порта при этом не страдают, но если тот же вывод переключить из прерывания между чтением и записью, одно переключение потеряется.
Альтернативные функции и ремап
У STM32F4 перед каждым выводом стоит мультиплексор на 16 входов AF0–AF15, номер выбирается четырьмя битами в AFRL (выводы 0–7) или AFRH (8–15); в CMSIS это массив AFR[0] и AFR[1]. Одновременно к выводу подключена только одна функция, а одна и та же функция периферии обычно доступна на нескольких выводах. У STM32F405/407 номера распределены по блокам (RM0090, рисунок 26):
| AF | Периферия | AF | Периферия |
|---|---|---|---|
| AF0 | системные: JTAG и SWD, MCO, RTC_REFIN | AF8 | USART4–6 |
| AF1 | TIM1, TIM2 | AF9 | CAN1, CAN2, TIM12–14 |
| AF2 | TIM3–5 | AF10 | USB OTG FS и HS |
| AF3 | TIM8–11 | AF11 | Ethernet |
| AF4 | I2C1–3 | AF12 | FSMC, SDIO, OTG HS |
| AF5 | SPI1, SPI2 | AF13 | DCMI |
| AF6 | SPI3 | AF14 | — |
| AF7 | USART1–3 | AF15 | EVENTOUT |
После сброса все выводы подключены к AF0. Какие именно сигналы стоят на конкретном выводе, указано в таблице альтернативных функций даташита и в атласе: например, у STM32F407VE вывод PA2 — это USART2_TX на AF7, TIM2_CH3 на AF1 и ETH_MDIO на AF11. У STM32F42x/43x распределение шире: на AF5 добавлены SPI4–SPI6, на AF6 — SAI1, на AF8 — UART7 и UART8, на AF9 и AF14 — контроллер дисплея LTDC (RM0090, рисунок 27).
У STM32F1 мультиплексора нет: периферия подключается к своим выводам, как только её включили, а вывод нужно перевести в нужный режим из таблицы выше. Если выводы по умолчанию заняты или неудобны, часть функций можно перенести на другие выводы — это называется ремап и задаётся битами регистров AFIO_MAPR и AFIO_MAPR2. Например, бит USART1_REMAP переносит USART1 с PA9 и PA10 на PB6 и PB7, а поле CAN_REMAP переносит CAN с PA11 и PA12 на PB8 и PB9 (RM0008, раздел 9.3). Варианты ремапа каждого вывода показаны на страницах атласа, например у STM32F103C8, а все биты — на странице регистров AFIO.
Скорость выходов
Скорость вывода — это крутизна фронтов выходного каскада, от которой зависит, при какой частоте и ёмкости нагрузки сигнал ещё успевает доходить до уровней. Частота, с которой программа может переключать порт, от неё не зависит. У STM32F1 скорость задаётся полем MODE (DS5319, таблица 38):
| MODE | Название | Наибольшая частота | Фронт и спад, не больше |
|---|---|---|---|
| 10 | 2 МГц | 2 МГц при 50 пФ | 125 нс |
| 01 | 10 МГц | 10 МГц при 50 пФ | 25 нс |
| 11 | 50 МГц | 50 МГц при 30 пФ и VDD 2,7–3,6 В; 30 МГц при 50 пФ; 20 МГц при 50 пФ и VDD 2–2,7 В | 5 нс при 30 пФ, 8 нс при 50 пФ |
У STM32F4 — полем OSPEEDR, четыре ступени (DS8626, таблица 50; названия по RM0090, 8.4.3):
| OSPEEDR | Название | Частота при VDD > 2,7 В | Частота при VDD > 1,8 В | Частота при 10 пФ и VDD > 2,7 В | Фронт и спад при VDD > 2,7 В |
|---|---|---|---|---|---|
| 00 | Low | 4 МГц при 50 пФ | 2 МГц | 8 МГц | 100 нс при 50 пФ |
| 01 | Medium | 25 МГц при 50 пФ | 12,5 МГц | 50 МГц | 10 нс при 50 пФ |
| 10 | High | 50 МГц при 40 пФ | 25 МГц | 100 МГц | 6 нс при 40 пФ |
| 11 | Very high | 100 МГц при 30 пФ | 50 МГц | 180 МГц | 4 нс при 30 пФ |
Частоты в обеих таблицах даны для скважности 45–55 % на указанной ёмкости. На скоростях High и Very high RM0090 (раздел 9.1) рекомендует включить ячейку компенсации выводов — бит CMP_PD регистра SYSCFG_CMPCR, готовность показывает флаг READY. Она подстраивает крутизну фронтов и снижает помехи по питанию, но работает только при питании 2,4–3,6 В.
Быстрые фронты дают большие импульсы тока, электромагнитные помехи и помехи по питанию при одновременном переключении многих выходов, поэтому ST советует выбирать самую медленную скорость, при которой сигнал успевает (AN4899, раздел 7.2). Ориентир даёт определение наибольшей частоты в DS5319 (рисунок 30): сумма фронта и спада должна быть не больше двух третей периода. Светодиоду, реле или сигналу разрешения хватит самой медленной ступени, а частота выше 1 МГц требует проверки по таблицам выше с учётом ёмкости линии. На потребление скорость не влияет: динамический ток вывода равен I = CL · VDD · f и зависит только от ёмкости нагрузки, напряжения и частоты переключения (AN4899, раздел 5.1.3). Например, выход тактовой частоты 8 МГц на нагрузку 20 пФ при 3,3 В потребляет 20 пФ · 3,3 В · 8 МГц ≈ 0,53 мА.
Токи и уровни
| Параметр | STM32F103 (DS5319) | STM32F407 (DS8626) |
|---|---|---|
| Ток одного вывода, абсолютный максимум | 25 мА | 25 мА |
| Сумма токов по VDD и по VSS, абсолютный максимум | 150 мА | 240 мА |
| Уровни при токе ±8 мА (8 выводов сразу) | низкий ≤ 0,4 В, высокий ≥ VDD − 0,4 В | так же |
| Уровни при токе ±20 мА, VDD 2,7–3,6 В | низкий ≤ 1,3 В, высокий ≥ VDD − 1,3 В | так же |
| PC13, PC14, PC15 | не больше ±3 мА, до 2 МГц и 30 пФ | так же, и PI8 |
| Порог низкого уровня на входе | не выше 0,35 VDD | не выше 0,3 VDD |
| Порог высокого уровня на входе | не ниже 0,65 VDD | не ниже 0,7 VDD |
| Гистерезис триггера Шмитта | 200 мВ, у FT — 5 % VDD, не меньше 100 мВ | 10 % VDD, не меньше 200 мВ |
| Подтяжки | 30–50 кОм | 30–50 кОм, у PA10 и PB12 — 7–14 кОм |
| Ток утечки входа | ±1 мкА, у FT при 5 В — 3 мкА | так же |
| Ёмкость вывода | 5 пФ | 5 пФ |
| Наведённый ток через защитные диоды | FT: −5/+0 мА, остальные ±5 мА, сумма ±25 мА | так же |
Значения — из таблиц 7, 36 и 37 DS5319 и таблиц 12, 48 и 49 DS8626. Ток 25 мА — предел, за которым микросхему можно повредить, а не рабочий режим: уровни на выходе даташит гарантирует только при 8 и 20 мА. При этом сумма токов всех выводов вместе с потреблением самого микроконтроллера не должна выйти за 150 или 240 мА, так что десяток выводов по 20 мА одновременно — уже перебор.
PC13, PC14 и PC15 (у STM32F407 ещё PI8) питаются через ключ домена резервного питания, который пропускает не больше 3 мА. Поэтому на них нельзя вешать нагрузку, питающуюся от вывода, — например, светодиод, включённый между выводом и землёй (примечание к таблице выводов DS5319 и к таблице 49 DS8626). На плате Blue Pill светодиод стоит на PC13 и включён на втекающий ток: он подключён к питанию и зажигается, когда вывод прижимает его к земле (STM32-base) — но и втекающий ток PC13 ограничен теми же 3 мА.
Для светодиода на обычном выводе ток удобно ограничить 8 мА: тогда даташит гарантирует уровни. Если прямое напряжение светодиода около 2 В, при питании 3,3 В резистор должен быть не меньше (3,3 − 2,0) В/8 мА ≈ 160 Ом — из ряда E24 подойдёт 180 Ом. Подробнее — в калькуляторе резистора для светодиода. Белому светодиоду с прямым напряжением около 3,5 В питания 3,3 В не хватит вовсе: для него AN4899 (раздел 5.3.1) предлагает открытый сток с питанием светодиода от 5 В или внешний транзистор.
Внутренние подтяжки и I²C
Внутренние подтяжки 30–50 кОм годятся для кнопок и чтобы задать уровень неиспользуемого входа, но для шины I²C они слишком слабы. Время нарастания фронта от 0,3 до 0,7 VDD равно 0,8473 · R · C (AN4899, раздел 5.1.5): при типовых 40 кОм и ёмкости линии 100 пФ это 3,4 мкс, а спецификация I²C UM10204 допускает 1000 нс в стандартном режиме 100 кГц и 300 нс на 400 кГц. Нужны внешние резисторы — расчёт в статье об интерфейсе I²C и в калькуляторе подтягивающих резисторов. DS5319 (раздел 5.3.16) отмечает ещё одну особенность: выводы I²C STM32F103 — не «настоящий» открытый сток. Транзистор P-MOS в этом режиме выключен, но физически присутствует.
Выводы, выдерживающие 5 В
В таблице выводов даташита у каждого вывода указан тип. FT (five-volt tolerant) — вывод, к которому можно подключить сигнал 5 В; у остальных выводов вход ограничен VDD + 0,3 В. У STM32F103 и STM32F407 рабочий диапазон входа FT — от −0,3 до 5,5 В при питании 2–3,6 В и до 5,2 В при питании 2 В и ниже (DS5319, таблица 9; DS8626, таблица 14). Абсолютный максимум — VDD + 4 В. Условий несколько:
- Подтяжки выключены. Чтобы держать на выводе больше VDD + 0,3 В, внутренние подтяжки вверх и вниз должны быть отключены (примечания к таблицам 9 и 36 DS5319, 14 и 48 DS8626): иначе ток пойдёт через резистор в шину питания.
- Нет аналоговой функции. В аналоговом режиме вывод не выдерживает 5 В (RM0090, 8.3.12), а пока к нему подключён вход АЦП, напряжение не должно превышать VDDA или VREF+ больше чем на 0,3 В (AN4899, раздел 5.2.2).
- Микроконтроллер запитан. Без питания, когда VDD = 0, на вывод FT нельзя подавать больше 3,6 В (AN4899, разделы 5.2.2 и 6.3). Если внешняя схема с питанием 5 В может включиться раньше STM32, ограничьте ток в вывод резистором или стабилитроном.
- Вход, а не двухтактный выход. AN4899 оговаривает, что 5 В допустимы на выводе в режиме входа. В той же заметке (раздел 5.3.3) STM32 работает на шине I²C с подтяжкой к 5 В: выводы I²C — с открытым стоком, транзистор P-MOS выключен, и к 5 В линию тянет внешний резистор.
Так STM32 с питанием 3,3 В напрямую работает с 5-вольтовыми устройствами: вход FT принимает их уровни, а высокий уровень выхода STM32 не ниже 2,4 В при токе 8 мА (таблица 37 DS5319, таблица 49 DS8626) и понятен любому входу с порогами ТТЛ — 0,8 и 2,0 В. У входа КМОП порог высокого уровня — около двух третей питания (AN4899, раздел 5.1.4), при 5 В это 3,3 В, а гарантированный высокий уровень STM32 при 8 мА — VDD − 0,4 = 2,9 В. Такому входу нужен открытый сток с подтяжкой к 5 В или преобразователь уровней.
Внешние прерывания
Любой вывод может вызвать прерывание через контроллер EXTI. Линий для выводов шестнадцать: линия n обслуживает вывод с номером n, а какой порт к ней подключён — A, B, C и так далее, — выбирается в регистрах AFIO_EXTICR у STM32F1 и SYSCFG_EXTICR у STM32F4. Отсюда ограничение: PA0 и PB0 не могут одновременно вызывать прерывания, а PA0 и PB1 — могут. Вывод при этом остаётся в режиме входа (RM0008, 9.1.3; RM0090, 8.3.8). Минимальная длительность импульса, который заметит EXTI, — 10 нс (DS5319, таблица 38; DS8626, таблица 50). Регистры описаны на страницах EXTI STM32F1 и STM32F4, а приоритеты прерываний считает калькулятор NVIC.
Блокировка настроек: LCKR
Регистр LCKR замораживает настройки выбранных выводов до следующего сброса: у STM32F1 — биты CRL и CRH, у STM32F4 — MODER, OTYPER, OSPEEDR, PUPDR, AFRL и AFRH (RM0090, 8.3.6). Данные — ODR и BSRR — продолжают работать. Блокировка защищает от ошибочного кода, который мог бы перенастроить, например, вывод управления силовым ключом. Она включается последовательностью записей в бит LCKK (бит 16) с одинаковой маской выводов в битах 0–15: запись 1, запись 0, запись 1, затем чтение — и необязательное второе чтение, которое покажет LCKK = 1, если блокировка сработала. Ошибка в последовательности её отменяет. Запись выполняется только целым словом.
/* Lock the configuration of PA2 and PA5 until the next reset */
uint32_t key = GPIO_LCKR_LCKK | GPIO_LCKR_LCK2 | GPIO_LCKR_LCK5;
GPIOA->LCKR = key;
GPIOA->LCKR = key & ~GPIO_LCKR_LCKK;
GPIOA->LCKR = key;
(void)GPIOA->LCKR;
if (GPIOA->LCKR & GPIO_LCKR_LCKK) {
/* locked */
}
То же делает функция HAL_GPIO_LockPin.
Неиспользуемые выводы
Неподключённый вход в цифровом режиме ловит наводки, его триггер Шмитта переключается случайным образом и тратит ток. AN4899 (разделы 6.1 и 7.1) предлагает либо перевести такие выводы в аналоговый режим — у STM32F4 это MODER = 11, у STM32F1 — CNF = 00 и MODE = 00, — либо включить подтяжку, либо подключить вывод к земле на плате. Если устройство чувствительно к электростатике, надёжнее выход с низким уровнем. Выход с открытым стоком без нагрузки тоже лучше держать в нуле, а не в высокоимпедансном состоянии (раздел 6.4). Перед уходом в режимы пониженного потребления все линии нужно привести к определённым уровням — выходом или подтяжкой (раздел 7.4).
Примеры на CMSIS
Кнопка и светодиод на STM32F103. Светодиод на PC13 включён между питанием и выводом, кнопка на PA0 замыкает вывод на землю, поэтому у входа включена подтяжка вверх.
#include "stm32f1xx.h"
int main(void)
{
/* Clock for ports A and C */
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
/* PC13: general-purpose push-pull output, 2 MHz (MODE13 = 10, CNF13 = 00) */
GPIOC->CRH = (GPIOC->CRH & ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13)) | GPIO_CRH_MODE13_1;
/* PA0: input with pull-up (MODE0 = 00, CNF0 = 10, ODR0 = 1 selects the pull-up) */
GPIOA->CRL = (GPIOA->CRL & ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0)) | GPIO_CRL_CNF0_1;
GPIOA->BSRR = GPIO_BSRR_BS0;
for (;;) {
if (GPIOA->IDR & GPIO_IDR_IDR0)
GPIOC->BSRR = GPIO_BSRR_BS13; /* released: PC13 high, LED off */
else
GPIOC->BSRR = GPIO_BSRR_BR13; /* pressed: PC13 low, LED on */
}
}
Выход и альтернативная функция на STM32F407: PA5 — обычный выход, PA2 — передатчик USART2 на AF7.
#include "stm32f4xx.h"
void gpio_init(void)
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
/* PA5: push-pull output, low speed, no pull (MODER5 = 01) */
GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODER5) | GPIO_MODER_MODER5_0;
/* PA2: USART2_TX on AF7, push-pull, medium speed */
GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODER2) | GPIO_MODER_MODER2_1;
GPIOA->OSPEEDR = (GPIOA->OSPEEDR & ~GPIO_OSPEEDR_OSPEED2) | GPIO_OSPEEDR_OSPEED2_0;
GPIOA->AFR[0] = (GPIOA->AFR[0] & ~GPIO_AFRL_AFSEL2) | (7U << GPIO_AFRL_AFSEL2_Pos);
GPIOA->BSRR = GPIO_BSRR_BS5; /* PA5 high */
GPIOA->BSRR = GPIO_BSRR_BR5; /* PA5 low */
}
Каждая запись меняет только поля своего вывода, поэтому выводы отладчика PA13 и PA14 остаются на месте. Без включённого тактирования порта его регистры не настроятся: у STM32F1 порты тактируются от шины APB2 (биты IOPxEN в RCC_APB2ENR), у STM32F4 — от AHB1 (биты GPIOxEN в RCC_AHB1ENR). В HAL то же делают функции HAL_GPIO_Init, HAL_GPIO_WritePin и HAL_GPIO_ReadPin, а скорость задаётся константами GPIO_SPEED_FREQ_LOW, MEDIUM, HIGH и у STM32F4 — VERY_HIGH. У STM32F1 они соответствуют режимам 2, 10 и 50 МГц, то есть кодам MODE 10, 01 и 11.
Частые ошибки
- Не включено тактирование порта — запись в регистры не действует, а вывод остаётся входом.
- Перезаписан регистр порта A целиком — выводы PA13 и PA14 теряют функцию SWD, отладчик не подключается. Восстановить связь обычно помогает подключение с удержанием сброса.
- Нагрузка на PC13–PC15 — больше 3 мА эти выводы не дают, и источником тока для светодиода служить не могут.
- Внутренняя подтяжка вместо внешней на I²C — фронты в несколько микросекунд, шина работает нестабильно или не работает вовсе.
- 5 В на вывод не FT, на вывод с включённой подтяжкой или на незапитанный микроконтроллер — ток через защитные диоды; предельный наведённый ток — 5 мА на вывод.
- Переключение одного вывода через ODR в основном цикле и в прерывании — изменения теряются; используйте BSRR.
- Вход АЦП не в аналоговом режиме — оба руководства требуют для входов АЦП и выходов ЦАП аналоговый режим (RM0008, 9.1.11; RM0090, 8.3.2).
Частые вопросы
Какой ток можно брать с вывода STM32?
Абсолютный максимум — 25 мА на вывод, а сумма токов всех выводов вместе с потреблением самого микроконтроллера не должна превышать 150 мА у STM32F103 и 240 мА у STM32F407 (DS5319, таблица 7; DS8626, таблица 12). Нормированные уровни даташит гарантирует при ±8 мА: низкий не выше 0,4 В, высокий не ниже VDD − 0,4 В; при ±20 мА — с запасом 1,3 В. Выводы PC13, PC14 и PC15 питаются через ключ и отдают не больше 3 мА.
Можно ли подавать 5 В на вход STM32?
Только на выводы с пометкой FT в таблице выводов даташита. У STM32F103 и STM32F407 вход FT выдерживает от −0,3 до 5,5 В при питании 2–3,6 В, если на выводе выключены внутренние подтяжки и вывод не в аналоговом режиме. Пока микроконтроллер не запитан, по AN4899 на вывод нельзя подавать больше 3,6 В. Обычные выводы выдерживают не больше VDD + 0,3 В.
Чем отличается двухтактный выход от открытого стока?
Двухтактный (push-pull) выход сам формирует оба уровня: единица включает транзистор P-MOS к VDD, ноль — N-MOS к земле. Открытый сток включает только N-MOS: ноль тянет линию к земле, единица отпускает её, и высокий уровень создаёт внешний резистор. Открытый сток нужен для шин с несколькими передатчиками, как I²C, и для подтяжки к другому напряжению.
Что значит скорость вывода 2, 10 и 50 МГц у STM32F1?
Это не частота переключения порта, а крутизна фронтов выходного каскада. По DS5319 (таблица 38) в режиме 2 МГц фронт длится до 125 нс, в режиме 10 МГц — до 25 нс, в режиме 50 МГц — 5–12 нс в зависимости от нагрузки. Чем быстрее фронт, тем сильнее импульсы тока и помехи, поэтому ST советует выбирать самую медленную скорость, которой хватает для сигнала.
Почему после перенастройки порта A пропадает отладчик?
Выводы PA13 и PA14 после сброса работают как SWDIO и SWCLK. У STM32F4 это видно в регистре GPIOA_MODER: после сброса в нём 0xA800 0000, то есть PA13, PA14 и PA15 в режиме альтернативной функции. Если записать в MODER значение целиком, а не изменить только нужные поля, SWD отключится. Меняйте регистр чтением-изменением-записью.
Как переключить вывод STM32 атомарно?
Записью в регистр BSRR: единица в бите n (0–15) устанавливает вывод n, единица в бите n + 16 сбрасывает его, нули ничего не меняют. Это одна запись по шине, прерывание её не разорвёт, и остальные выводы порта не затрагиваются. Так работают HAL_GPIO_WritePin и LL_GPIO_SetOutputPin. Если в одной записи заданы и установка, и сброс одного вывода, побеждает установка.
Источники
- STMicroelectronics. RM0008 Rev 21. Reference manual: STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx — 9.1 — режимы, структура вывода (рисунки 13–18), таблицы 20–21 — коды CNF и MODE, состояние после сброса и выводы JTAG; 9.1.11 — настройка выводов для периферии (таблицы 22–33); 9.2 — регистры GPIO, доступ только словами, приоритет установки в BSRR; 9.3 — PC14/PC15 и PD0/PD1 как GPIO, ремап; 9.4 — тактирование AFIO, поле SWJ_CFG; 31.4.4 — освобождение выводов JTAG
- STMicroelectronics. RM0090 Rev 22. Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439 — 8.3 — режимы и таблица 36, выводы отладчика после сброса, мультиплексор AF0–AF15 (рисунок 26), BSRR, блокировка LCKR, аналоговый режим без устойчивости к 5 В; 8.4 — значения MODER, OSPEEDR и PUPDR после сброса; 9.1 — ячейка компенсации
- STMicroelectronics. DS5319 Rev 20. STM32F103x8, STM32F103xB datasheet — таблицы 6, 7 и 9 — предельные напряжения и токи, рабочий диапазон входов FT; таблица 35 — наведённый ток; таблица 36 — пороги, гистерезис, утечка, подтяжки; таблица 37 — выходные уровни при 8 и 20 мА; таблица 38 и рисунок 30 — частоты и фронты для MODE; ограничения PC13–PC15; выводы I²C — не «настоящий» открытый сток
- STMicroelectronics. DS8626 Rev 12. STM32F405xx, STM32F407xx datasheet — таблицы 11, 12 и 14 — предельные напряжения и токи, рабочий диапазон входов FT; таблица 48 — пороги, гистерезис, подтяжки (PA10 и PB12 — 7–14 кОм); таблица 49 — выходные уровни; таблица 50 — частоты и фронты для OSPEEDR, ячейка компенсации выше 50 МГц
- STMicroelectronics. AN4899 Rev 4. Guidelines for GPIO hardware settings and low-power consumption on STM32 MCUs, 2026 — 5.1.3 — динамический ток C·V·F, скорость на него не влияет; 5.1.4 — пороги КМОП и ТТЛ; 5.1.5 — время нарастания 0,8473·R·C; 5.2.2 — выводы FT: до VDD + 3,6 В и не выше 5,5 В, без питания — не выше 3,6 В; 5.3.3 — шина I²C 5 В; 6.1–6.6 — неиспользуемые выводы, открытый сток без нагрузки, подтяжки выводов отладчика; 7.1–7.4 — аналоговый режим для неиспользуемых выводов, выбор скорости
- NXP Semiconductors. UM10204: I2C-bus specification and user manual, Rev. 7.0, 1 October 2021 — наибольшее время нарастания фронта: 1000 нс в Standard-mode, 300 нс в Fast-mode
- STM32-base. STM32F103C8T6 Blue Pill — светодиод на PC13, включённый на втекающий ток
- STMicroelectronics. STM32CubeF1 и STM32CubeF4: драйверы HAL и LL, заголовки CMSIS (репозитории stm32f1xx-hal-driver, stm32f4xx-hal-driver, cmsis-device-f1, cmsis-device-f4) — HAL_GPIO_WritePin, HAL_GPIO_TogglePin и HAL_GPIO_LockPin в stm32f1xx_hal_gpio.c и stm32f4xx_hal_gpio.c; LL_GPIO_SetOutputPin и LL_GPIO_ResetOutputPin; константы GPIO_SPEED_FREQ_x; имена битов в stm32f103xb.h и stm32f407xx.h
Нашли ошибку?
Смотрите также
- STM32Распиновки по корпусам, альтернативные функции, похожие по выводам МК
- STM32F1Cortex-M3: F100, F101, F102, F103, F105/107 — линейки и распиновки
- STM32F4Cortex-M4 с FPU: от F401 и F411 до F429 и F469 — линейки и распиновки
- Cortex-M3Регистры, карта памяти, bit-banding, NVIC, SysTick, MPU, старт, пример
- I²CSDA и SCL, START/STOP, ACK, адреса, скорости, расчёт подтяжек
- Резистор для светодиодаНоминал и мощность гасящего резистора
- Подтягивающие резисторы I²CДиапазон Rp по напряжению, скорости и ёмкости шины