5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

STM32 nucleoを使う (3) EXTI割り込み

Posted at

#はじめに
SWの検出を割り込みで行うプログラムについて記述します。
前回のプログラムを改造していきます。
STM32にはGPIOの割り込みはEXTIを使います。EXTIとは拡張割り込み/イベントコントローラのことです。信号の立上り/立下りの検出を行い割り込みを発生させます。

#EXTIの設定
iocファイルのSwAndLedTest.iocを開きます。
01.png
GPIOのコンフィグレーションを開きます。
GPIOモードをFalling edgeからRising/Falling Edgeに変更します。
02.png
NVICのコンフィグレーションを開き、EXTI Line[15..10] interruptsにチェックを入れます。
外部割込みを有効とします。
03.png
iocファイルを保存するとコードを生成するか確認が入るので、Yesを選択しコード生成をします。

#割り込みハンドラ
割り込みの処理は割り込みハンドラに記述します。
stm32f3xx_it.cに各割り込みハンドラがありますので、EXTI line[15:10]の割り込みハンドラのEXTI15_10_IRQHandlerを探します。内容は以下のようになっています。
ここの/* USER CODE BEGIN EXTI15_10_IRQn 0 /と/ USER CODE END EXTI15_10_IRQn 0 */に割り込み処理を書いてもよいですが、もう少し内容を見てみます。

void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */

  /* USER CODE END EXTI15_10_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}

HALのEXTIの割り込みハンドラHAL_GPIO_EXTI_IRQHandlerを呼んでいます。

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

割り込みをクリアする関数とEXTIのコールバック関数HAL_GPIO_EXTI_Callbackを呼んでいます。
HAL_GPIO_EXTI_Callbackの内容は以下の通り。

/**
  * @brief  EXTI line detection callback.
  * @param  GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
}

このコールバック関数にはweakシンボルが付いています。他でHAL_GPIO_EXTI_Callbackが定義されていない場合はweakが付いた関数が使われますが、他で定義されている場合は使われません。
割り込み処理を記述するには、HAL_GPIO_EXTI_CallbackのコメントにあるようにユーザーファイルにHAL_GPIO_EXTI_Callbackを作成するのが良いでしょう。

#HAL_GPIO_EXTI_Callbackの作成
main.cの/* USER CODE BEGIN 0 /と/ USER CODE END 0 */の間に記述します。
前と同じだと違いが判りませんので、押している間は消灯するように変更します。

/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == B1_Pin)
  {
    if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == GPIO_PIN_RESET)
    {
      HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
    }
    else
    {
      HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
    }
  }
}
/* USER CODE END 0 */

pin15-10の割り込みが共通なので最初にB1による割り込みかどうかを判定しています。
立下り/立上りの割り込みとしたので、ピンの状態でLEDの点灯/消灯を決定しています。

mainルーチンからは処理を削除します。
何もしない無限ループとします。

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    ;
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

#実行
RUNボタンで実行します。
起動時は割り込みが発生していないのでLEDは消灯しています。
ボタンを押し離したときにLEDが点灯します。
その後は、押すと消灯し離すと点灯します。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?