STM32(1)-GPIOを再検討する
stm32を初めて学ぶとき、私は何も知らず、51を理解していません。C言語があいまいです。ハードウェアとシングルチップとは何かという質問にも答えられません。恥ずかしい考えです
棚の上でアヒルを捕まえた後、急いで急いで、幸運にも定時原子に関するチュートリアルを学びましたが、それはアプリケーションに限定されていて、詳細の理解の欠如はトランス状態でした。次に、FPGAをゆっくりと使用してタイミングを理解し、他のハードウェアを使用します。。。。。私は自分の考えと多くの問題についての考えを持っています。以前のように、ブラックテクノロジーを使用したライブラリ関数はもう見ていません。0011のシリーズを見て
純粋な野生の白なので、被写体を理解するのは困難であり、まだ欠陥があります、王海漢。
gpioからstm32について本当に話したい場合は、M3カーネルと命令セットをバイパスしてテキストを伝えるのは適切ではありません。結局のところ、ビジターに関心がある場合は、M3の信頼できるガイドを参照することをお勧めします。 ARMアーキテクチャの理解は、これらの問題を詳細に検討するには不十分です。アプリケーションから始めましょう-最初のGPIO
ハードウェア機器:時間厳守の原子戦艦V3 STM32F103zet6
GPIO
(説明シーケンス
1ライブラリ関数
2レジスタ
3ビット演算
)
1、ライブラリ関数
GPIO_Init()
すべてはinitと不可分です
見る
1 void GPIO_Init(GPIO_TypeDef * GPIOx、GPIO_InitTypeDef * GPIO_InitStruct) 2 / * 最初のパラメーターはピンのグループであり、各グループには16個のピンがあり、各グループには異なるレジスター構成アドレスがあり、2番目のパラメーターはデータ構造、つまりこのデータ構造に基本構成情報を入れ、この構造を構成用の関数に渡します* / 3 // データメカニズムは次のように表すことができます 4 typedef struct 5 { 6 uint16_t GPIO_Pin; // pin No. 7 GPIOSpeed_TypeDef GPIO_Speed; // 構成速度 8 GPIOMode_TypeDef GPIO_Mode; // 作業モード 9 } GPIO_InitTypeDef; 10 11 // 構成変数と作業モードがGPIOSpeed_TypeDefとGPIOMode_TypeDef である列挙型変数 12 // モード定義が続く 13 typedef enum 14 {GPIO_Mode_AIN = 0x0、// アナログ入力 15 GPIO_Mode_IN_FLOATING = 0x04、// フローティング入力モード、デフォルト 16 GPIO_Mode_IPD = 0x28、// プルアップ/プルダウン入力モード 17 GPIO_Mode_IPU = 0x48、// 予約済み 18 GPIO_Mode_Out_OD = 0x14、// 一般的なオープンドレイン出力 19 GPIO_Mode_Out_PP = 0x10、// 一般的なプッシュプル出力 20 GPIO_Mode_AF_OD = 0x1C、// 多重(オープンドレイン)出力 21である GPIO_Mode_AF_PP = 0x18の // 多重(プッシュプル)出力 22である ;} GPIOMode_TypeDef 23である // 最終的に速度を定義
24のtypedef 列挙 25 { 26で GPIO_Speed_10MHz = 1 、 27 GPIO_Speed_2MHz、 28 GPIO_Speed_50MHz 29 } GPIOSpeed_TypeDef;
3つの定義がstm32IOポートの半分をサポートしていますが、これはどのようにして実現できますか?
最初にパラメータ情報を見てみましょう
GPIO_TypeDef * GPIOx
typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef;
明らかに、これはレジスタを関数にロードすることです
次へ
GPIO_InitStruct
typedef struct { uint16_t GPIO_Pin; / * !<構成するGPIOピンを指定します。 このパラメーターには、@ ref GPIO_pins_define * / GPIOSpeed_TypeDef GPIO_Speedの任意の値を指定できます。 / * !<選択したピンの速度を指定します。 このパラメーターは、@ ref GPIOSpeed_TypeDef * / GPIOMode_TypeDef GPIO_Modeの値にすることができます。 / * !<選択したピンの動作モードを指定します。 このパラメーターは、@ ref GPIOMode_TypeDef * / } GPIO_InitTypeDef;の値にすることができます。
3つの定義ピン速度作業モード、3つの定義は3つのマクロ定義につながります
IS_GPIO_ALL_PERIPH(GPIOx);
#define IS_GPIO_ALL_PERIPH(PERIPH)(((PERIPH)== GPIOA)|| \
((PERIPH)== GPIOB)|| \
((PERIPH)== GPIOC)|| \
((PERIPH)== GPIOD)|| \
((PERIPH)== GPIOE)|| \
((PERIPH)== GPIOF)|| \
((PERIPH)== GPIOG))
このマクロ定義の機能は、パラメーターPERIPH(ペリフェラル)をチェックし、パラメーターPERIPHがGPIOX(A ... G)ベースアドレスの1つであるかどうかを判別することです。それらの1つがtrueである限り、値はtrueであり、それ以外の場合はfalseです。
IS_GPIO_MODE(GPIO_InitStruct-> GPIO_Mode);
#define IS_GPIO_MODE(MODE)(((MODE)== GPIO_Mode_AIN)||((MODE)== GPIO_Mode_IN_FLOATING)|| \
((MODE)== GPIO_Mode_IPD)||((MODE)== GPIO_Mode_IPU)|| \
( ((MODE)== GPIO_Mode_Out_OD)||((MODE)== GPIO_Mode_Out_PP)|| \
((MODE)== GPIO_Mode_AF_OD)||((MODE)== GPIO_Mode_AF_PP))
最初のモードと同じ8つの作業モードは、1つが当てはまる限り当てはまります。
IS_GPIO_PIN(GPIO_InitStruct-> GPIO_Pin);
#define IS_GPIO_PIN(PIN)((((PIN)&(uint16_t)0x00)== 0x00)&&((PIN)!=(uint16_t)0x00))
(PIN)&(uint16_t)0x00)== 0x00 PINと0x00が0の場合、それは真であり、この方程式は常に真であり、PINの値が何であれ、結果は0x00です。
(PIN)!=(Uint16_t)0x00)PIN = 0x00がtrueでない場合はtrue、
&&はtrueとfalseの両方を意味します。
全体として、2番目の文が0でない場合、最初の文は常にtrueであり、この式の条件は、PINの値を0x00にできないことです。
レジスターを通じて、4ビットごとにio速度と動作モードを制御することがわかりました(以下で必要)
assert_param()のマクロは上で定義され(私
はそれを保存しました)、以下で必要です。それが何であるかを見てみましょう
。???実際、これはこれを適用するのに役立たないアサーションメカニズムです。
#ifdef USE_FULL_ASSERT #define assert_param(expr)((expr)?(void)0:assert_failed((uint8_t *)__ FILE__、__LINE__)) / * エクスポートされた関数---------------- --------------------------------------- * / void assert_failed(uint8_t * file、uint32_t line ); #else の#define assert_param(expr)は((無効)0)
これは、設計者がデバッグする興味深いデバッグプログラムです。マクロが1の場合、関数が無効の場合、関数は1を返し、プログラムは実行を継続します。戻り値が0の場合、実行がその場所に戻るという問題があります(三眼鏡演算子を参照)。
これは、assert_param()を含む関数が無効であることを意味します。
ボイド(* GPIO_TypeDef GPIOX、GPIO_InitTypeDef * GPIO_Init GPIO_InitStruct) { / * 各種変数を初期化する* / のuint32_t電流モード = 0x00で、currentpin = 0x00で、pinpos = 0x00で、POS = 0x00の; のuint32_t tmpreg = 0x00で、pinmask = 0x00の; // のための電流モード一時的なLCIR // currentpinは設定されたピン位置を保存するために使用されます // pinposは現在の操作ピン番号を保存するために使用されます // posは現在の操作ピン位置を保存するために使用されます // tmreg現在のCIR // ピンマスク // 判定パラメーター assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); assert_param(IS_GPIO_MODE(GPIO_InitStruct--> GPIO_Mode)); assert_param(IS_GPIO_PIN(GPIO_InitStruct- > GPIO_Pin)); / * ----------------------------モード設定- ---------------------- * / // 構成情報のモード情報を取得し、その下位4ビットを 取得します currentmode =((uint32_t)GPIO_InitStruct-> GPIO_Mode )&((uint32_t)0x0F ); if(((((uint32_t)GPIO_OInitStruct-> GPIO_Mode)&((uint32_t)0x10))!= 0x00)// 出力モード { // 判定パラメーター assert_param(IS_GPIO_SPEED(GPIO_InitStruct- )); // currentmodeの下位2ビットに速度情報を入力しますcurrentmode | =(uint32_t)GPIO_InitStruct-> GPIO_Speed; } if(((uint32_t)GPIO_InitStruct-> GPIO_Pin&((uint32_t)0x00FF))!= 0x00)// ピンが定義されている { // 現在のCRL保存 tmpreg = GPIOx-> CRL; // 下位8ビットをサイクル for(pinpos = 0x00 ; pinpos < 0x08 ; pinpos ++ ) { // 現在のピン、その位置1 pos =((uint32_t)0x01)<< pinpos; // ピン情報で現在のピンを読み取るcurrentpin = (GPIO_InitStruct-> GPIO_Pin)&pos; if(currentpin == pos) // 現在のピンが構成情報に存在する場合 { pos = pinpos << 2 ; // pos =ピン番号x2 pinmask =((uint32_t)0x0F)<< pos; // 1111 <<ピン番号x2、CRLの構造によれば、 tmpreg&=〜pinmask; を理解するのは簡単です// 現在のビットにすること動作クリアCRL 0 tmpreg | =(電流モード<< POS); // 設定された現在の動作CRL-ビット IF(GPIO_InitStruct-> == GPIO_Mode GPIO_Mode_IPD)// ポートで設定された高 { GPIOX - > BRR =(((uint32_t)0x01)<< pinpos); } else { if(GPIO_InitStruct-> == GPIO_Mode GPIO_Mode_IPU) // ポートクリア0 { GPIOX - > BSRR =(((のuint32_t)は0x01)<< pinpos); } } } } GPIOX - > CRL = tmpreg; }
同様8高く、処理モード、及びBRRプラス8つの注目BSRR場合
GPIO_DeInit()の処理方法もGPIOX呼び出し関数を探すのに非常にシンプルで大まかなものであり、関数の本質はクロックリセットです。
IOポートの各グループには、次の7つのレジスタが含まれています。つまり
、GPIOのグループの合計16個のIOポートを制御できる7つのレジスタです。
2つの32ビット構成レジスタ(GPIOx_CRL、GPIOx_CRH)、
2つの32ビットデータレジスタ(GPIOx_IDRおよびGPIOx_ODR)、
32ビットビット/リセットレジスタ(GPIOx_BSRR)、
16ビットのリセットレジスタ(GPIOx_BRR)
32ビットのロックレジスタ(GPIOx_LCKR)。
モデルは持っています
─入力フローティング─入力プルアップ─入力プルダウン─アナログ入力─オープンドレイン出力─プッシュプル出力─プッシュプル多重機能
ioポートに関連するすべてのレジスタはAPB2バスにマウントされています
ビットバンド操作
エム、。。。この記事は続きます
周莞の時間を作る
stm32(0)で32の内務について話す予定です