Tangwx

Tangwx

博客网站

03.STM32GPIO汎用入出力ポート

3 GPIO 一般入出力ポート#

3.1 GPIO の概要#

GPIO(General Purpose Input Output)一般入出力ポート

8 種類の入出力モードに設定可能

ピンレベル:0V〜3.3V、一部のピンは 5V に耐えられる

出力モードではポートの出力高低レベルを制御し、LED を駆動したり、ブザーを制御したり、アナログ通信プロトコルの出力タイミングを生成するなどに使用される

入力モードではポートの高低レベルまたは電圧を読み取り、キー入力を読み取ったり、外部モジュールのレベル信号を入力したり、ADC 電圧を収集したり、アナログ通信プロトコルでデータを受信したりするために使用される

3.2 GPIO の基本構造#

STM32 では、すべての GPIO は APB2 周辺機器バスにマウントされており、GPIO の名前は GPIOA、GPIOB、GPIOC などで命名されている。各 GPIO 周辺機器には 16 本のピンがあり、番号は 0 から 15 までである。各 GPIO モジュール内には、主にレジスタとドライバが含まれており、レジスタは特別なメモリの一部であり、コアは APB2 バスを介してレジスタを読み書きすることができる。これにより、出力レベルの生成とレベルの読み取りが可能になる。このレジスタの各ビットは 1 本のピンに対応しており、出力レジスタに 1 を書き込むと、対応するピンは高レベルを出力し、0 を書き込むと低レベルを出力する。入力レジスタが 1 を読み取ると、対応するポートが現在高レベルであることを示し、0 を読み取ると低レベルであることを示す。STM32 は 32 ビットのマイコンであるため、STM32 内部のレジスタはすべて 32 ビットであるが、ポートは 16 ビットしかないため、このレジスタの低 16 ビットのみがポートに対応し、高 16 ビットは使用されない。このドライバは信号の駆動能力を増加させるために使用され、レジスタはデータを保存する役割を果たす。点灯などの操作を行う場合は、ドライバが駆動能力を増加させる必要がある。これが GPIO の全体的な基本構造である。

image-20220821193133744

3.3 GPIO のビット構造#

GPIO の各ビットの具体的な回路構造は、下図は STM32 のリファレンスマニュアルにおける GPIO ビット構造の回路図であり、左側の 3 つはレジスタであり、中央部分はドライバであり、右側は特定の IO ポートのピンである。全体の構造は 2 つの部分に分けられ、上半分は入力部分、下半分は出力部分である。

3.3.1 入力部分#

