汎用入出力【STM32のGPIO使い方詳細 】
STM32マイコンの汎用入出力GPIOの使い方を詳細に解説しています。ペリフェラルの中で最も基本で使用頻度の高いGPIOを使いこなせるようになることはプログラミングだけでなくインターフェースを構成している電子回路の理解も必要なため、STM32マイコン操作の勘所を理解することでもあります。
目次
汎用入出力GPIOとは
汎用入出力はGPIO(Genaral Purpose Input/Output)ともいい、ソフトウェアで任意に入出力を制御できるポート(ピン)です。ピンに入力された信号を情報としてCPUに取り込んだり、マイコン内のCPUから端子に信号を出力したりします。
STM32マイコンのGPIO回路構成を下に示します。STM32マイコンではペリフェラルライブラリで指定のピンの仕様を入力にしたり出力にしたりできます。
入力の場合は、入力ドライバ部の回路が使われてプルアップ入力、プルダウン入力、フローティング入力そしてアナログ入力の4種類を使用する機能に合わせて指定します。
プルアップ、プルダウン入力が指定されるとそれぞれ指定のプルアップかプルダウン抵抗がONし、シュミットトリガ回路を通して入力データレジスタへ情報として渡されます。シュミットトリガ回路は入力されたデジタル信号の波形を整形するものです。
デジタル電圧信号を入力とする場合はフローティング入力を指定します。このときプルアップ・プルダウン抵抗はOFFとなります。
アナログ信号を入力とする場合、信号はシュミット回路を介さずに直接ADコンバータ回路へ送られます。
出力の場合には汎用出力のプッシュプル、オープンドレイン、オルタネート機能出力のプッシュプルとオープンドレインの4種類を使用する機能に合わせて指定します。
汎用プッシュプル出力が指定されると出力がONのときに出力ピンはHレベル電圧が、OFFのときに出力ピンはLレベル電圧が出力されます。
オープンドレイン出力を指定すると出力回路のN-MOSだけが機能します。出力をONにしたときN-MOSがOFFになるので出力ピンはHレベル電圧でもLレベル電圧でもない浮いた不定の状態となります。出力がOFFしたときはN-MOSがONとなるため出力ピンはLレベル電圧となります。
指定対象のポートが汎用でなくペリフェラル機能の出力である場合はオルタネート機能の出力を指定します。これにもプッシュプルとオープンドレインの2種類をペリフェラルに合わせて指定します。
GPIOペリフェラルの使い方
それでは実際にGPIOペリフェラルライブラリを活用して設定する方法を解説していきましょう。GPIOのペリフェラルライブラリは下図の手順で設定します。
ポートA pin1をプッシュプル出力に設定
① GPIOAにクロック供給
まず使用するGPIOにクロックを供給します。ペリフェラルによりAPB1バスとAPB2バスのどちらかに接続しているかを確認し選択します。
クロック供給関数RCC_APBxPeriphClockCmd()の第1引数でAPBxバスに接続するペリフェラルを指定、第2引数がENABLEで供給開始、DISABLEで供給停止となります。
引数というのは関数の中で使用する設定パラメータで複数ある場合は順次、第1引数、第2引数…となります。GPIOのAポートの場合はAPB2バスに接続していますのでRCC_APB2PeriphClockCmd関数を指定してクロックを供給し機能をONします。
設定例:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIA, ENABLE);
下表のクロック供給関数へのマクロはstm32f10x_rcc.h内で定義されているものです。
② GPIOAの初期化
次にGPIOAの初期化を行います(GPIO_Init関数を使用)。
使用するペリフェラルのライブラリが記述された関数をつかってパラメータを設定し、初期化します。GPIOの場合はstm32f10x_gpio.c に制御レジスタに設定するマクロ関数が記述されており、その中で使用される変数、構造体類をstm32f10x_gpio.hに定義しています。
GPIOAの初期化はGPIO_Init関数を使用します。
設定例: GPIO_Init(GPIA, &GPIO_InitStructure);
関数の第1引数は設定対象のGPIOポートを指定します。マイコンにより使用できるポートは限定されます。
第2引数のGPIO_InitStructureは設定パラメータをグループ化した構造体変数と呼ばれるものでヘッダファイルstm32f10x_gpio.h内で定義されています。使用するまえにGPIO_InitTypeDef GPIO_InitStructure;と宣言しておきます。
構造体変数のGPIO_InitStructureには関数内の設定パラメータをメンバとして含み、使用するピン、入出力の仕様、出力の場合は最大スイッチング速度を指定します。パラメータ詳細を下表に示します。
出力にオルタネート機能というものがありますが、これはピンが単なるGPIO入出力でなくタイマやUARTなどのペリフェラル(周辺機能)の出力となる場合です。ペリフェラルにより指定すべき出力仕様がありますので各ペリフェラルで解説します。
設定例: GPIOA_1 プッシュプル出力 最大スイッチング周波数2MHz
GPIO_InitTypeDef GPIO_InitStructure;//構造体変数宣言
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//(0x0001)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//(0x10)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;// (0x02)
設定パラメータを指定したら初期化関数GPIO_Init()を実行します。各ポート(AからGポート)で対象のポートを指定します。これ以後、初期化したポートはプログラム内で任意に使用できるようになります。
GPIOのオルタネート機能・リマップ
オルタネート機能
これまではマイコンのポートをGPIOで使用することを前提にすすめてきましたが、初期化作業はポートをGPIO以外のペリフェラル(周辺機能)で使用する際にも必要です。
STM32ではどのポートがどの周辺機能に使用できるかはあらかじめ決まっています。GPIO以外の用途への入出力のためにSTM32の各ポートを使用できる機能のことをオルタネート機能とよんでいます。
ポートを使用した外部割込みもオルタネート機能に含まれます。オルタネート機能でペリフェラルのためにポートを出力として使用するときは入出力仕様項目のGPIO_Mode_AF_PP(オルタネート機能プッシュプル)かGPIO_ModeにGPIO_Mode_AF_OD(オルタネート機能オープンドレイン)を設定します。
オルタネート機能を使用する場合はクロックを供給してオルタネート機能をONする必要があります。
設定例: オルタネート機能を使用する場合
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
リマップ(再配置)
リマップとはSTM32にデフォルトとしてもともと割り当てられているオルタネート機能とは別の機能を利用するためのものです。どのような場合に使用する機能なのかを解説していきます。
マイコンを活用するにあたって、比較的単機能な場合はポートをGPIOやペリフェラルを使うにしても標準的なデフォルトのオルタネート機能でことは足りるためリマップは必要ないかもしれません。
システムが複雑で多機能になってくると一つのマイコンで複数のペリフェラル(タイマ、UART通信など)を同時に使うようになります。マイコンのピン数は限られているので機能が増えるほどを思い通りに同時に使うことはできなくなってきます。
このようなときにリマップ機能があれば使用したい必要な機能を別のピンにリマップ(再配置)させることができるのでより効率よくマイコンの機能を活用できるようになります。ただし、マイコンによりリマップできる箇所は限られていますので仕様書のピン定義表でよく確認することが大切です。
ポートPC10をピン定義表でみるとオルタネート機能はデフォルトではUART4_TXかSDIO_D2が割り当てられています。したがって、UART4かSDIOのどちらか使用するペリフェラルにクロックを供給すると供給された側のペリフェラルがONして機能します。
言い換えるとそのままではUART4かSDIOしか使用できません。でも、このピンにはリマップにUART3_Txが割り当てられています。リマップをするとこのピンでUART3_TXが使用できるようになるのです。
リマップが必要となるのは例えば以下のようなケースです。
シリアル通信のUART3を使用したいが、オルタネート機能としてのデフォルトUART3のPB10付近のピンはすでに他の用途で使用しています。
そこで、リマップでUART3が使えるピンを探してみるとPC10付近に割り当てられています。この付近のピンが空いていればリマップ機能を設定することでUART3が使用できるようになるのです。
リマップは下図の手順で設定します。
ペリフェラルUART3のTXとRXをそれぞれPC10とPC11に割り当てるためのリマップする例で解説します。
① GPIOの構造体変数宣言
GPIOの構造体変数宣言は一度実行すればよいのではじめにしておきます。
② GPIOCにクロック供給
ポートPC10とPC11を使用するためにポートCにクロックを供給します。
③ オルタネート機能にクロック供給
ペリフェラルUART3とリマップ機能を使用するためにオルタネート機能にクロックを供給します。
④ ピンPC10をUART3_TX用に設定
PC10のUART3_TXはプッシュプル出力タイプですがペリフェラルの出力ですのでオルタネートプッシュプル出力に設定します。スイッチング速度は設定通信スピード(ボーレート)より速いものに設定しておきます。設定後GPIO_Init関数を実行してオルタネートプッシュプル出力として初期化します。
⑤ ピンPC11をUART3_RX用に設定
PC11のUART3_RXはデジタル電圧入力のフローティングに設定します。設定後GPIO_Init関数を実行してフローティング入力として初期化します。
⑥ リマップ実行
各ピンの初期化後、リマップを実行します。
リマップ実行はGPIO_PinRemapConfig関数を実行することで行います。関数の第1引数でリマップの対象となるペリフェラルを指定します。前述しましたがリマップは任意の箇所でできるのではなくあらかじめ割り当てられています。
リマップには部分リマップという機能の一部だけがリマップされたものとフルリマップなる機能全てがリマップされるものがあります。
設定例:
GPIO_PinRemapConfig (GPIO_PartialRemap_USART3, ENABLE);//部分リマップ
⑦ GPIOC再設定
リマップ関数を実行すると使用しないポートもオルタネート機能に含めてしまう場合があります。上記設定の例ではリマップ後に使用したいのはUART3のPC10(UART3_TX)とPC11(UART3_RX)の2ポートだけです。
リマップ機能によりオルタネート機能に含まれたPC12をGPIOやデフォルトのオルタネート機能(UART5_TX)として使用したい場合は元の機能になる設定をすればよいです。上記の例ではPC12を汎用入力に再設定しています。
以上がリマップ機能を実行する作業手順です。リマップ機能は限られたピン数のマイコンの機能をより効率よく利用することができる有効な機能です。ある程度多機能なシステムを設計する場合にはリマップ機能を使うと柔軟にピン配置を構成できるので大変便利です。
リマップ機能の割当を対応した表にまとめていますので、仕様書のピン定義表とともに確認しながら設定してください。