TWELITE ZONE

TWELITEプログラミングを容易にするbasicio.hを紹介するサイト

タイマー 概要



リファレンスマニュアル トップ


TWELITE用ライブラリ basicio.h のタイマー系関数の概要です。




TWELITEのタイマーと機能の有効化

TWELITEは0~4の5つのタイマーを持っており、下記の機能をタイマーに割り当てて使用します。これらはすべてタイマー機能を使っているため、関数名は timer_ で始まります。

  • マイクロ秒カウンタ
  • タイマーコールバック
  • PWM出力
  • DAC(アナログ出力)

タイマー0は上記に加え、下記の2つの固有の機能を有しています。これらの関数名は timer0_ で始まります。

  • キャプチャ
  • カウンタ



タイマー関数を有効にするには、basicio_module.h 内で USE_TIMER を宣言する必要があります。

//-1:
#define USE_TIMER




マイクロ秒カウンタ

basicio.hでは経過時間を知る方法として、無所属関数の millis() を使用できます。これはデフォルトで4ミリ秒毎にカウントアップします。
マイクロ秒カウンタは1μ秒毎にカウントする32ビットカウンタです。特に何かをするわけではなく、millis() 関数のようにカウント値を読み出して使用します。コードの実行時間や、ハードウェア応答の非常に短い時間待ちなどに使用できます。

マイクロ秒カウンタは timer_attachMicroCounter() を使用して開始します。
サンプルコード

マイクロ秒カウンタは次で説明する、TWLITEのタイマーコールバック機能をbasicio.hで拡張したものです。



タイマーコールバック

指定された時間毎にコールバック関数を呼び出すものです。

タイマーコールバックは timer_attachCallback() または timer_attachCallbackByHz() を使用して開始します。

サンプルコード

タイマーをプレスケーラーとサイクルカウントで指定する

タイマーコールバック関数を timer_attachCallback() によって登録します。少し計算が必要ですが、柔軟な設定ができる方法です。

呼び出し間隔は次式で表されます。

呼び出し間隔[秒] = サイクルカウント値 ÷ クロック[Hz]
クロック[Hz] = 16000000 ÷ (2のプリスケーラ乗)
サイクルカウント値:0~65535 (0の場合は65536として計算)
プリスケーラー:0~16

基本クロック16MHzをプリスケーラーで分周したものをクロックとし、16ビットカウンタをクロックにより0からカウントアップしていきます。16ビットカウンタがサイクルカウント値に到達するとタイマーコールバックが呼び出されます。16ビットカウンタは0に戻ってカウントアップを続けます。

これらは計算ツールを使って容易にプリスケーラーとサイクルカウント値を得ることができます。

タイマーをHzで指定する

タイマーコールバック関数を timer_attachCallbackByHz() によって登録します。
整数でHz指定するため少し雑になりますが、簡単に設定ができます。
Hz、つまり1秒間のコールバック関数呼び出し回数です。

この場合、timer_attachCallbackByHz() を使用してコールバック関数を設定します。
この関数は内部でプレスケールとサイクルカウント値を計算しています。



PWM, DACが出力するDIO

各タイマーには出力可能なDIOが決まっており、PWM, DACで使用されます。
bUseSecondPin はPWM, DACの初期化関数のパラメータです。

bUseSecondPin Timer0 Timer1 Timer2 Timer3 Timer4
FALSE DIO10 DIO11 DIO12 DIO13 DIO17
TRUE DIO4 DIO5 DIO6 DIO7 DIO8

ピン配置 - TWELITE ZONE



PWM出力

タイマーを使ってPWM出力を使用することができます。
PWMは timer_attachPWM() または timer_attachPWMByHzDuty() を使用して開始します。

サンプルコード

PWMをプレスケーラーとサイクルカウント、パルスカウントで指定する

PWMを timer_attachPWM() によって開始する場合です。少し計算が必要ですが、柔軟な設定ができる方法です。

呼び出し間隔は次式で表されます。

PWMの周期

f:id:mae8bit:20191014144105p:plain
タイマーコールバックと同じ考え方です。

PWMの周期[秒] = サイクルカウント値 ÷ クロック[Hz]
クロック[Hz] = 16000000 ÷ (2のプリスケーラ乗)
サイクルカウント値:0~65535 (0の場合は65536として計算)
プリスケーラー:0~16

PWMのパルス幅

f:id:mae8bit:20191014144234p:plain
基本的にPWMの周期と同じです。
パルス幅はパルスカウントでカウントされます。パルス幅は周期の中のHIGHの時間であるため、パルスカウントはサイクルカウントと同じか小さい値でないといけません。

PWMのパルス幅[秒] = パルスカウント値 ÷ クロック[Hz]
パルスカウント値:0~サイクルカウント
   (但しサイクルカウントが0の場合は0~65535)
プリスケーラー:PWMの周期と共通

PWMパルスの位置

f:id:mae8bit:20191014145727p:plain
パルス部分を周期の最初または後にもってくるかを指定します。bStartFromHi はPWM初期化関数のパラメータです。

基本クロック16MHzをプリスケーラーで分周したものをクロックとし、16ビットカウンタをクロックにより0からカウントアップしていきます。周期の最初の出力がHIGHかLOWかは bStartFromHi パラメータによって決まります。「最初のカウンタ値」に到達したとき、出力が反転され、16ビットカウンタがサイクルカウントに到達したときにPWMの周期が完成します。16ビットカウンタは0に戻ってカウントアップを続けます。
「最初のカウンタ値」はパルスカウント値からbasicio.hによって計算されます。