ピンには 2 つの保護ダイオードが接続されており、入力電圧を制限する。上のダイオードは VDD-3.3V に接続され、下は VSS-0V に接続されている。入力電圧が 3.3V を超えると、上のダイオードが導通し、入力電圧から生成される電流は内部回路に流れずに直接 VDD に流れ、内部回路に対する過電圧の損傷を防ぐことができる。入力電圧が 0V 未満の場合、この電圧は VSS に対する電圧であるため、負の電圧が存在することができる。この場合、下のダイオードが導通し、電流は VSS から直接流出し、内部回路から電流を引き出すことはないため、内部回路を保護することができる。入力電圧が 0〜3.3V の範囲内にある場合、両方のダイオードは導通せず、ダイオードは回路に影響を与えない。これが保護ダイオードの用途である。電流はプルアップ抵抗とプルダウン抵抗を通過し、プルアップ抵抗は VDD に、プルダウン抵抗は VSS に接続され、このスイッチはプログラムによって設定可能である。上が導通し、下が開放されている場合はプルアップ入力モードであり、下が導通し、上が開放されている場合はプルダウン入力モードである。両方が開放されている場合はフローティング入力モードである。プルアップとプルダウンは、入力にデフォルトの入力レベルを提供するために使用される。デジタルポートの場合、入力は高レベルまたは低レベルである。何も接続されていない場合、入力はフローティング状態になり、ピンの入力レベルは外部の干渉を受けやすく変化するため、ピンがフローティング状態になることによる入力データの不確定性を避けるために、ここでプルアップまたはプルダウン抵抗を追加する必要がある。プルアップ抵抗を接続すると、ピンがフローティング状態のときでもプルアップ抵抗がピンの高レベルを保証するため、プルアップ入力はデフォルトの高レベル入力モードとも呼ばれる。プルダウンも同様で、デフォルトは低レベルの入力方式である。プルアップ抵抗とプルダウン抵抗の抵抗値は比較的大きく、弱いプルアップと弱いプルダウンであり、正常な入力操作にできるだけ影響を与えないことを目的としている。TTL シュミットトリガーはここではシュミットトリガーであり、入力電圧を整形する役割を果たす。実行ロジックは、入力電圧がある閾値を超えると出力が瞬時に高レベルに上昇し、入力電圧がある閾値を下回ると出力が瞬時に低レベルに下降する。シュミットトリガーにとっては、上限を超えたり下限を下回ったりした場合にのみ出力が変化する。シュミットトリガーで整形された波形は直接データレジスタに書き込むことができ、プログラムで入力データレジスタの特定のビットのデータを読み取ることで、ポートの入力レベルを知ることができる。アナログ入力は ADC に接続されており、AD はアナログ量を受信する必要があるため、この線はシュミットトリガーの前に接続する必要がある。もう 1 つはマルチプレックス機能入力であり、これは他のポート周辺機器を読み取る必要があるもので、例えばシリアルポートの入力ピンなどである。この線はデジタル量を受信するため、シュミットトリガーの後に接続される。

3.3.2 出力部分#

