2013年11月26日火曜日

STM32F1 ピン変化割り込み

STM32F1のピン変化割り込み EXTIの初期化方法について

今回は僕のボードの関係でPD1の立ち上がりエッジで割り込みが入るように設定する

クロックの供給

AFIOとGPIOのクロックを有効化する
一般的な有効化と同じ手順
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,   ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,  ENABLE);

今回はUART5 RXを使うためにGPIODを
JTAGを無効化するためにAFIOを 
それぞれクロックを供給していたので追加のコードは必要なかった
/*
  JTAGを無効化するにはAFIOを初期化して
  AFIO->MAPR = _BV(26);
  として26bitを立ててやればJTAGとSWJの両方を無効化できる
*/


GPIOの初期化

これも一般的な初期化の方法と同じ
GPIO_InitTypeDef GPIO_InitStructure;
で構造体を確保し
GPIO_InitStructure.GPIO_Pin = _BV(1);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
でPD1を入力モードにした
IPUでもIPDでも問題ないはず

EXTIの有効化

GPIO_EXTILineConfig関数を使う
第一引数にポートを 第二引数にピンを指定する
これは一般的なGPIOAや_BV(0)といった指定方法ができない
GPIO_PortSourceGPIOAやGPIO_PinSource0というマクロを使う
今回はGPIODのピン1を使うので
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource1);
という感じ
/*
  ヘッダファイルを見てみるとGPIO_PortSourceGPIOAは ((uint8_t)0x00) が Bは0x01 Cは0x02
  GPIO_PinSource0は ((uint8_t)0x00) が 1は0x01 2は0x02
  という感じで指定されている

  一般的なGPIOAやGPIOBはペリフェラルのポインタが
  _BVは #define _BV(n) ( 1 << (n) ) という指定でビットシフトしている
  そのため基本的にGPIO_PortSourceとGPIOxの互換性は全くない ピン指定も同じ
*/


EXTIの初期化

EXTI_Init関数を使う
EXTI_InitTypeDefポインタを引数にする
中身は 
    EXTI_Line
    EXTI_LineCmd
    EXTI_Mode
    EXTI_Trigger
の4個

LineはEXTI_Line0からEXTI_Line19の20個から選択
ピン0がLine0 ピン15がLine15という感じで割り付けられている
また16,17,18,19はそれぞれ電圧計国やRTCのアラーム等に設定されている

LineCmdは有効化するか否かをENABLE/DISABLEで選択
Modeは割り込みかイベントを選択 それぞれEXTI_Mode_InterruptとEXTI_Mode_Event
Triggerはどちらのエッジを使うか 
    EXTI_Trigger_Risingで立ち上がり
    EXTI_Trigger_Fallingで立ち下がり
    EXTI_Trigger_Rising_Fallingで両方
という感じ

今回はピン1の立ち上がりエッジで割り込み という設定なので
EXTI_Line1 ENABLE EXTI_Mode_Interrupt EXTI_Trigger_Rising
で初期化する

// PB1は立ち上がりで PC1は立ち下がりで とかの割り込みはどうするんだろう?

NVICの設定

NVICの設定は一般的な設定と同じ
ここは省略する
NVICのチャンネルはEXTI1_IRQn等を設定する

割り込みハンドラ

割り込みで呼び出される関数
void EXTI1_IRQHandler(void)
となる
中で EXTI_ClearITPendingBit(EXTI_Line1); でペンディングビットをクリアする必要がある
EXTI_GetITStatusを使ってLine1のペンディングビットを確認することができるけど EXTI1_IRQHandlerはLine1割り込みしか呼ばれないはずなのでGetで確認は不要のはず



上記の手順でEXTI割り込みが使えるようになる
しかし、ピン変化割り込みハンドラが呼ばれても、どのラインの割り込みか はわかるが
どのポートが割り込み操作のトリガになったかは判別できない気がする
例えばPA1とPB1の両方に割り込みを設定した場合、Px1が動いた と言うのはわかるんだが、それがAなのかBなのかは判断できない

あとPA1は立ち上がり PB1は立ち下がり とかだとRising_Fallingにして、ハンドラで確認する必要があるのか?

気が向いた時にでも調べておく必要がある

0 件のコメント:

コメントを投稿