DCマウス研修(移行中)

マイクロマウス研修[5]タイマ割り込み

DCマウス研修(移行中)

こんにちは。koraです。

今回はタイマ割り込みを実装します。割り込みとは、マイコンで実行中のプログラムに一時的に割り込んで、別の処理を実行する機能です。タイマ割り込みを使うことで、一定周期でセンサを読み取ったりモータに指示を出したりして、マイクロマウスをリアルタイムで制御することが可能になります。

タイマ割り込みの準備

init.c

Step7のinit.cからinit_cmt()関数をコピーして、自作プロジェクトのinit.cに貼り付けます。また、init_all()関数内にinit_cmt();を追加して、init_all()からタイマ割り込みの初期化を呼び出せるようにします。

CMTはコンペアマッチタイマと言い、一定周期で割り込み処理を行うことができる機能です。init_cmt()関数内ではCMT0~2の、3つのタイマを初期化しています。この初期化で、CMT0は1kHz、CMT1は4kHz、CMT2は2kHzで割り込みが発生する設定になります。モータの制御に使うのはCMT0です。CMT1とCMT2は今後センサーの処理に使用します。

intprg.c

init_cmt()の設定で、intprg.cファイル内のExcep_CMT0_CMI0()関数が1kHzで呼び出されるようになります。今後、多様な処理を割り込みの中で実行したいので、Excep_CMT0_CMI0()関数から、別の関数を呼び出して実際の処理を行います。

#pragma section IntPRGの下に、次の行を追加します。

extern int_cmt0();

そして、void Excep_CMT0_CMI0(void){ } を次のように書き換えます。

void Excep_CMT0_CMI0(void){
    int_cmt0();
}

interrupt.c

「新しいファイルを追加」から、interrupt.cというファイルを作ります。今回はテストのため、下のような簡単な処理のみにします。(本番用のプログラムでは、速度と旋回速度を制御するコードに書き換えます。)

#include "iodefine.h"
#include "glob_var.h"
#include "portdef.h"

void int_cmt0(void)
{
    MOT_OUT_R =(short)(240.0 * Duty_r);
    MOT_OUT_L =(short)(240.0 * Duty_l);
}

glob_var.hとglob_var.c

グローバル変数を複数のファイル間で共有する場合、ヘッダファイルでextern付きの宣言をして各ソースファイルにインクルードし、実態を持たせる1つのソースファイルでextern無しの定義します。

しかし、このサンプルプログラム(Step7)では何十個もグローバル変数を使います。ヘッダファイルとソースファイルに同じ変数名を何十個も書くのは面倒です。

そこで、マクロでexternの有り無しを制御し、実態を持たせるソースファイルにインクルードされたときのみexternが外れるようにします。

glob_var.hに、

#ifdef _GLOB_VAR
#define GLOBAL
#else
#define GLOBAL extern
#endif

GLOBAL float Duty_r; // 出力のデューティ比 [%]
GLOBAL float Duty_l; // 出力のデューティ比 [%]

と書きます。そして、glob_var.cの方に、

#define _GLOB_VAR
#include "glob_var.h"

と書きます。

テスト

my_hm_starterkit.cファイルに、

#include "glob_var.h"

を追加して、main関数を次のように書き換えます。

init_all(); // 初期化

MOT_POWER_ON; // モータドライバの電源ON
MOT_CWCCW_R = MOT_R_FORWARD; // モータの回転方向を指定
MOT_CWCCW_L = MOT_L_FORWARD; // モータの回転方向を指定

Duty_r = 0.5; // PWMのDuty設定
Duty_l = 0.5; // PWMのDuty設定

グローバル関数Duty_rとDuty_lに値が代入されることで、タイマ割り込みで呼び出されるint_cmt0関数に値が渡され、PWMとして出力されます。Duty_rとDuty_lの値を0.0~1.0の値に設定することによって、モータの回転速度が変化します。

次回

タイマ割り込みでモータが動かせるようになりました。エンコーダ、ジャイロ、光センサの情報を反映できるようにしたいところですが、その前に、センサの情報をPCに表示するため、シリアル通信を使えるようにしたいと思います。

タイトルとURLをコピーしました