デジタル部分は出力データレジスタまたはオンチップ周辺機器によって制御され、データセレクタを介して出力制御部分に接続される。出力データレジスタを介して制御を選択する場合は、通常の IO ポート出力となり、このデータレジスタの特定のビットを書き込むことで対応するポートを操作できる。左側にはビット設定 / クリアレジスタがあり、他のビットに影響を与えずに出力データレジスタの特定のビットを個別に操作するために使用される。この出力データレジスタは同時に 16 ポートを制御し、このレジスタは全体としてのみ読み書きできる。他のポートに影響を与えずに特定のポートを個別に制御したい場合は、特別な操作方法が必要である。最初の操作方法は、このレジスタを読み出し、ビット単位の AND &= およびビット単位の OR |= の方法で特定のビットを変更し、最後に変更されたデータを書き戻すことである。この方法は面倒で効率が悪く、IO ポートの操作にはあまり適していない。2 番目の方法は、このビット設定 / クリアレジスタを設定することである。特定のビットを 1 に設定する操作を行う場合は、ビット設定レジスタの対応するビットに 1 を書き込み、他の操作が不要なビットには 0 を書き込む。これにより、内部回路は出力データレジスタの対応するビットを 1 に設定し、他のビットは 0 のまま保持される。これにより、他のビットに影響を与えずに特定のビットのみを操作することが保証され、これは一度の操作で完了する。特定のビットをクリアする操作を行いたい場合は、ビットクリアレジスタの対応するビットに 1 を書き込むだけで、内部回路はそのビットをクリアする。さらに、3 番目の操作方法として、STM32 の「ビットバンド」領域を読み書きすることである。このビットバンドの役割は 51 マイコンのビットアドレッシングの役割に似ており、STM32 では特定のアドレス領域が割り当てられており、このアドレスは RAM と周辺機器レジスタのすべてのビットをマッピングしている。このアドレス内のデータを読み書きすることは、マッピングされた位置の特定のビットを読み書きすることに相当する。これがビットバンドの操作方法であり、この方法は本コースでは使用せず、主にライブラリ関数を使用して操作する。ライブラリ関数はビット設定 / クリアレジスタの読み書きを使用する。出力制御の後は 2 つの MOS 管に接続され、上はP-MOS、下はN-MOSである。この MOS 管は電子スイッチの一種であり、信号がスイッチの導通と閉鎖を制御する。スイッチは IO ポートをVDDまたはVSSに接続する役割を果たし、ここではプッシュプル、オープンドレイン、またはオフの 3 つの出力方式を選択できる。プッシュプル出力では、P-MOSN-MOSの両方が有効であり、データレジスタが 1 のとき、上の管が導通し、下の管が開放され、出力は直接 VDD に接続され、高レベルを出力する。データレジスタが 0 のとき、上の管が開放され、下の管が導通し、出力は直接 VSS に接続され、低レベルを出力する。このモードでは、高低電圧の両方に強い駆動能力があるため、プッシュプル出力モードは強力なプッシュ出力モードとも呼ばれる。プッシュプル出力モードでは、STM32 は IO ポートに対して絶対的な制御権を持ち、高低レベルはすべて STM32 によって決定される。オープンドレイン出力モードでは、P-MOSは無効で、N-MOSのみが動作し、データレジスタが 1 のとき、下の管は開放され、このとき出力は開放され、高抵抗モードとなる。データレジスタが 0 のとき、下の管が導通し、出力は直接 VSS に接続され、低レベルを出力する。このモードでは、低レベルのみが駆動能力を持ち、高レベルには駆動能力がない。オープンドレインモードは通信プロトコルの駆動方式として使用でき、例えば I2C 通信のピンはオープンドレインモードを使用しており、マルチデバイス通信の状況下では、このモードは各デバイスの相互干渉を避けることができる。また、オープンドレインモードは 5V のレベル信号を出力するためにも使用でき、IO ポートに 5V の電源にプルアップされた抵抗を接続すると、低レベルを出力する際には内部の N-MOS が直接 VSS に接続され、高レベルを出力する際には外部のプルアップ抵抗によって 5V に引き上げられる。これにより、5V のレベル信号を出力し、5V レベルのデバイスとの互換性を持たせることができる。残りの状態はオフであり、これはピンが入力モードに設定されているときであり、この 2 つの MOS 管は無効であり、出力はオフになり、ポートのレベルは外部信号によって制御される。以上が GPIO ビット構造のすべての紹介である。

image-20220821193240193

3.4 GPIO の 8 つの動作モード#

GPIO のポート設定レジスタを設定することで、ポートは以下の 8 つのモードに設定可能である。

フローティング入力、プルアップ入力、プルダウン入力の回路構造は基本的に同じであり、違いはプルアップ抵抗とプルダウン抵抗の接続にある。これらはすべてデジタル入力ポートであり、ポートの高低レベルを読み取ることができる。ピンがフローティング状態のとき、プルアップ入力はデフォルトで高レベルであり、プルダウン入力はデフォルトで低レベルであり、フローティング入力のレベルは不確定であるため、フローティング入力を使用する際には、ポートに連続した駆動源を接続する必要があり、フローティング状態を避ける必要がある。

アナログ入力の特徴は GPIO が無効であり、ピンが内部 ADC に直接接続され、ADC アナログ - デジタル変換器の専用設定である。

オープンドレイン出力とプッシュプル出力の回路構造も基本的に同じであり、デジタル出力ポートであり、高低レベルを出力するために使用される。違いは、オープンドレイン出力の高レベルが高抵抗状態であり、駆動能力がないのに対し、プッシュプル出力の高低レベルはすべて駆動能力を持っている。

マルチプレックスオープンドレイン出力とマルチプレックスプッシュプル出力は通常のオープンドレイン出力とプッシュプル出力に近く、マルチプレックス出力であり、ピンのレベルはオンチップ周辺機器によって制御される。

GPIO のこれら 8 つのモードの中で、アナログ入力モードを除いて、他の 7 つのモードでは入力が有効である。

