GPIOとピン多重化
1本のピンがなぜ入力にも出力にもUARTにもなるのかが原理から腑に落ちる。入出力モード・プルアップ・オープンドレイン・オルタネート機能・ドライブ強度まで、基板設計とレジスタ設定で刺さる勘所を押さえられる。
- 1.GPIOピンは1本の物理パッドに入力バッファ・出力ドライバ・プル抵抗が同居し、モードレジスタでどれを有効化するかを切り替える。入力ならバッファで読み、出力ならプッシュプルかオープンドレインで駆動する。
- 2.ピン多重化(マルチプレクサ)は、1本のパッドをGPIOか複数のペリフェラル(UART・SPI・I2C・タイマ等)のどれに接続するかを選ぶセレクタ。オルタネート機能レジスタで割り当て先を選び、限られたピン数を機能で共有する。
- 3.ドライブ強度は出力トランジスタの駆動能力、スルーレートは出力の立ち上がり/立ち下がりの傾き。強く速くするほど負荷を速く駆動できるが、リンギングとEMI(電磁ノイズ)が増えるトレードオフになる。
1本のピンに詰め込まれた回路
マイコンのデータシートでピン配置を見ると、PA9 のような1つのピンに USART1_TX / TIM1_CH2 / GPIO などと複数の機能が併記されています。ピン数は数十本しかないのに、内蔵ペリフェラルは何十個もある——この矛盾を解くのが GPIO(汎用入出力)とピン多重化 です。1本の物理パッドの内側には、入力を読むためのバッファ、外へ電圧を出す出力ドライバ、High/Low に引き込むプル抵抗が同居しており、さらにその出口を「GPIOレジスタ」につなぐか「どれかのペリフェラル」につなぐかを選ぶセレクタが入っています。
CPU から見れば、これらの構成はすべてメモリマップドレジスタ(詳細は /embedded/memory-mapped-io/)のビットで制御されます。ピンごとに「入力か出力か」「プル抵抗をどうするか」「GPIOか第n機能か」を設定するレジスタが並び、その組み合わせで1本のパッドの振る舞いが決まります。まずは入出力モードから、内部で何が起きているかを追います。
入力モードと出力モード
入力モード では、パッドの電圧を シュミットトリガ入力バッファ が読み取り、しきい値を境に 0/1 のデジタル値へ変換して入力データレジスタ(IDR)に反映します。シュミットトリガはヒステリシス(立ち上がりと立ち下がりで別のしきい値)を持ち、緩やかに変化する信号やノイズが乗った信号でチャタリングするのを防ぎます。このとき出力ドライバは切り離されており、ピンは基本的にハイインピーダンス(外から見て高抵抗)です。
出力モード では、出力データレジスタ(ODR)に書いた値を出力ドライバがパッドへ駆動します。ドライバには2つの方式があります。
| 出力方式 | High側 | Low側 | 特徴と用途 |
|---|---|---|---|
| プッシュプル | P-MOSがVDDへ引く | N-MOSがGNDへ引く | 0/1両方を能動的に駆動。応答が速く、通常のGPIO出力の既定 |
| オープンドレイン | 駆動しない(ハイインピーダンス) | N-MOSがGNDへ引く | Lowのみ駆動。Highは外部プルアップ任せ。バス共有・レベル変換に必須 |
プッシュプルは上下2つのトランジスタで 0 と 1 の両方を能動的に押し引きするため応答が速く、LED 駆動や単純な信号出力の既定です。対してオープンドレインは Low に引く N-MOS だけを持ち、High 側は「何もしない(開放)」状態になります。
プルアップ/プルダウンとオープンドレイン
入力ピンをどこにもつながずに放置すると、パッドは宙に浮いた フローティング 状態になり、周囲のノイズを拾って 0/1 がランダムに揺れます。これを防ぐのが内蔵の プルアップ抵抗(VDD へ弱く引く)と プルダウン抵抗(GND へ弱く引く)です。ボタンやスイッチの読み取りでは、押されていないときの既定値を確定させるために必ずどちらかを有効にします。抵抗値は数十kΩ程度と大きく、能動ドライバに比べれば「弱い」引き込みなので、外部から強く駆動されればそちらが勝ちます。
未接続の入力を内部プル抵抗もなしに読むと、値は不定です。デバッグ時には安定して見えても、手を近づけただけ・電源ノイズが乗っただけで反転し、再現しにくい不具合になります。使わない入力ピンにも既定の引き込みを設定するか、外部で確実にプルするのが鉄則です。リセット直後のピンは多くがフローティング入力なので、起動シーケンスでの初期化順序にも注意します。
オープンドレイン出力とプルアップの組み合わせは、単なる選択肢ではなく特定の回路構成で必須になります。複数のデバイスが1本の線を共有し、誰かが Low に引けば線全体が Low、誰も引かなければプルアップで High——という ワイヤードAND(論理積) を作れるのはオープンドレインだけです。プッシュプル同士を同じ線につなぐと、一方が High を、他方が Low を出した瞬間に VDD から GND へ貫通電流が流れ、素子が壊れます。I2C の SDA/SCL がオープンドレイン必須なのはこのためで、詳細は /embedded/bus-i2c-spi-uart/ で扱っています。異なる電源電圧のデバイス間をつなぐレベル変換にも、オープンドレイン+目標電圧へのプルアップがよく使われます。
ピン多重化(オルタネート機能)
ここからが本題のピン多重化です。1本のパッドを、GPIOロジックにつなぐか、UART・SPI・タイマといった特定ペリフェラルの信号につなぐかを選ぶ マルチプレクサ(セレクタ) が、パッドとペリフェラルの間に挟まっています。この「GPIO以外の機能」を オルタネート機能(Alternate Function, AF) と呼びます。
STM32 の Cortex-M を例にすると、ピンの役割は2段構えで決まります。まずモードレジスタ(MODER)で各ピンを「入力/出力/アナログ/オルタネート機能」のいずれかに設定し、オルタネート機能を選んだピンについては、さらにオルタネート機能選択レジスタ(AFR、AFRL/AFRH の2本で16ピン分)に 0〜15 の番号を書いて どのペリフェラルに割り当てるか を指定します。
1本のパッドにぶら下がる多重化の構造(概念図):
┌──────────── GPIO 出力(ODR) ─────┐
ペリフェラルA(USART_TX) ─┐ │
ペリフェラルB(TIM_CH) ──┤ ▼
ペリフェラルC(SPI_MOSI)──┤ MUX ──▶ 出力ドライバ ──▶ [PAD] ──▶ 外部
▲ │
AFR/MODER で選択 ▼
入力バッファ ──▶ GPIO入力(IDR)
└─▶ 各ペリフェラルの入力へ
/* STM32: PA9 を USART1_TX(AF7)に割り当てる例(概念コード) */
GPIOA->MODER &= ~(3u << (9 * 2)); /* PA9 のモードビットをクリア */
GPIOA->MODER |= (2u << (9 * 2)); /* 10b = オルタネート機能モード */
GPIOA->AFR[1] &= ~(0xFu << ((9 - 8) * 4)); /* AFRH の PA9 用4ビットをクリア */
GPIOA->AFR[1] |= (0x7u << ((9 - 8) * 4)); /* AF7 = USART1 を選択 */
重要なのは、1本のパッドが同時につながれるのは1つの機能だけ という点です。ある番号のペリフェラルに割り当てると、そのピンはもう GPIO としては使えません。しかも各ペリフェラル信号は「このピン群のこの番号でしか出せない」と固定されているため、基板設計では「使いたいペリフェラルの組み合わせが、ピンの多重化表の上で衝突しないか」を事前に検証する必要があります。TX と別機能を同じピンに要求してしまうと、どちらかを諦めるかピン割り当てを組み直すことになります。
「UART2本+SPI1本+I2C1本+PWM4本」のように必要機能を並べ、各信号が取り得るピン候補を多重化表から拾って競合しない組を探す作業は、基板の配線が確定する前に済ませておくべき工程です。ベンダのGUIツール(STM32CubeMX 等)は、この割り当てを自動で解いて衝突を可視化してくれます。後から「このピンでは目的の機能が出せない」と判明すると、基板の作り直しに直結します。
ドライブ強度とスルーレート
出力モードの最後の調整項目が ドライブ強度 と スルーレート です。ドライブ強度(駆動能力)は出力トランジスタが流せる電流の大きさで、大きいほど重い容量負荷や低いプルアップを速く駆動できます。スルーレート(出力の傾き、単位は V/秒)は、出力が Low から High へ(またはその逆へ)遷移する際の電圧変化の速さです。多くのマイコンは出力速度レジスタ(OSPEEDR 等)でこれらを数段階に設定できます。
この2つは「速く・強くすれば良い」わけではなく、明確なトレードオフを持ちます。
| 設定 | 速く・強くする | 遅く・弱くする |
|---|---|---|
| 立ち上がり/立ち下がり | 急峻。高速信号を正しく伝送できる | 緩やか。高速バスでは波形が間に合わない |
| リンギング/オーバーシュート | 増える(配線のインダクタンスと共振) | 減る。波形が素直に落ち着く |
| EMI(放射ノイズ) | 増える(急峻なエッジは高周波成分が多い) | 減る。近傍回路への干渉が小さい |
| 消費電流・貫通電流 | 増えやすい | 抑えられる |
エッジが急峻なほど信号に含まれる高周波成分が増え、配線の寄生インダクタンスと容量が共振して波形が跳ねる リンギング や、放射ノイズ(EMI)が悪化します。そのため定石は、その信号が必要とする速度ちょうどに設定する ことです。数十MHz の SPI クロックには高いドライブ強度と速いスルーレートを与え、ゆっくり点滅させる LED やまれにしか変化しない制御線には最も遅い設定を選びます。過剰なドライブ強度は、性能を上げるどころかノイズ問題を自ら作り込む原因になります。
低消費電力モードへ入ると、GPIO の一部は状態を保持し、一部はハイインピーダンスに落ちる設定があります。プルアップを有効にしたピンはスリープ中も微小なリーク電流を流し続けるため、超低消費電力設計では不要なプルを切る、あるいは出力を確定させて浮かせないなどの配慮が要ります。詳細は /embedded/low-power-sleep-modes/ を参照してください。
「プッシュプルとオープンドレインの違いは」には『プッシュプルは0/1両方を能動駆動、オープンドレインはLowのみ駆動しHighは外部プルアップ任せ。バス共有やレベル変換にはオープンドレインが必須』と答えます。「なぜ入力ピンをフローティングにしてはいけないか」には『値が不定になりノイズで誤動作するため、プルアップ/プルダウンで既定値を確定させる』。「オルタネート機能とは」には『1本のピンをGPIOか特定ペリフェラルのどれに接続するかをマルチプレクサで選ぶ仕組みで、AFレジスタで割り当て先を指定する』。ドライブ強度/スルーレートを上げる代償(リンギング・EMI増)も定番です。
まとめ
- GPIOピンは1本のパッドに入力バッファ・出力ドライバ・プル抵抗が同居し、モードレジスタでどれを有効化するかを切り替える。入力はシュミットトリガで読み、出力はプッシュプルかオープンドレインで駆動する。
- プルアップ/プルダウンは入力の既定値を確定させてフローティングを防ぐ弱い引き込み。オープンドレイン+プルアップはワイヤードANDを作れる唯一の方式で、I2C のようなバス共有やレベル変換に必須。
- **ピン多重化(オルタネート機能)**は、1本のパッドをGPIOか複数ペリフェラルのどれに接続するかを選ぶマルチプレクサ。MODER でモードを、AFR で割り当て先番号を指定し、限られたピンを機能で共有する。同時に有効化できる機能は1つだけなので、設計初期にピン競合を解いておく。
- ドライブ強度(駆動能力)とスルーレート(エッジの傾き)は、速く強くするほど重い負荷を速く駆動できる反面、リンギングとEMIが増える。信号が要求する速度ちょうどに設定するのが定石で、過剰設定はノイズ問題を自ら招く。
組込み・IoT Article
GPIOとピン多重化を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
組み込み
比較で見る軸
難易度: advanced / カテゴリ: 組込み・IoT / タグ数: 6
導入後に効く点
ピン多重化(マルチプレクサ)は、1本のパッドをGPIOか複数のペリフェラル(UART・SPI・I2C・タイマ等)のどれに接続するかを選ぶセレクタ。オルタネート機能レジスタで割り当て先を選び、限られたピン数を機能で共有する。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- 組込み・IoT
- タグ数
- 6
判断チェックリスト
- 自社の用途が「組み込み / GPIO」に近いか確認する。
- 強みである「GPIOピンは1本の物理パッドに入力バッファ・出力ドライバ・プル抵抗が同居し、モードレジスタでどれを有効化するかを切り替える。入力ならバッファで読み、出力ならプッシュプルかオープンドレインで駆動する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。