95а. Преобразователи уровней: транзистор с подтяжками, TXB и TXS — почему модуль не работает с I²C и длинным проводом
В 95.6 разобран ключ на полевом транзисторе: затвор на 3,3 В, по подтяжке с каждой стороны, и линия I²C ходит в обе стороны без вывода направления. Но на рынке модулей таких ключей меньше, чем плат на микросхемах с «автоматическим» направлением — восьмиканальных TXB0108 и TXS0108E. Внешне они одинаковые: восемь линий, две ножки питания, вывод OE. Ведут себя по-разному, и именно здесь рождаются жалобы «датчик I²C через модуль не отвечает» и «по проводу полметра SPI работает, по метру — мусор».
Здесь: три устройства преобразователя и что каждое умеет; фронты ключа на транзисторе при разных подтяжках и ёмкостях; модель буфера со слабым выходом и ускорителями фронта, как у TXB, — на шине I²C и на проводе; до какой частоты доходит каждый вариант; когда преобразователь не нужен вовсе, потому что вывод STM32 терпит 5 В; таблица выбора для I²C, SPI, UART и 1-Wire.
Опоры: DocID13587 Rev 17 (выводы F103x8/xB и их отметка FT, предел напряжения на выводе FT, оговорка о подтяжках), DS8626 Rev 9 (то же для F407), RM0008 (DocID13902 Rev 17, режимы вывода F1: подтяжки только у входа). Пределы фронта I²C 1000 и 300 нс и пороги 0,3 и 0,7 питания — из 95.3 и раздела 17. Принцип TXB и TXS — по описаниям в заметках производителя (TI SCEA043, SCEA044, SCEA054), пересказ; с их даташитами раздел не сверялся, поэтому чисел производителя — выходного сопротивления, тока ускорителя, длительности одновибратора, допустимой подтяжки — здесь нет. Все модели — свои, в ngspice 39; их параметры названы ниже и выбраны для иллюстрации механизма, а не по паспорту микросхем.
Как это называется в документации
Оригинал Перевод level translator, level shifter преобразователь уровней auto-direction sensing автоматическое определение направления edge-rate accelerator, one-shot ускоритель фронта, одновибратор pass transistor проходной ключ body diode внутренний диод транзистора open-drain / push-pull открытый сток / двухтактный выход direction control (DIR) вывод направления output enable (OE) разрешение выходов five-volt tolerant (FT) вывод, терпимый к 5 В
95а.1 Три устройства под одним названием
Ключ на транзисторе. Один N-канальный полевой транзистор на линию (чаще всего BSS138) и две подтяжки — к 3,3 и к 5 В. Сам транзистор никуда ничего не тянет вверх: он только передаёт ноль с одной стороны на другую. Единицу на каждой стороне делает подтяжка, поэтому фронт вверх — это заряд ёмкости через резистор, как на любой шине с открытым стоком (95.3).
Буфер со слабым выходом и ускорителями (TXB). Внутри — два встречных буфера. Каждый ведёт свою сторону к своему питанию, но через большое выходное сопротивление: любой внешний выход его перебарывает, и так определяется направление. Чтобы фронт не был медленным, на смену уровня срабатывает одновибратор и на короткое время подключает к линии сильные ключи — к питанию на фронте вверх, к земле на фронте вниз. Такой буфер рассчитан на двухтактные линии: SPI, UART, просто сигналы. Подтяжка снаружи спорит со слабым выходом, длинный провод — с одновибратором (95а.3, 95а.4).
Ключ с подтяжками и ускорителями (TXS). По принципу это тот же ключ на транзисторе: проходной транзистор между сторонами, подтяжки уже внутри, а на фронт вверх — ускорители. Поэтому TXS годится для открытого стока — I²C, 1-Wire, а её подтяжки складываются с внешними и с подтяжками модуля (95.4). Отдельной модели TXS в разделе нет: на I²C она ведёт себя как ключ из 95а.2, только с более быстрым фронтом вверх.
Двухтактный буфер с выводом направления. Обычный буфер с двумя питаниями: направление задаёт вывод DIR, выход сильный и в нуле, и в единице. Ничего не определяет сам, поэтому ничему и не мешает; для I²C не годится — линия там двунаправленная и с открытым стоком.
95а.2 Ключ на транзисторе: фронты и уровни
Модель: своя модель небольшого N-канального транзистора — порог 1,3 В, внутренний диод сток-исток, малые ёмкости; выводы микроконтроллера и датчика — ключи с открытым стоком на 25 Ом. Сторона микроконтроллера — 3,3 В, сторона модуля — 5 В, подтяжки одинаковые с обеих сторон, ёмкости тоже. Сначала линию прижимает микроконтроллер, потом отпускает; затем то же делает датчик со своей стороны. Меряется фронт противоположной стороны от 0,3 до 0,7 её питания — как в стандарте I²C.
.include fet.inc
.param rl=4.7k rh=4.7k ca=50p cb=50p vl=3.3
VL l 0 DC {vl}
VH h 0 DC 5
Rl l a {rl}
Rh h b {rh}
Ca a 0 {ca}
Cb b 0 {cb}
M1 b l a MSS
Sa a 0 ka 0 SWD
Sb b 0 kb 0 SWD
Vka ka 0 PULSE(0 1 2u 1n 1n 30u 1)
Vkb kb 0 PULSE(0 1 62u 1n 1n 30u 1)
.tran 1n 122u 0 2n
| Ёмкость каждой стороны | Подтяжки | Фронт на стороне 5 В | Фронт на стороне 3,3 В |
|---|---|---|---|
| 50 пФ | 10 кОм | 577 нс | 384 нс |
| 50 пФ | 4,7 кОм | 269 нс | 185 нс |
| 50 пФ | 2,2 кОм | 124 нс | 89 нс |
| 200 пФ | 10 кОм | 1973 нс | 1271 нс |
| 200 пФ | 4,7 кОм | 920 нс | 614 нс |
| 200 пФ | 2,2 кОм | 427 нс | 295 нс |
Сторона 5 В растёт медленнее, чем одна цепочка RC: для 10 кОм и 50 пФ формула из 95.3 даёт 424 нс, а модель — 577. Пока сторона 3,3 В не выше затвора минус порог, транзистор открыт, и подтяжка 5 В заряжает обе ёмкости сразу; дальше сторона 5 В тянется одна. Сторона 3,3 В, наоборот, растёт быстрее своей RC — ей в начале помогает подтяжка 5 В.
Ноль проходит хорошо: на противоположной стороне от 0,02 до 0,10 В (больше при сильной подтяжке), фронт вниз — от 5,6 до 19,0 нс. Если датчик тянет к нулю сторону 5 В, транзистор сначала открывает его же внутренний диод, а дальше — канал.
Что это значит для I²C. На 100 кГц (фронт до 1000 нс) при 50 пФ годится любая подтяжка из таблицы, при 200 пФ — 4,7 и 2,2 кОм. На 400 кГц (до 300 нс) при 50 пФ — 4,7 и 2,2 кОм, а при 200 пФ не годится ни одна: даже с 2,2 кОм сторона 5 В растёт 427 нс. Считать надо по стороне 5 В — она медленнее.
Та же ячейка с микроконтроллером на 1,8 В (и затвором на 1,8 В): ноль на стороне 5 В 0,044 В, фронт 234 нс при 4,7 кОм и 50 пФ. Модель с порогом 1,3 В здесь работает, но запас «затвор минус порог» всего 0,5 В: порог своего транзистора смотрите в его даташите: если он близок к 1,8 В, ключ откроется плохо или не откроется вовсе.
95а.3 Буфер с ускорителями на I²C: подтяжка спорит со слабым выходом
Модель одного канала по принципу TXB — своя и упрощённая, с параметрами для иллюстрации: слабый выход 4 кОм, ускоритель — ключ 30 Ом на время около 10 нс, порог каждой стороны — половина её питания:
.subckt TXBCH a b va vb params: rw=4k racc=30 tos=14.4n
* логическое состояние стороны с задержкой входа 0,5 нс
Bsa sa0 0 V = 0.5*(1+tanh((V(a)-V(va)/2)/0.05))
Rsa sa0 sa 1k
Csa sa 0 0.5p
Bsb sb0 0 V = 0.5*(1+tanh((V(b)-V(vb)/2)/0.05))
Rsb sb0 sb 1k
Csb sb 0 0.5p
* встречные буферы со слабым выходом
Bdb nb 0 V = V(vb)*V(sa)
Rwb nb b {rw}
Bda na 0 V = V(va)*V(sb)
Rwa na a {rw}
* одновибраторы: сглаженная копия состояния отстаёт на tos; разница больше 0,5 — ускоритель включён
Efa fa0 0 sa 0 1
Rfa fa0 fa 1k
Cfa fa 0 {tos/1000}
Efb fb0 0 sb 0 1
Rfb fb0 fb 1k
Cfb fb 0 {tos/1000}
* фронт на любой стороне включает ускорители обеих сторон
Bup up 0 V = 0.5*(1+tanh((max(V(sa)-V(fa),V(sb)-V(fb))-0.5)/0.02))
Bdn dn 0 V = 0.5*(1+tanh((max(V(fa)-V(sa),V(fb)-V(sb))-0.5)/0.02))
Bua 0 a I = (V(va)-V(a))/{racc}*V(up)
Bda2 a 0 I = V(a)/{racc}*V(dn)
Bub 0 b I = (V(vb)-V(b))/{racc}*V(up)
Bdb2 b 0 I = V(b)/{racc}*V(dn)
Dpa a va DCL
Dna 0 a DCL
Dpb b vb DCL
Dnb 0 b DCL
.model DCL D(IS=1e-14 N=1 RS=2)
.ends
Ставим её на шину I²C: микроконтроллер с открытым стоком на стороне 3,3 В, внешние подтяжки одного номинала с обеих сторон (как на модуле датчика и на плате микроконтроллера). Микроконтроллер прижимает свою сторону к нулю — что получает датчик:
| Внешние подтяжки | Ноль на стороне 5 В | После того как датчик прижал свою сторону: ноль на стороне 3,3 В | Линия после отпускания |
|---|---|---|---|
| нет (1 МОм) | 0,02 В | 0,01 В | осталась в нуле |
| 47 кОм | 0,39 В | 0,26 В | осталась в нуле |
| 10 кОм | 1,43 В | 0,94 В | осталась в нуле |
| 4,7 кОм | 2,30 В | 1,52 В | осталась в нуле: 2,31 и 1,52 В |
| 2,2 кОм | 3,23 В | 2,13 В | вернулась: 5,00 и 3,30 В |
Механизм простой: одновибратор прижимает линию лишь на время импульса, а потом ноль держит слабый выход против внешней подтяжки — получается делитель. Со слабой подтяжкой ноль чистый, с 10 кОм он уже на краю порогов (1,5 В для стороны 5 В и 0,99 В для 3,3 В — 0,3 питания), с 4,7 кОм — не ниже 2,30 В, с 2,2 кОм нуля нет вовсе: 3,23 В для датчика — единица.
Хуже другое — последний столбец. Открытый сток сам единицу не делает: он только отпускает линию. А буфер помнит ноль и держит его своим слабым выходом на обеих сторонах. Вернуть линию в единицу может только подтяжка, которая перетянет делитель через порог буфера, — в модели это удалось лишь с 2,2 кОм, когда нуля уже нет. При всех остальных подтяжках шина после первого же нуля повисла. Окна, где работают и ноль, и единица, у такого буфера на открытом стоке нет.
Числа зависят от параметров модели, вывод — нет: буфер со слабым выходом рассчитан на двухтактные выходы, которые сами делают и ноль, и единицу. Модули датчиков I²C приносят свои подтяжки (95.4) — поэтому TXB на I²C не ставят.
95а.4 Буфер с ускорителями на проводе
Теперь сторона 5 В идёт по проводу к приёмнику. Провод — линия без потерь с 70 пФ и 0,5 мкГн на метр: 84,5 Ом и 5,92 нс на метр. На конце — вход 10 пФ с диодами на питание и землю. Микроконтроллер двухтактным выходом даёт меандр 1 МГц, два периода — четыре фронта. Считаем, сколько раз приёмник перешёл через 2,5 В:
| Провод | Модель буфера с ускорителями | Двухтактный буфер | Двухтактный + 56 Ом |
|---|---|---|---|
| 0,25 м | 4 переключения | 4 | 4 |
| 1 м | 296 | 4 | 4 |
| 2 м | 159 | 4 | 4 |
На 0,25 м все три чистые. На метре модель буфера с ускорителями срывается в колебания: ускоритель бросает в провод фронт, отражение возвращается через удвоенную задержку и переводит сторону через порог; одновибратор срабатывает уже в обратную сторону, и так без конца. С 0,6 до 0,95 мкс, когда вход давно стоит в единице, приёмник переключился 52 раза — 74,3 МГц; на 2 м — 28 раз, 40,0 МГц. Ускоритель стороны 3,3 В при этом спорит с выходом микроконтроллера: сам вход буфера проседает до 1,76 В (на 2 м — до 1,77 В).
Двухтактный буфер сбоев не даёт, но звенит: выброс до 5,93 В и провал до −0,93 В — их срезают только диоды входа. Резистор последовательного согласования 56 Ом (вместе с выходом 25 Ом это почти волновое сопротивление провода, раздел 160) убирает звон: на метре и двух максимум 5,12 В, минимум не ниже −0,12 В, на 0,25 м — 5,05 и −0,05 В.
Насколько длинный провод выдержит настоящий TXB, модель не скажет — это зависит от его ускорителей. Скажет другое: автоматический буфер с ускорителями — это петля с положительной обратной связью через провод, и на длинной линии он может сорваться в генерацию. Двухтактный буфер с направлением такой петли не имеет.
95а.5 Скорость
Меандр с двухтактного выхода микроконтроллера (3,3 В) проходит на сторону 5 В с нагрузкой 50 пФ — вход модуля и короткий провод. Считаем, сколько из 16 фронтов (восемь периодов) доходят полностью — ниже 1,5 и выше 3,5 В:
| Частота | Ключ, 10 кОм | Ключ, 2,2 кОм | Модель с ускорителями | Двухтактный |
|---|---|---|---|---|
| 100 кГц | 16 | 16 | 16 | 16 |
| 400 кГц | 16 | 16 | 16 | 16 |
| 1 МГц | 16 | 16 | 16 | 16 |
| 2 МГц | 0 | 16 | 16 | 16 |
| 4 МГц | 0 | 16 | 16 | 16 |
| 10 МГц | 0 | 0 | 16 | 16 |
| 20 МГц | 0 | 0 | 16 | 16 |
| 40 МГц | 0 | 0 | 14 | 16 |
Ключ с 10 кОм на стороне 5 В — до 1 МГц, с 2,2 кОм — до 4 МГц: фронт вверх здесь всегда заряд ёмкости через подтяжку. Для SPI на несколько мегагерц ключ не годится. Граница модели с ускорителями зависит от её параметров; двухтактный буфер (выход 25 Ом в модели) прошёл весь список.
95а.6 Без преобразователя: выводы, терпимые к 5 В
Самый надёжный преобразователь — тот, которого нет. Вывод с отметкой FT терпит на входе до VDD + 4 В (DocID13587 и DS8626, таблица предельных значений) — при поданном питании и с выключенными встроенными подтяжками (общие оговорки — в 8.1). Отсюда два приёма:
- сигнал с 5 В внутрь (MISO, RX от пятивольтового модуля) — прямо на вывод FT, без делителя и без микросхемы;
- линия с открытым стоком к 5 В (I²C, 1-Wire, любой сигнал наружу) — вывод FT в режиме открытого стока, подтяжка прямо к 5 В. Модуль на 5 В увидит полные 5 В в единице, а фронт считается по 95.3.
Выводы шин из даташитов:
| Выводы | Шина | F103 | F407 |
|---|---|---|---|
| PB6, PB7 | I2C1 | FT | FT |
| PB8, PB9 | I2C1 после переназначения | FT | FT |
| PB10, PB11 | I2C2 | FT | FT |
| PA9, PA10 | USART1 | FT | FT |
| PA2, PA3 | USART2 | нет | FT |
| PA5, PA6, PA7 | SPI1 | нет | PA5 — только 3,3 В (TTa), PA6, PA7 — FT |
| PB13, PB14, PB15 | SPI2 | FT | FT |
У F103 выводы, заведённые на АЦП, 5 В не терпят: SPI1 и USART2 на пятивольтовый модуль — только через преобразователь, а SPI2 и USART1 — напрямую. У F407 нетерпим SCK первого SPI на PA5; SPI1 на PB3–PB5 обходится без преобразователя.
Свой вывод с открытым стоком к 5 В — например, PB8 у обоих семейств:
#if defined(STM32F10X_MD)
/* F103: MODE = 10 (выход, 2 МГц), CNF = 01 (открытый сток). Подтяжки у F1 включаются только в режиме входа. */
void od5v_pin(GPIO_TypeDef *port, uint32_t pin)
{
volatile uint32_t *cr = (pin < 8u) ? &port->CRL : &port->CRH;
uint32_t sh = (pin & 7u) * 4u;
*cr = (*cr & ~(0xFu << sh)) | (0x6u << sh);
}
_Static_assert((GPIO_CRL_MODE0_1 | GPIO_CRL_CNF0_0) == 0x6u, "F103: MODE=10, CNF=01");
_Static_assert((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) == 0xFu, "F103: четыре бита на вывод");
#else
/* F407: выход, открытый сток, низкая скорость, встроенные подтяжки выключены —
* с ними вывод FT не держит напряжение выше VDD + 0,3 В. */
void od5v_pin(GPIO_TypeDef *port, uint32_t pin)
{
port->MODER = (port->MODER & ~(3u << (pin * 2u))) | (1u << (pin * 2u));
port->OTYPER |= 1u << pin;
port->OSPEEDR &= ~(3u << (pin * 2u));
port->PUPDR &= ~(3u << (pin * 2u));
}
_Static_assert(GPIO_MODER_MODER0_0 == 1u && GPIO_OTYPER_OT_0 == 1u && GPIO_PUPDR_PUPDR0 == 3u
&& GPIO_OSPEEDER_OSPEEDR0 == 3u, "F407: поля MODER, OTYPER, OSPEEDR, PUPDR");
#endif
/* Отпустить линию: единицу до 5 В даст внешняя подтяжка. */
void od5v_release(GPIO_TypeDef *port, uint32_t pin)
{
port->BSRR = 1u << pin;
}
/* Прижать линию к нулю. */
void od5v_low(GPIO_TypeDef *port, uint32_t pin)
{
port->BSRR = 1u << (pin + 16u);
}
/* Прочитать линию: вход читается и в режиме выхода с открытым стоком. */
uint32_t od5v_read(GPIO_TypeDef *port, uint32_t pin)
{
return (port->IDR >> pin) & 1u;
}
У F1 отдельного регистра подтяжек нет: по RM0008 они подключаются только
в режиме входа, так что открытый сток уже «без подтяжек». У F407 их надо
выключить явно — PUPDR. Для шины I²C те же выводы в режиме
альтернативной функции настраиваются кодом из 95.3. Код собирается для
F103 и F407 без предупреждений: 64 и 86 байт.
Чего FT не решает: выход 3,3 В в двухтактном режиме даёт пятивольтовому входу с порогом 3,5 В слишком мало (62.5). Для быстрого сигнала наружу — двухтактный буфер; для медленного — открытый сток с подтяжкой к 5 В.
Что ставить:
| Линия | Что ставить | Чего избегать |
|---|---|---|
| I²C | вывод FT с подтяжками к 5 В; иначе ключ на транзисторе или TXS, фронт — по 95а.2 | буфер со слабым выходом (TXB): подтяжки модулей его перебарывают |
| SPI | двухтактный буфер с DIR, по каналу на линию (MISO — обратным каналом или прямо на FT); на проводе — 33…56 Ом последовательно | ключ на транзисторе выше 1–4 МГц; буфер с ускорителями на длинном проводе |
| UART | RX от 5 В — прямо на FT; TX наружу — двухтактный буфер или вход 5 В с порогами ТТЛ (62.5) | подтяжки на линии при буфере со слабым выходом |
| 1-Wire | вывод FT с подтяжкой к 5 В; иначе ключ на транзисторе | буфер со слабым выходом: на 1-Wire обязательна подтяжка |
95а.7 Грабли
Датчик I²C через восьмиканальный модуль не отвечает, на осциллографе ноль висит около половины питания. На модуле буфер со слабым выходом (TXB), а выходы I²C — с открытым стоком. В модели с подтяжками 4,7 кОм ноль не опускается ниже 2,30 В, а после отпускания линия так и остаётся внизу. Нужен ключ на транзисторе, TXS или вывод FT.
С модулем на TXS шина работает, но вывод не держит ноль. Встроенные подтяжки TXS стоят параллельно подтяжкам модуля датчика и платы микроконтроллера: ток в нуле складывается, как в 95.4. Лишние подтяжки снять.
SPI через модуль работает на макетке, а на проводе в метр — мусор. Буфер с ускорителями на длинной линии срывается в колебания: в модели на метре вместо четырёх переключений приёмника — 296. Двухтактный буфер с направлением и резистор 33…56 Ом у выхода.
Ключ на транзисторе «не успевает» на SPI. Фронт вверх — это заряд ёмкости через подтяжку: при 10 кОм и 50 пФ — до 1 МГц, при 2,2 кОм — до 4 МГц. Для быстрых двухтактных линий ключ не предназначен.
Фронт I²C считали по формуле — на 400 кГц всё равно сбои. Через ключ сторона 5 В растёт медленнее одиночной RC: 577 нс против 424 при 10 кОм и 50 пФ. Мерить и считать надо по стороне 5 В.
Ключ на транзисторе для 1,8 В не работает. Затвор на 1,8 В, а порог транзистора по даташиту близок к этому напряжению: канал открывается плохо или не открывается. Транзистор с низким порогом — или вывод FT.
Модуль на TXB/TXS, вывод OE оставлен в воздухе. OE выключает все выходы; висящий вход даёт случайное состояние. OE — к питанию стороны, к которой его относит даташит, или к выводу микроконтроллера.
Подтяжка к 5 В на выводе без FT. PA5–PA7 у F103 и PA5 у F407 5 В не терпят. Сверить вывод по таблице даташита, а не по «соседнему, который работал».
95а.8 Итоги
- Три устройства: ключ на транзисторе (открытый сток), буфер со слабым выходом и ускорителями (TXB, двухтактные линии), ключ с подтяжками и ускорителями (TXS, открытый сток); плюс двухтактный буфер с DIR.
- Ключ: ноль 0,02–0,10 В, фронт вниз 5,6–19,0 нс; фронт вверх на стороне 5 В — 577 нс при 10 кОм и 50 пФ, 427 нс при 2,2 кОм и 200 пФ: 400 кГц на 200 пФ не проходит.
- Модель буфера со слабым выходом на I²C: ноль на стороне 5 В — 0,39 В при 47 кОм, 1,43 В при 10 кОм, 2,30 В при 4,7 кОм, 3,23 В при 2,2 кОм; после отпускания линия вернулась в единицу только с 2,2 кОм.
- На проводе 1 м модель с ускорителями генерирует 74,3 МГц (296 переключений вместо 4), на 2 м — 40,0 МГц; двухтактный буфер — 4 переключения, с 56 Ом выброс не выше 5,12 В.
- Частота на 50 пФ: ключ с 10 кОм — до 1 МГц, с 2,2 кОм — до 4 МГц; двухтактный буфер — весь список до 40 МГц.
- Выводы FT терпят VDD + 4 В: I2C1, I2C2, USART1, SPI2 у F103 и F407 — без преобразователя; SPI1 и USART2 у F103 — нет.
Полные исходники
lvl95a.c — линия с открытым стоком, подтянутая к 5 В, на выводе FT.
/* Раздел 95а: линия с открытым стоком, подтянутая снаружи к 5 В, — без преобразователя уровней.
* Только для выводов FT (терпимых к 5 В), например PB8 у F103 и F407. Собирается для F103 (-DSTM32F10X_MD,
* stm32f10x.h) и для F407 (-DSTM32F407xx, stm32f4xx.h). */
#include <stdint.h>
#if defined(STM32F10X_MD)
/* F103: MODE = 10 (выход, 2 МГц), CNF = 01 (открытый сток). Подтяжки у F1 включаются только в режиме входа. */
void od5v_pin(GPIO_TypeDef *port, uint32_t pin)
{
volatile uint32_t *cr = (pin < 8u) ? &port->CRL : &port->CRH;
uint32_t sh = (pin & 7u) * 4u;
*cr = (*cr & ~(0xFu << sh)) | (0x6u << sh);
}
_Static_assert((GPIO_CRL_MODE0_1 | GPIO_CRL_CNF0_0) == 0x6u, "F103: MODE=10, CNF=01");
_Static_assert((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) == 0xFu, "F103: четыре бита на вывод");
#else
/* F407: выход, открытый сток, низкая скорость, встроенные подтяжки выключены —
* с ними вывод FT не держит напряжение выше VDD + 0,3 В. */
void od5v_pin(GPIO_TypeDef *port, uint32_t pin)
{
port->MODER = (port->MODER & ~(3u << (pin * 2u))) | (1u << (pin * 2u));
port->OTYPER |= 1u << pin;
port->OSPEEDR &= ~(3u << (pin * 2u));
port->PUPDR &= ~(3u << (pin * 2u));
}
_Static_assert(GPIO_MODER_MODER0_0 == 1u && GPIO_OTYPER_OT_0 == 1u && GPIO_PUPDR_PUPDR0 == 3u
&& GPIO_OSPEEDER_OSPEEDR0 == 3u, "F407: поля MODER, OTYPER, OSPEEDR, PUPDR");
#endif
/* Отпустить линию: единицу до 5 В даст внешняя подтяжка. */
void od5v_release(GPIO_TypeDef *port, uint32_t pin)
{
port->BSRR = 1u << pin;
}
/* Прижать линию к нулю. */
void od5v_low(GPIO_TypeDef *port, uint32_t pin)
{
port->BSRR = 1u << (pin + 16u);
}
/* Прочитать линию: вход читается и в режиме выхода с открытым стоком. */
uint32_t od5v_read(GPIO_TypeDef *port, uint32_t pin)
{
return (port->IDR >> pin) & 1u;
}
Дальше: раздел 96 «Температура: NTC-термистор и DS18B20» — первый датчик части: аналоговый и цифровой способ измерить одно и то же.