モード名性質特徴
フローティング入力デジタル入力ピンのレベルを読み取ることができ、ピンがフローティング状態の場合、レベルは不確定である
プルアップ入力デジタル入力ピンのレベルを読み取ることができ、内部にプルアップ抵抗が接続され、フローティング状態のときはデフォルトで高レベル
プルダウン入力デジタル入力ピンのレベルを読み取ることができ、内部にプルダウン抵抗が接続され、フローティング状態のときはデフォルトで低レベル
アナログ入力アナログ入力GPIO が無効で、ピンが内部 ADC に直接接続される
オープンドレイン出力デジタル出力ピンのレベルを出力でき、高レベルは高抵抗状態で、低レベルは VSS に接続される
プッシュプル出力デジタル出力ピンのレベルを出力でき、高レベルは VDD に接続され、低レベルは VSS に接続される
マルチプレックスオープンドレイン出力デジタル出力オンチップ周辺機器によって制御され、高レベルは高抵抗状態で、低レベルは VSS に接続される
マルチプレックスプッシュプル出力デジタル出力オンチップ周辺機器によって制御され、高レベルは VDD に接続され、低レベルは VSS に接続される

3.5 GPIO 入力フローティング / プルアップ / プルダウン設定#

入力モードでは、出力ドライバはオフになっており、ポートは入力のみ可能で出力はできない。上記の 2 つの抵抗はプルアップ動作、プルダウン動作、または動作しないように選択でき、対応するのはプルアップ入力、プルダウン入力、フローティング入力である。入力はシュミットトリガーを介して波形整形され、入力データレジスタに接続される。右側の入力保護には VDD または VDD_FT と書かれており、これは 3.3V ポートと 5V ポートの違いである。5V に耐えられるピンの上の保護ダイオードは処理が必要であり、ここに直接 VDD3.3V を接続すると、外部から 5V の電圧が接続されると、上のダイオードが開き、大きな電流が流れることになる。

image-20220821193727313

3.6 GPIO 高抵抗のアナログ入力設定#

アナログ入力の出力もオフになっており、入力のシュミットトリガーも無効の状態であり、GPIO の大部分は無効であり、ピンはオンチップ周辺機器、すなわち ADC に直接接続されるため、ADC を使用する際にはピンをアナログ入力に設定すればよく、他の時には一般的にアナログ入力は使用しない。

image-20220821193914682

3.7 GPIO オープンドレイン / プッシュプル出力設定#

出力は出力データレジスタによって制御され、P-MOSが無効であればオープンドレイン出力であり、P-MOSN-MOSの両方が有効であればプッシュプル出力である。また、出力モードでは入力モードも有効である。1 つのポートには 1 つの出力しか存在できないが、複数の入力が存在でき、出力モードに設定されているときに内部でも入力を行うことができる。

image-20220821193955149

3.8 マルチプレックスオープンドレイン / プッシュプル出力#

出力制御の左側の一般的な出力はオフになっており、ピンの制御権はオンチップ周辺機器に移行し、オンチップ周辺機器が制御する。入力部分では、オンチップ周辺機器もピンのレベルを読み取ることができ、通常の入力も有効であり、同時にレベル信号を受信することができる。

image-20220829075654841

3.9 GPIO で LED とアクティブブザーを制御#

image-20220829084106943

USE使用 STD標準 PERIPH周辺機器 DRIVERドライバ

3.9.1 LED の点滅#

#include "stm32f10x.h"                  // デバイスヘッダー
#include "Delay.h"

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//RCCがGPIOクロックを有効にし、Cポートのクロックを開く
	GPIO_InitTypeDef GPIO_InitStructure;//GPIO構造体変数を定義
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//一般的なプッシュプル出力
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;//PC13ポート
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz速度
	GPIO_Init(GPIOC, &GPIO_InitStructure);//GPIO_InitでGPIOを初期化し、ポートモードを設定
    //出力または出力 SetBitsを高レベルに設定し、ResetBitsを低レベルに設定
