LPC810M021FN8 (9) -- SCT を PWM として使う (6)

今回は、

  • NXP 社の表現で「Single Edge PWM mode」
  • STmicroelectronics 社の表現で「Edge Aligned PWM mode」

と呼ばれる、デューティーに応じて PWM 波の一方のエッジの位相のみ変化して、もう一方エッジの位相は変化しない方式 (「重心位置」の位相は変化する) についての話です
Atmel 社の表現では「Fast PWM mode」と呼ばれていて、Double Edge と同じ分解能の設定で PWM 周波数が約 2 倍になるため「Fast」と呼ばれています。
その代わり、「信号波形」として見た場合に、ひずみ率が大きくなります。 
シンセの CV のように、過渡応答の特性はそれほど要求されず、ほぼ DC と見なせるような場合には、PWM 周波数が高いので接続する LPF が「軽く」すむというメリットがあります。
LPC8xx には CTOUT_0 〜 CTOUT_3 の 4 つの出力があり、マッチ・レジスタは 5 本あるので、4 本のマッチ・レジスタを 4 つの出力それぞれに割り当てれば、独立 4 ch の PWM 出力を得ることができます。
残りの 1 本のマッチ・レジスタは、カウンタの「リミット」および固定エッジの生成のイベントに使うことができます。
要求される PWM の「仕様」によっては、カウンタのリミットと固定エッジ生成のためのイベントとを分ける必要が生じますが、その場合には出力 ch 数を削ってマッチ・レジスタを確保することになります。
以前に示したタイミング・チャートを下に再掲します。
前に示したプログラムはこの構成を実現したものです。

この図では、「同相」(非反転) つまりデューティーの設定値が小さいとき (平滑後の) PWM 出力電圧も低く、設定値が大きいとき出力電圧も高くなるように設定した場合を示しています。
逆相 (反転) の場合には出力の SET/CLR が互いに逆になります。
カウンタはアップ・カウントのみの「単方向」で、「リミット値」として設定した値に達すると、次のクロックでゼロに戻され、アップ・カウントを続けます。
このリミット値を設定するマッチ・レジスタによるイベントで、

  • カウンタ・リミット
  • マッチ・レジスタのリロード
  • 全出力一斉の SET 動作
  • (必要ならば割り込み発生)

を行うように設定します。 (リロードはリミット動作に伴いハード的に行われるので指定する必要はない)
(個別の) マッチ・レジスタのイベント定義としては、カウンタ値とのコンペア・マッチが成立したら、対応する出力の CLR 動作を行うように設定します。
PWM 周期 N に対して、カウンタは
0, 1, 2, ... , (N-2), (N-1)
と変化し、リミット値として設定すべき値は最大値である (N-1) となります。
デューティー値としてマッチ(・リロード)・レジスタに設定される値がこれと同じ (N-1) の場合に、出力に対して SET 動作と CLR 動作が同時に要求され、「コンフリクト」が生じます。
コンフリクト発生時の動作は conflict resolution register に設定する値で制御でき、デフォルトの動作は「出力値を変化させない」です。
上のタイミング・チャートの場合、コンフリクト時の動作としては、「変化なし」あるいは「SET 優先」の動作に設定する必要があります。 (逆相の場合「変化なし」あるいは「CLR 優先」)
コンフリクト発生時には SET 動作のみとなるので、デューティー 100 % の「H」レベルが出力されることになります。
例えば、PWM 周期 N = 256 を指定して初期設定した場合の、MATCHREL レジスタに設定する値と、実際の PWM 波のデューティーとの関係は、

レジスタ
設定値
実際の
デューティー (正相)
実際の
デューティー (逆相)
0 1/256 255/256
n (n + 1)/256 (255 - n)/256
254 255/256 1/256
255 256/256 = 100 [%] 0/256 = 0 [%]

となります。
ここで、正相の場合デューティー 0 % は得られず、一番小さくて 1/256 となり、逆相の場合デューティー 100 % は得られず、一番大きくて 255/256 となっています。
LED の光量制御などで、完全に消灯する必要がある場合、逆相の構成とし、デューティー値に対して 1 の補数を求める、つまりビットごとに反転した値をレジスタにセットすれば実現できます。
正相の構成でデューティー 0 %、逆相の構成でデューティー 100 % がどうしても欲しいという場合には、

  • 正相の場合 conflict resolution を CLR 優先
  • 逆相の場合 conflict resolution を SET 優先

とすれば、下の表のようになります。

レジスタ
設定値
実際の
デューティー (正相)
実際の
デューティー (逆相)
255 0/256 = 0 [%] 256/256 = 100 [%]
0 1/256 255/256
n (n + 1)/256 (255 - n)/256
254 255/256 1/256

目的のデューティー値からレジスタへ設定する値への変換の計算方法は、正相の場合に、

  • デューティー値から 1 を引き
  • 8 ビット範囲からはみ出した部分をマスクするために 0xff と AND をとる

となります。
デューティー 0 % と 100 % とを同時に得たい場合には、リミットのためのマッチ・レジスタと固定エッジ生成のためのマッチ・レジスタを分ける必要があります。
デューティー 0 % / 100 % の片方を固定エッジと可変エッジのコンフリクト、もう片方を可変エッジのマッチなしで作成します。
固定エッジ作成のためのマッチ・レジスタには 0 をロードして、0 とのコンペア・マッチ・イベントを定義し、conflict resolution は正相の場合 CLR 優先、逆相の場合 SET 優先とします。
また、デューティー値 0, 1, ... , (N-1) に対してリミット値を 1 小さい (N-2) と設定します。
N = 256 に対しては、下の表のようになります。

レジスタ
設定値
実際の
デューティー (正相)
実際の
デューティー (逆相)
0 0/255 = 0 [%] 255/255 = 100 [%]
1 1/255 254/255
n n/255 (255 - n)/255
254 254/255 1/255
255 255/255 = 100 [%] 0/255 = 0 [%]

レジスタ = 0 の場合コンフリクトが生じ、conflict resolution により正相の場合 0 % デューティー、逆相の場合 100 % デューティーを得ています。
カウンタのリミット値は 254 となるので、マッチ・レジスタ値 254 まではコンペア・マッチが生じますが、レジスタ値 255 ではマッチが成立せず、固定エッジを生成するマッチ・イベントの SET/CLR 動作だけが連続することになるので、正相の場合デューティー 100 %、逆相の場合デューティー 0 % が得られます。