SPモーターを決め角度だけ回す
続いて、SPモーターの特長、決めた角度だけ回す方法も実験してみます。
前回の回転プログラムに追加するだけでやってみます。
制御方法
タイマーW割り込み関数を利用します。
コンペアマッチのたびに割り込みがかかるので、この割り込みのときに回数を数えます。
決め角度が来るとタイマーカウンタを停止して保持させます。
レジスタ設定
割り込みする設定を加えます。
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | OVIE | - | - | - | IMIED | IMIEC | IMIEB | IMIEA |
オーバーフロー 割り込み |
- | - | - | マッチDで 割り込み |
マッチCで 割り込み |
マッチBで 割り込み |
マッチAで 割り込み |
|
設定値 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
コンペアマッチA、Bで割り込み設定にします。
TW.TIERW.BYTE=0x03 (0000 0011)
プログラム-2
プログラム2 (決め角度にSPモーターを回転させる
HP_SPmoterANG
#include<3664.h>
int cnt=0;
void int_timerw (void){ // この関数名の前に必ず void が必要
cnt++;
if(cnt>12) TW.TMRW.BYTE=0x00; //カウント停止
//7.5度×12=90度回転
TW.TSRW.BIT.IMFA = 0; // 検知フラグを戻して再開
TW.TSRW.BIT.IMFB = 0; // 検知フラグを戻して再開
}
void main(void)
{
DI;
TW.TCRW.BYTE=0xB9; // クロックとして、内部クロックの1/8( 2MHz ),マッチAでタイマクリアあり
// FTIOAの初期値は1
// FTIOBの初期値は0
// FTIOCの初期値は0
// FTIODの初期値は1
TW.TCNT=0x0000; // TCNの初期化
TW.TIOR0.BYTE=0x33; //マッチA,BでFTIOへトグル出力
TW.TIOR1.BYTE=0x33; //マッチC,DでFTIOへトグル出力
TW.TIERW.BYTE=0x03; // 000 0011 割り込み設定 マッチA マッチB
int Ha=11000;
int Hb=5500;
TW.GRA=Ha;
TW.GRB=Hb;
TW.GRC=Ha;
TW.GRD=Hb;
TW.TMRW.BYTE=0x80; //カウント開始
EI;
while(1) ;
}
コンペアマッチのたびに1ステップ回転するので、コンペアマッチ割り込みの回数を数えると回転角度がわかるはずです。
グローバル変数 cnt をつくり、コンペアマッチA,Bの両方で割り込みをして、割り込み関数内でカウントします。
TW.TIERW.BYTE=0x03 ( 000 0011 割り込み設定 マッチA とマッチBで割り込み)
一度割り込み関数を呼び出すと 検知フラグをクリアします。
TW.TSRW.BIT.IMFA = 0 // 検知フラグを戻して再開
TW.TSRW.BIT.IMFB = 0
これを忘れると、この割り込み以後動きません。
このSPモーターは1ステップ7.5度なので
1ステップ7.5度 × 割り込み12回分 = 90度回転 になります。
実行結果
実行するたび90度回転します。停止後は保持となるので、手では回らないほと強力に保持トルクが働きます。
このSPモーターは1ステップ7.5度なので、コンペアマッチA,Bがあわせて12回で、
7.5度×12=90度回転 になります。
まとめ
タイマーWを使ってSPモーターの回転をやってみましたが、とりあえず回してみたという感じです。
実際はこの方法で考えると、逆転させるにはレジスタ設定を書き換えなければならず、実用的ではないことがわかります。
タイマーWが3664Fでは一番設定が多いタイマー最高峰ですが、SPモーターを制御するにはタイマー機能の設定だけでは不十分です。PWM波形を3つ出せる機能はありますが、SPモーター制御の機能はもともと考えられていません。
またモーター1つにタイマー1つ使用というのも非効率ですし、たとえタイマーの数が多くても、ロボットなど多軸を扱うにはマイコン付属のタイマーの数では足りなくなります。
要するに、タイマー機能に頼っているのでは限界がすぐきます。
やはり、定期的な割り込みなどを使用し、汎用SPモーター制御関数などを作る必要があるみたいです。
- twtter
- google+
- hatena