//	GPIO_SetBits(GPIOC, GPIO_Pin_13);
	GPIO_ResetBits(GPIOC, GPIO_Pin_13);
	while (1)
	{
        GPIO_SetBits(GPIOC, GPIO_Pin_13);//SetBitsを高レベルに設定
        Delay_ms(500);
		GPIO_ResetBits(GPIOC, GPIO_Pin_13); //ResetBitsを低レベルに設定
        Delay_ms(500);
        
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);//低レベル
		Delay_ms(500);
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);//高レベル
		Delay_ms(500);
        
        GPIO_WriteBit(GPIOC,GPIO_Pin_13,{BitAction}0);//低レベル
		Delay_ms(500);
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,{BitAction}1);//高レベル
		Delay_ms(500);
	}
}

3.9.2 LED の流れる光#

#include "stm32f10x.h"                  // デバイスヘッダー
#include "Delay.h"

/************************************************************************************************************************
* GPIO(General Purpose Input Output)一般入出力ポート
* 8種類の入出力モードに設定可能
* ピンレベル:0V〜3.3V、一部のピンは5Vに耐えられる
* 出力モードではポートの出力高低レベルを制御し、LEDを駆動したり、ブザーを制御したり、アナログ通信プロトコルの出力タイミングを生成するなどに使用される
* 入力モードではポートの高低レベルまたは電圧を読み取り、キー入力を読み取ったり、外部モジュールのレベル信号を入力したり、ADC電圧を収集したり、アナログ通信プロトコルでデータを受信したりするために使用される
* GPIOポート画像のTTLシュミットトリガーはシュミットトリガーであるべきである
* シュミットトリガーは高い上限または低い下限レベルを超えたときにのみ変化し、非常に良いデバウンスを提供する
* プッシュプル出力、オープンドレイン出力、オフの3つの状態
* プッシュプル出力では、P-MOSとN-MOSの両方が有効であり、このモードでは高低レベルの両方に強い駆動能力があるため、プッシュプル出力は強力なプッシュ出力モードとも呼ばれる
* プッシュプル出力モードでは、STM32はIOポートに対して絶対的な制御権を持ち、高低レベルはすべてSTM32によって決定される
* オープンドレイン出力モードでは、P-MOS出力は無効で、N-MOSのみが動作し、このモードでは低レベルのみが駆動能力を持ち、高レベルには駆動能力がない
* オープンドレインモードは通信プロトコルの駆動方式として使用でき、I2C通信のピンはオープンドレインモードを使用し、マルチデバイス通信の状況下ではこのモードは複数のデバイスの相互干渉を避けることができる
* また、オープンドレインモードは5Vのレベル信号を出力するためにも使用できる
* オフは、ピンが入力モードに設定されているときであり、P-MOSとN-MOSの両方が無効であり、出力はオフになり、ポートのレベル信号は外部信号によって制御される
************************************************************************************************************************/

/************************************************************************************************************************
* | **モード名** | **性質** | ************************特徴***********************|
* | ------------ | -------- | -------------------------------------------------- |
* | フローティング入力     | デジタル入力 | ピンのレベルを読み取ることができ、ピンがフローティング状態の場合、レベルは不確定である           |
* | プルアップ入力     | デジタル入力 | ピンのレベルを読み取ることができ、内部にプルアップ抵抗が接続され、フローティング状態のときはデフォルトで高レベル |
* | プルダウン入力     | デジタル入力 | ピンのレベルを読み取ることができ、内部にプルダウン抵抗が接続され、フローティング状態のときはデフォルトで低レベル |
* | アナログ入力     | アナログ入力 | GPIOが無効で、ピンが内部ADCに直接接続される                      |
* | オープンドレイン出力     | デジタル出力 | ピンのレベルを出力でき、高レベルは高抵抗状態で、低レベルはVSSに接続される        |
* | プッシュプル出力     | デジタル出力 | ピンのレベルを出力でき、高レベルはVDDに接続され、低レベルはVSSに接続される           |
* | マルチプレックスオープンドレイン出力 | デジタル出力 | オンチップ周辺機器によって制御され、高レベルは高抵抗状態で、低レベルはVSSに接続される        |
* | マルチプレックスプッシュプル出力 | デジタル出力 | オンチップ周辺機器によって制御され、高レベルはVDDに接続され、低レベルはVSSに接続される           |
* フローティング入力、プルアップ入力、プルダウン入力のこの3つのモードの回路構造は基本的に同じであり、違いは上下のプル抵抗の接続にある
* オープンドレイン出力とプッシュプル出力のこの2つの回路構造も基本的に同じであり、違いはオープンドレイン出力の高レベルが高抵抗状態であり、駆動能力がないことである
* マルチプレックスオープンドレイン出力とマルチプレックスプッシュプル出力のこの2つのモードは通常のものとほぼ同じであり、ただしマルチプレックス出力であり、ピンのレベルはオンチップ周辺機器によって制御される
* アナログ入力モードはデジタル入力機能をオフにする唯一のモードであり、他のモードではデジタル入力が有効である
************************************************************************************************************************/ 

int main(void)
{
	/***********************************************************************************
		GPIO出力
	***********************************************************************************/
	uint16_t i=0;//ループ変数を定義
	//対応するクロックを有効にする
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Aポートのクロックを開き、有効にする
	//構造体を定義する
	GPIO_InitTypeDef GPIO_InitStructure;
	//ポートモードを設定する
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //一般的なプッシュプル出力
	/**********************************************************
	GPIOの8つの動作モード
	GPIO_Mode_AIN アナログ入力(analog in)
	GPIO_Mode_IN_FLOATING フローティング入力(in floating)
	GPIO_Mode_IPD プルダウン入力(in pull down)
	GPIO_Mode_IPU プルアップ入力(in pull up)
	GPIO_Mode_Out_OD オープンドレイン出力(out open drain)
	GPIO_Mode_Out_PP プッシュプル出力(out push pull)
	GPIO_Mode_AF_OD マルチプレックスオープンドレイン出力(alt open drain)
	GPIO_Mode_AF_PP マルチプレックスプッシュプル出力(alt push pull)
	**********************************************************/
	//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // A4ピン
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //Aポートのすべてのピン
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz速度
	//ポートを初期化する
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//ポートの高低レベルを設定する
	/********************************************************************
	void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//ピンを高レベルに設定する
	void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//ピンを低レベルに設定する
	void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//BitAction BitValはBit_RESETとBit_SETの値
	void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//PortVal:出力データレジスタに書き込む値を指定する 
	*********************************************************************/
	//GPIO_SetBits(GPIOC, GPIO_Pin_13);//高レベル
	//GPIO_ResetBits(GPIOC, GPIO_Pin_13);//低レベル
	//GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET);//低レベル
	//GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);//高レベル
	//GPIO_Write(GPIOC, 0x0001); //0000 0000 0000 0001 PC0〜PC15の16ピンに対応
	while(1)
	{
		/*
		//LED点滅
		GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);//低レベル
		Delay_ms(500);
		GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);//高レベル
		Delay_ms(500);
		*/
		//流れる光
		for(i=0;i<16;i++)
		{
			GPIO_Write(GPIOA, ~0x0001);//0000 0000 0000 0001 ビット単位で反転し、低レベルで点灯
			Delay_ms(500);
			GPIO_Write(GPIOA, ~0x0002);//0000 0000 0000 0010
			Delay_ms(500);
			GPIO_Write(GPIOA, ~0x0004);//0000 0000 0000 0100
			Delay_ms(500);
			GPIO_Write(GPIOA, ~0x0008);//0000 0000 0000 1000
			Delay_ms(500);
			GPIO_Write(GPIOA, ~0x0010);//0000 0000 0001 0000
			Delay_ms(500);
			GPIO_Write(GPIOA, ~0x0020);//0000 0000 0010 0000
			Delay_ms(500);
			GPIO_Write(GPIOA, ~0x0040);//0000 0000 0100 0000
			Delay_ms(500);
			GPIO_Write(GPIOA, ~0x0080);//0000 0000 1000 0000
			Delay_ms(500);
			//GPIO_Write(GPIOA, 0x0001);//高レベルで点灯
			//Delay_ms(500);
		}
	}

}

