割り込み:TIM3_IRQHandler
1.本日の内容
(1) STM32マイコン(nucleof401RE)を使用しLEDの点灯/消灯を制御する。
(2) 割り込み処理を行う場合、下記2つの関数がある。
・void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
・void TIM3_IRQHandler(void)
TIM3_IRQHandlerの使い方と、2つの関数の違いについて説明する。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
の実装方法などは下記を参照
・STM32マイコン20(割り込み処理部分を別ファイルに作成) - Project_OKI’s diary
・STM32マイコン_9(タイマ割り込み:LED点滅) - Project_OKI’s diary
・目次
2.内容
(1) やる内容の詳細
・void TIM3_IRQHandler(void)を使用し、割り込み処理を実装する。
・割り込み処理によって、LEDを1秒ごとに点灯/消灯を繰り返す。
・TIM3_IRQHandlerとHAL_TIM_PeriodElapsedCallbackの違いについて説明する。
(メリットデメリットなど)
(2) CubeMXの設定
CubeMXの設定は、下記記事と同じ。
→STM32マイコン_9(タイマ割り込み:LED点滅) - Project_OKI’s diary
(3) プログラムの作成
typedef.hファイルの作成
/** * @file typedef.h * @brief 基本型変数定義 */ #ifndef TYPEDEF_H #define TYPEDEF_H ///BOOL型(ない場合のみ) #undef false #undef true typedef enum{false=0 ///<為 ,true ///<真 }bool; ///ONOFF型 typedef enum{OFF=0 ///<OFF指定 ,ON ///<ON指定 }ONOFF; ///SIGNAL型 typedef enum{LOW=0 ///<信号をLOWにする ,HIGH ///<信号をHIGHにする。 }SIGNAL; ///基本型定義 typedef signed char SCHAR; ///<8bit変数 符号有り typedef unsigned char UCHAR; ///<8bit変数 符号無し typedef signed short SSHORT; ///<16bit変数 符号有り typedef unsigned short USHORT; ///<16bit変数 符号無し typedef signed int SINT; ///<int型 符号有り(8bitサイズ) typedef unsigned int UINT; ///<int型 符号無し(8bitサイズ) typedef signed long SLONG; ///<32bit変数 符号有り typedef unsigned long ULONG; ///<32bit変数 符号無し #endif
led.cファイルの作成
/** ******************************************************* */ /** * @file led.c * @brief LED制御処理 * @brief Compiler : Atollic True Studio for STM32 9.0.0 * @brief CPU : STM32F401 */ /** ******************************************************* */ /* ************************************************************ */ // インクルード ファイル /* ************************************************************* */ #include "main.h" #include "led.h" //LED制御ヘッダファイルのインクルード /** ************************************************************ */ /** 外部定義変数 */ /** ************************************************************ */ LEDCTRL ledctrl; //LED制御構造体 /** ******************************************************* */ // 関数の作成 /** *************************************************** */ /** *********************************************** */ /** * MODE1 LED点灯/消灯処理(LED1を点灯/消灯(反転)する処理) * @param void : none * @return void : none
*/ /** ************************************************ */ void Led1Blink() { ///LED点滅フラグ確認 if(ledctrl.led1blif == true){ if(Led1State == HIGH){ ///LEDがHIGHの時 Led1(LOW); ///LED1をON }else{ ///LED1がLOWの時 Led1(HIGH); ///LED1をOFF } } } /* **** ファイルの最後 ( led.c ) ******************************** */
led.hファイルの作成
/** ******************************************** */ /** * @file led.h * @brief LED制御ヘッダ * @brief Compiler : Atollic True Studio for STM32 9.0.0 * @brief CPU : STM32F401RE * */ /** ******************************************** */ ///多重インクルード防止 #ifndef LED_H ///<LED未定義? #define LED_H ///<LED_H 定義済み!! /* ****************************************************** */ // インクルード ファイル /**************************************************** */ #include "typedef.h" //基本型変数定義ヘッダファイルのインクルード /* **************************************************** */ // 定数値の定義 /* **************************************************** */ /* ************************************************** */ // 式、関数の置き換え /* **************************************************** */ ///Bit変換:出力 #define OutGPIOBit(port,pin,data) (port->ODR=((port->ODR&~(pin))|((data==0) ? 0 : (pin)))) ///GPIO設定 ///Bit変換:入力 #define InGPIO(port,pin) ((((port->IDR)&(pin))==0)?0:1) ///LED ON/OFF関数の作成 #define Led1(dt) OutGPIOBit(LED1_GPIO_Port,LED1_Pin,dt) ///LEDステート確認用変数 #define Led1State InGPIO(LED1_GPIO_Port,LED1_Pin) /* ****************************************************** */ // 構造体の定義 /* ************************************************ */ //MODE LEDステート管理用構造体 typedef struct{ //LED動作ステート USHORT led1blicout;///LED点滅時間カウント用変数 bool led1blif; ///LED1点滅ステート:true:LED点滅 false:LED点滅しない } LEDCTRL; /* **************************************************** */ // 外部変数の定義 /* ********************************************* */ extern LEDCTRL ledctrl; ///LED制御構造体 /* ********************************************** */ // 関数のプロトタイプ宣言 /* ********************************************* */ extern void Led1Blink(); ///LED1を点灯/消灯(反転)関数 #endif ///<LED_H 未定義 End /* **** ファイルの最後 ( led.h ) ************************* */
main.cファイルの作成
/* USER CODE BEGIN Includes */ #include "typedef.h" #include "led.h" /* USER CODE END Includes */
/* USER CODE BEGIN 2 */ //TIM3開始 HAL_TIM_Base_Start_IT(&htim3); //LED点滅開始 ledctrl.led1blif = true; /* USER CODE END 2 */
stm32f4xx_it.cファイル (割り込みについて記載、CubeMXで自動生成される。)
ここに、TIM3_IRQHandlerが自動的に作成される。
TIM3_IRQHandlerのUSER CODEに自分が作成した割り込みの関数などを実行する。
/* USER CODE BEGIN Includes */ #include "typedef.h" ///< 基本型 #include "IntR.h" ///< 割り込み /* USER CODE END Includes */
/* USER CODE BEGIN TIM3_IRQn 1 */ Tim3_Int(); ///< Tim割り込み処理 /* USER CODE END TIM3_IRQn 1 */
IntR.cファイルの作成
/** *********************************************** */ /** * @file IntR.c * @brief 割り込み制御 * @brief Compiler : CubeIDE * @brief CPU : STM32F401RE */ /** *********************************************** */ #include "typedef.h" ///< 基本型 #include "IntR.h" ///< 割り込み制御 #include "main.h" ///< メイン処理 #include "led.h" ///< led制御 /**************************************************************** */ /** グローバル変数定義 */ /**************************************************************** */ ///構造体宣言 volatile TTimCtrlInf GTimCtrlInf; ///ハンドラ宣言 extern TIM_HandleTypeDef htim3; /* *************************************************************** */ /** STM32 関数作成 */ /* *************************************************************** */ /** ************************************************************** */ /** * TIM3割り込み処理(1msごとに割り込み) * @param void : None * @return void : None */ /** ************************************************************** */ void Tim3_Int() { ///1ms経過毎の処理 GTimCtrlInf.uc1sCnt++; ///< 1sカウンタを更新 ///1s時実行 if(GTimCtrlInf.uc1sCnt >= TIM1S_CNT_VAL){ GTimCtrlInf.uc1sCnt = 0; ///< 1sカウンタ初期化 Led1Blink(); ///< LED1反転処理 } }
IntR.hファイルの作成
/** *********************************************** */ /** * @file IntR.h * @brief 割り込み制御 * @brief Compiler : CubeIDE * @brief CPU : STM32F401RE * @date $LastChangedDate : 2023/03/21 $ */ /** *********************************************** */ #ifndef INTR_H #define INTR_H #define TIM1S_CNT_VAL 1000 ///< 1sタイマ値(1ms*1000=1s) /** *********************************************** */ /* 構造体の定義 */ /** *********************************************** */ /// タイマ制御情報 構造体の定義 typedef struct { UINT uc1sCnt;///< 1s カウンタ } TTimCtrlInf; /** *********************************************** */ /* 外部変数の定義 */ /** *********************************************** */ extern volatile TTimCtrlInf GTimCtrlInf; ///< タイマ制御情報 /** *********************************************** */ /* プロトタイプ宣言 */ /** *********************************************** */ extern void Tim3_Int(); #endif
(4) プログラムの説明
(5) TIM3_IRQHandlerとHAL_TIM_PeriodElapsedCallbackの違い
この関数を使用すると、より低レベルの割り込み処理を実装することができる。
割り込みハンドラーは、プロセッサが割り込みを受け取った際に、
以下の場合は、HALドライバより、TIM3_IRQHandlerに記載した方が良い。
・割り込みが発生して、すぐにレジスタ値を読み込んで処理をする必要がある場合。(DMAなど)
・割り込みが発生した際に直ちにデータを受信する必要がある場合
・特定のシリアル通信モードに移行するために特定のレジスタに特定の値を書き込む必要がある場合
それ以外だと基本は、HALドライバを使用した方が、コード変更が容易になり、
他のCPUへの応用もききやすい。
3.関連記事
・STM32マイコン_2(UART通信:TeraTermにHellow表示) - Project_OKI’s diary
・STM32マイコン_3(UART通信:複数文字送信) - Project_OKI’s diary
・STM32マイコン_4(NVICの設定内容) - Project_OKI’s diary
・STM32マイコン_5(スイッチ入力とLED点灯、消灯) - Project_OKI’s diary
その他:
・CubeIDEの使い方(起動~デバック実行) - Project_OKI’s diary
C言語:
・組み込みの為のC言語基礎知識1(printf) - Project_OKI’s diary
・C言語基礎知識2(for分で処理を繰り返す) - Project_OKI’s diary
・C言語基礎知識3(配列) - Project_OKI’s diary
*1:port->ODR&~(pin