IOピンでパルス発生をテスト

これまではタイマーのパルス発生機能を使い、その機能でパルス波を発生させていました


3664Fではタイマーではその数に限りがあります。IOピン出力でパルス波をつくりだすことが出来れば、多軸のパルスをタイマーWのPWM機能だけに頼らずにできることになります。どの程度まで可能か探ってみます。

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になり、

  1. Cnt=7 までで周期は8ms。
  2. Cnt=3 までON(High)出力(Pio=1)
  3. 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設定値)

TCRV0
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

というパルス波です。

pluse1ms

 

このようなパルスなら割り込みのたびに、下のように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)

pluse1ms測定波形1

 

cnt<4 で
  パルス幅を400usにしてみました。
  (グラフの1マス(div)が200usです)

  400usに測定が416usと少しの違いはありますが、
  パルスはちゃんと出ています。

 

cnt<1 で
   100us(0.1ms) にしたもの

pluse0.1ms測定波形1

 

 

割り込み間隔を
 10kHz(100us=0.1ms) にして 
 IOを最初の1度だけ出力 cnt<1 で 発生させたパルスです。

 10KHzでも十分にパルスが発生出来ています。
 この測定では誤差が6usあります。

 

さらにタイマー割り込みの間隔を細かくして 20us(0.02ms)に

pluse0.2ms測定波形1

 

さらにタイマー割り込みの間隔を細かくして 20us(0.02ms)にし、
 パルス幅を小さくして cnt<1 で 20usのパルスにしてみました。
 ここまで来ると出来たパルス幅が 24.8usと誤差が大きくなっていました。

 

しかしこれだけ短いパルス幅でも誤差は大きくなりますが、IO出力でしっかり出ています!

 

タイマーVで発生させたパルス

タイマーVでは更に間隔を短く10us(0.01ms)にしてみました。
これがタイマーVの機能で直接10usで発生させた 10us(0.01ms)のパルス波形です。

TIMRVpluse0.01ms測定波形1

 

10usと短いパルス幅ですが、このオシロで測定しても 10.4us と誤差が少ないです。
タイマーVでは
 間隔を100us(0.1ms)にしたときでは 誤差は0でした。

 

やはりタイマー機能ではより正確にパルス波が作れることがわかります。

 

ラジコンサーボに使えるか

1ms、0.1ms、それ以下の単位で、IO出力でパルス波を発生してみました。ラジコンサーボへのパルス範囲はだいたい 1ms~2ms です。


短いパルス 20us(0.02ms) で 24.8us と誤差が目立ちました。
一方、 タイマーV機能で発生させると 10us で  10.4us と小さくなっても誤差は少ないです。

あまり細かい調節は期待できそうになく、その点をふまえればラジコンサーボにも使えるそうかな。

 

スポンサーリンク
  • facebook
  • twtter
  • google+
  • hatena