3.9.3 ブザー#

#include "stm32f10x.h"                  // デバイスヘッダー
#include "Delay.h"

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//一般的なプッシュプル出力
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//PB12ポート
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz速度
	GPIO_Init(GPIOB, &GPIO_InitStructure);//GPIO_InitでGPIOを初期化し、ポートモードを設定

	while (1)
	{
        GPIO_SetBits(GPIOB, GPIO_Pin_12);//SetBitsを高レベルに設定
        Delay_ms(500);
		GPIO_ResetBits(GPIOB, GPIO_Pin_12); //ResetBitsを低レベルに設定
        Delay_ms(500);
	}
}

3.10 GPIO 入力#

ボタンのデバウンス

image-20220829223028287

3.10.1 ボタンで LED を制御#

ショートカットキーCtrl+ALT+スペースでコードヒントを表示

main.c#
#include "stm32f10x.h"                  // デバイスヘッダー
#include "Delay.h"
#include "LED.h"
#include "Key.h"

/************************************************************************************************************************
* GPIO(General Purpose Input Output)一般入出力ポート
* 8種類の入出力モードに設定可能
* ピンレベル:0V〜3.3V、一部のピンは5Vに耐えられる
* 出力モードではポートの出力高低レベルを制御し、LEDを駆動したり、ブザーを制御したり、アナログ通信プロトコルの出力タイミングを生成するなどに使用される
* 入力モードではポートの高低レベルまたは電圧を読み取り、キー入力を読み取ったり、外部モジュールのレベル信号を入力したり、ADC電圧を収集したり、アナログ通信プロトコルでデータを受信したりするために使用される
* GPIOポート画像のTTLシュミットトリガーはシュミットトリガーであるべきである
* シュミットトリガーは高い上限または低い下限レベルを超えたときにのみ変化し、非常に良いデバウンスを提供する
* プッシュプル出力、オープンドレイン出力、オフの3つの状態
* プッシュプル出力では、P-MOSとN-MOSの両方が有効であり、このモードでは高低レベルの両方に強い駆動能力があるため、プッシュプル出力は強力なプッシュ出力モードとも呼ばれる
* プッシュプル出力モードでは、STM32はIOポートに対して絶対的な制御権を持ち、高低レベルはすべてSTM32によって決定される
* オープンドレイン出力モードでは、P-MOS出力は無効で、N-MOSのみが動作し、このモードでは低レベルのみが駆動能力を持ち、高レベルには駆動能力がない
* オープンドレインモードは通信プロトコルの駆動方式として使用でき、I2C通信のピンはオープンドレインモードを使用し、マルチデバイス通信の状況下ではこのモードは複数のデバイスの相互干渉を避けることができる
* また、オープンドレインモードは5Vのレベル信号を出力するためにも使用できる
* オフは、ピンが入力モードに設定されているときであり、P-MOSとN-MOSの両方が無効であり、出力はオフになり、ポートのレベル信号は外部信号によって制御される
************************************************************************************************************************/