これらは計算ツールを使って容易にプリスケーラーとサイクルカウント値、パルスカウント値を得ることができます。

PWMをHzとデューティー比で指定する

PWMを timer_attachPWMByHzDuty() によって開始する場合です。パラメータを整数で指定するため少し雑になりますが、簡単に設定ができます。

Hz

1秒間のサイクル数(=パルスの数)を指定します。
例えばサーボモーターのPWM周期が20ミリ秒の場合の周波数は、1000ミリ秒 ÷ 20ミリ秒 = 50Hz です。

デューティー

f:id:mae8bit:20191014155248p:plain
デューティー比は周期に対するパルス幅の比率で、0.0~1.0 または 0~100% で表されます。しかしbasicio.hでは小数を使用しないため、0~32768 という範囲で表します。
例えば周期中のHIGHが半分、つまり50%の場合、16384 と表すことができます。

PWMパルスの位置

f:id:mae8bit:20191014145727p:plain
パルス部分を周期の最初または後にもってくるかを指定します。bStartFromHi はPWM初期化関数のパラメータです。

パルス幅の変更

一度設定したPWMパルス幅を変更する場合、timer_updatePWM() または timer_updatePWMDuty() を使用します。
これらの関数は、timer_attachPWM() または timer_attachPWMByHzDuty() のいずれの関数で初期化した場合でも使用できます。

timer_updatePWM()を使ってパルスカウント値を変更するには、サイクルカウント値を知っておく必要がありますが、timer_getPWMPulseCountULimit() を使って、サイクルカウントに設定可能な上限値を知ることができます。

特殊なパターン

下記の場合波形は生成されず、PWM出力はLOWまたはHIGHを維持します。

  • パルスカウントが0または、デューティー比が0の場合
  • パルスカウントがサイクルカウントと同じまたは、デューティー比が32768の場合


bStartFromH
パルスカウント = 0
または
デューティー比 = 0
パルスカウント = サイクルカウント
または
デューティー比 = 32768
FALSE HIGHを維持 LOWを維持
TRUE LOWを維持 HIGHを維持




DAC(アナログ出力)

TWELITEはデルタシグマ変調により、低速のDAC(Digital to Analog Converter)としての機能を持っています。TWELITE自身は NRZ(Non-Return-to-Zero) と RTZ(Return-To-Zero) の出力方式に対応していますが、basicio.hではNRZを用いてアナログ出力としています。コンデンサと抵抗をきちんと選定すれば電圧が得られるはず(私自身ハードウェアはあまり得意でないので書けません)。
単純にArduinoのanalogWrite()的に使えると思います。

アナログ出力は timer_attachAnalogWrite() を使って開始し、timer_updateAnalogPower() で出力を変更することができます。

サンプルコード



キャプチャ、カウンタに入力するDIO

bUseSecondPin はキャプチャ、カウンタの初期化関数のパラメータです。

bUseSecondPin Timer0
キャプチャ
Timer0
カウンタ
FALSE DIO9 DIO8
TRUE DIO3 DIO2

ピン配置 - TWELITE ZONE



キャプチャ

キャプチャはタイマー0専用機能です。DIOピンから入力されたパルス信号のLOWの時間とHIGHの時間を測定します。

キャプチャは timer0_attachCapture() によって開始されます。バッファの32ビットに1周期のデータが格納されます。
32ビット値からデータの取り出しには次の関数を使って、マイクロ秒の単位で取得できます。

サンプルコード


timer0_attachCapture() は入力パルス信号が無い場合に処理を完了しません。timer0_attachCapture() の測定が完了したかどうかを知るには timer0_captureCompleted() を使用します。もしくは timer0_getCaptureCount() で進行状況を知ることができます。
処理を強制的に終了させる場合は timer_detach() を使用します。

時間計測には16ビットカウンタを用いられますが、プリスケーラの設定により測定精度と測定可能な時間が変わってきます。

周期の長いものにプリスケーラーの小さな値で測定すると、周期が完了する前に16ビットカウンタがオーバーフローしてしまいます。ソフトウェアからは16ビットカウンタのオーバーフローは知ることができないため、取得した16ビットカウンタ値が正しいものか判別できないわけです。そのため、この関数は基本的に入力信号の周期がわかっているものに使用するか、もしくはプリスケーラの大きな値で仮測定し、適切なプリスケーラを選択する方法を考えるべきです。
Timer0キャプチャ機能の測定限界 - TWELITE ZONE

カウンタ

カウンタはタイマー0専用機能です。タイマーコールバックは基本クロック16MHzを使用していたのに対し、このカウンタでは基本クロックの代わりにDIOピンから入力されたパルス信号をクロックとして使用します。

TWELITEにはこのTimer0カウンタのほかに、パルスカウンタと呼ばれるよく似た機能があります。下記に違いをまとめたので参考にしてください。
パルスカウンタとTimer0カウンタの違い - TWELITE ZONE

カウンタは timer0_attachCounter() によって開始されます。
プリスケーラの使い方は、タイマーコールバックの項を参照してください。

サンプルコード