IOピンでパルス生成
タイマーVの割り込み関数を使用し、パルスを発生することにします。
周期 1k[Hz] にして、0.1k[Hz] のキザミで割り込み関数を呼び出します。
この方法はTekuRobo工作室HPでも検討されていました。原理がわかりやすく説明されています。
タイマー割込みでPWMする
パルス波はON,OFFの信号なので、タイマーで定期的に実行する割り込みを利用し、その中でIOピンの出力をON,OFFする原理です。
同じ図を引用させてもらいました、とてもわかりやすく書かれています。
1度の割り込みで Cnt=0 ~ Cnt=0 の間の処理になります。
Cnt=0 ~ Cnt=1
この間の処理に出力したいピンをいくつもONにすると、多数のPWMパルスを発生することになります。
上記の図を見ると、例えば
タイマー割り込みが1ms毎に実行されるとすると、上の Cnt=0~Cnt=1 の間隔は1msになり、
- Cnt=7 までで周期は8ms。
- Cnt=3 までON(High)出力(Pio=1)
- Cnt=3~Cnt=7 までOFF(Low)出力(Pio=0)
デューティ比 0.5 のPWMパルスが原理上は発生できます。この方法で自由なパルスを発生させることができることになります。
タイマーV設定
タイマーVの割り込みを使ってIOピンでパルスを発生させてみます。
まず、内部クロックは 1/64( 250kHz )に設定します
1ms = 1kHz
0.1ms= 10kHz
割り込み間隔
1kHz(1ms) と10kHz(0.1ms)でパルス発生
内部クロック : 1/64( 250kHz )で
まずは、1kHz(1ms) と 10kHz(0.1ms) 間隔の割り込みでパルス発生を試します。
この内部クロックで1kHz(1ms) と 10kHz(0.1ms) 間隔の割り込みにするにはコンペアマッチのGRBを
1ms = 1kHz : GRB= 250kHz / 1k =250
0.1ms= 10kHz: GRB= 250kHz / 10k =25 とします。
1.10kHz(0.1ms)のパルス発生
TV.TCORB= 25 (間隔0.1msにするGRB設定値)
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | CMIEB | CMIEA | ORIE | CCLR1 | CCLR2 | CKS2 | CKS1 | CKS0 |
説明 | B割り込み | A割り込み |
オーバフロー割り込み |
カウンタクリア条件 | TCNTVクロック 設定 |
TV.TCRV0.BYTE= 0x12 (1001 0011 )
TV.TCORB= 25 (10kHz(0.1ms))
プログラム
●10kHz(0.1ms) 間隔で割り込み
ファイル名
#include <3664.h>
/*
タイマーV割り込み関数をつかったIOピンでのパルス出力
*/
unsigned char cnt=0;
void int_timerv (void){
if(cnt<4){cnt++;IO.PDR8.BIT.B1=1;}
else if(cnt<10){cnt++;IO.PDR8.BIT.B1=0;}
else{cnt=0;}
TV.TCSRV.BIT.CMFB = 0; // 検知フラグを戻して再開
}
void main()
{
EI; /* 割り込み許可*/
IO.PCR8=0xFF;
TV.TCRV0.BYTE=0x93; //(1001 0011) 1/64 (250kHz)
// TV.TCORB=25; //10kHz
TV.TCORB=250; //1kHz
while(1);
}
まずはTV.TCORB= 25 (10kHz (0.1ms) にして 10kHz(0.1ms)割り込みでのパルス発生をさせてみました。
cnt=0 ~ cnt=3 まで 1
cnt=0 ~ cnt=9 まで 0
というパルス波です。
このようなパルスなら割り込みのたびに、下のようにIOの出力を設定します。
CNT=0 | CNT=1 | CNT=2 | CNT=3 | CNT=4 | CNT=5 | CNT=6 | CNT=7 | CNT=8 | CNT=9 |
IO=1 | IO=1 | IO=1 | IO=1 | IO=0 | IO=0 | IO=0 | IO=0 | IO=0 | IO=0 |
実行してみると、10kHz(0.1ms) (4回分=400us(0.4ms)
パルス幅を400usにしてみました。
(グラフの1マス(div)が200usです)
400usに測定が416usと少しの違いはありますが、
パルスはちゃんと出ています。
cnt<1 で
100us(0.1ms) にしたもの
10kHz(100us=0.1ms) にして
IOを最初の1度だけ出力 cnt<1 で 発生させたパルスです。
10KHzでも十分にパルスが発生出来ています。
この測定では誤差が6usあります。
さらにタイマー割り込みの間隔を細かくして 20us(0.02ms)に
パルス幅を小さくして cnt<1 で 20usのパルスにしてみました。
ここまで来ると出来たパルス幅が 24.8usと誤差が大きくなっていました。
しかしこれだけ短いパルス幅でも誤差は大きくなりますが、IO出力でしっかり出ています!
タイマーVで発生させたパルス
タイマーVでは更に間隔を短く10us(0.01ms)にしてみました。
これがタイマーVの機能で直接10usで発生させた 10us(0.01ms)のパルス波形です。
タイマーVでは
間隔を100us(0.1ms)にしたときでは 誤差は0でした。
やはりタイマー機能ではより正確にパルス波が作れることがわかります。
ラジコンサーボに使えるか
1ms、0.1ms、それ以下の単位で、IO出力でパルス波を発生してみました。ラジコンサーボへのパルス範囲はだいたい 1ms~2ms です。
短いパルス 20us(0.02ms) で 24.8us と誤差が目立ちました。
一方、 タイマーV機能で発生させると 10us で 10.4us と小さくなっても誤差は少ないです。
あまり細かい調節は期待できそうになく、その点をふまえればラジコンサーボにも使えるそうかな。
- twtter
- google+
- hatena