/************************************************************************************************************************
* | **モード名** | **性質** | ************************特徴***********************|
* | ------------ | -------- | -------------------------------------------------- |
* | フローティング入力     | デジタル入力 | ピンのレベルを読み取ることができ、ピンがフローティング状態の場合、レベルは不確定である           |
* | プルアップ入力     | デジタル入力 | ピンのレベルを読み取ることができ、内部にプルアップ抵抗が接続され、フローティング状態のときはデフォルトで高レベル |
* | プルダウン入力     | デジタル入力 | ピンのレベルを読み取ることができ、内部にプルダウン抵抗が接続され、フローティング状態のときはデフォルトで低レベル |
* | アナログ入力     | アナログ入力 | GPIOが無効で、ピンが内部ADCに直接接続される                      |
* | オープンドレイン出力     | デジタル出力 | ピンのレベルを出力でき、高レベルは高抵抗状態で、低レベルはVSSに接続される        |
* | プッシュプル出力     | デジタル出力 | ピンのレベルを出力でき、高レベルはVDDに接続され、低レベルはVSSに接続される           |
* | マルチプレックスオープンドレイン出力 | デジタル出力 | オンチップ周辺機器によって制御され、高レベルは高抵抗状態で、低レベルはVSSに接続される        |
* | マルチプレックスプッシュプル出力 | デジタル出力 | オンチップ周辺機器によって制御され、高レベルはVDDに接続され、低レベルはVSSに接続される           |
* フローティング入力、プルアップ入力、プルダウン入力のこの3つのモードの回路構造は基本的に同じであり、違いは上下のプル抵抗の接続にある
* オープンドレイン出力とプッシュプル出力のこの2つの回路構造も基本的に同じであり、違いはオープンドレイン出力の高レベルが高抵抗状態であり、駆動能力がないことである
* マルチプレックスオープンドレイン出力とマルチプレックスプッシュプル出力のこの2つのモードは通常のものとほぼ同じであり、ただしマルチプレックス出力であり、ピンのレベルはオンチップ周辺機器によって制御される
* アナログ入力モードはデジタル入力機能をオフにする唯一のモードであり、他のモードではデジタル入力が有効である
************************************************************************************************************************/ 


/************************************************************************************************************************
* uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
* GPIO_ReadInputDataBitこの関数は入力レジスタの特定のポートの入力値を読み取るために使用される
* uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
* GPIO_ReadInputDataこの関数は全体の入力データレジスタを読み取り、戻り値はuint16_tであり、16ビットのデータであり、各ビットは1つのポートの値を表す
* uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
* GPIO_ReadOutputDataBitこの関数は出力データレジスタの特定のビットを読み取るために使用される。原則として、これはポートの入力データを読み取るために使用されるものではなく、この関数は一般的に出力モードで使用され、自分の出力が何であるかを確認するために使用される
* uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
* GPIO_ReadOutputDataこの関数は全体の出力レジスタを読み取るために使用される
************************************************************************************************************************/

uint8_t Key_Num;

int main(void)
{
	/***********************************************************************************
		GPIO入力
	***********************************************************************************/
	LED_Init();
	Key_Init();
	
	while(1)
	{
		Key_Num = Key_GetNum();
		if(Key_Num == 1)
		{
			LED1_Turn();
		}
		if(Key_Num == 2)
		{
			LED2_Turn();
		}
		
	}

}

LED.c#
#include "stm32f10x.h"                  // デバイスヘッダー
#include "LED.h"

void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);//高レベルに設定
}

void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}

void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
}

void LED1_Turn(void)
{
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_1);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	}
}

void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}

void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_2);
}

void LED2_Turn(void)
{
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_2);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);
	}
}


key.c#
#include "Key.h"

void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//プルアップ入力
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
		Delay_ms(20);
		KeyNum = 1;
	}
	
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
		Delay_ms(20);
		KeyNum = 2;
	}
	
	return KeyNum;
}

GPIO 使用方法のまとめ

クロックを初期化する
構造体を定義する
構造体に値を設定する
GPIO_Init 関数で指定された GPIO 周辺機器を初期化する
GPIO の 8 つの主要な関数を読み書きする

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。