STM32 nucleoを使う (3) EXTI割り込み
はじめに
SWの検出を割り込みで行うプログラムについて記述します。
前回のプログラムを改造していきます。
STM32にはGPIOの割り込みはEXTIを使います。EXTIとは拡張割り込み/イベントコントローラのことです。信号の立上り/立下りの検出を行い割り込みを発生させます。
EXTIの設定
iocファイルのSwAndLedTest.iocを開きます。
GPIOのコンフィグレーションを開きます。
GPIOモードをFalling edgeからRising/Falling Edgeに変更します。
NVICのコンフィグレーションを開き、EXTI Line[15..10] interruptsにチェックを入れます。
外部割込みを有効とします。
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が点灯します。
その後は、押すと消灯し離すと点灯します。
Author And Source
この問題について(STM32 nucleoを使う (3) EXTI割り込み), 我々は、より多くの情報をここで見つけました https://qiita.com/toshidln/items/496097ecc0f6a650a6eb著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .