MSP430開発入門講座(4) PWM

今回のソース

PWM(Pulse Width Modulation)という手法でLEDの明るさを変えてみます。 今回使うPWMは一番単純に、一周期中に1個の矩形波があって、そのデューティ比を 変えるタイプです。PWMはLEDの他にもDCモータの速度を制御するときなどにも 使えます。 PWMを発生する際は、時間を測って(タイマ割り込みで)ソフトウェアでon/offしても いいのですが、MSP430をはじめ ほとんどのマイコンのタイマには勝手に出力ピンをon/offしてくれる機能が ついています (LaunchPad もそれを前提として設計されてるフシがあります) 。せっかくなので今回はこっちの機能を使ってみましょう。

// tutorial03.c  by Yagshi 2011
#include <io.h>

#define kPeriod      0xff       // 12000 / 256 = 46.875 [Hz]
#define kInitialDuty 0x07       // 0-0x07: on,  0x08-0xff: off

void initializeMCU(void)
{
  WDTCTL = WDTPW + WDTHOLD;     // shut up the dog
  BCSCTL3 |= LFXT1S_2;          // Select VLO for ACLK
  // setup PORT1
  P1SEL |= BIT6;
  P1DIR |= BIT6;
  // setup TIMER_A
  TACTL = TASSEL__ACLK + ID_0 + MC__UP;
  TACCR0 = kPeriod;
  TACCR1 = kInitialDuty;
  TACCTL1 = OUTMOD_6;           // toggle/set mode
}

int main(void)
{
  initializeMCU();
  for(;;) _BIS_SR(SCG1 | SCG0 | CPUOFF); // goes into LPM3
  return 0;
}

タイマのお約束2機能

そもそもタイマ(timer)とは

タイマというと、なんとなくカウントダウンしてある時間たったらアラームが なるみたいなそんなイメージがありますが、マイコンのタイマの場合、 一般には『放っておいても勝手にアップ(ダウン)してくれるカウンタ』のことを 指します。そういう意味では 時計やストップウォッチみたいなものと 思った方が誤解が少ないかもしれません。 とはいっても単なる自動カウンタだけではあまりにショボいので、ふつうは 『キャプチャ』と『コンペア』 という二つの機能が最低でももれなくついてくると 思って間違いないです。 『コンペア』機能を使うと上述のようないわゆる日常用語としてのタイマぽい ことができるようになります。

MSP430には (第1回 で紹介したWatchdogタイマを別にすれば) Timer_AとTimer_Bという二つのタイマがありますが、G2ファミリには Timer_Bは今のところなさそうなので気にしないことにしましょう。ちなみに Timer_Bの方が若干高機能です。

キャプチャ(capture)(TACCTLx.CAP=1)

時計で言えばストップウォッチ。 外部ピンなどの状態変化が生じたときのタイマの値をキャプチャする機能です。 時間計測などに使えます。MSP430の場合は、TACCRxレジスタに 記録されます。

コンペア(compare)(TACCTLx.CAP=0)

時計で言えば目覚まし(=アラーム)。 あらかじめレジスタ (MSP430の場合はTACCRxレジスタ)にセットした値と現在のタイマ値を 比較し、 一致したらあるアクションを起こします。具体的には次のようなアクションです (両方同時に実行することもできます)。

Timer_A のクロック設定(TACTLレジスタ→TASSELx/IDxビットフィールド

Timer_A のクロック源はTACKL, ACLK, SMCLK, INCLKの4つで、これを設定 するのがTACTLレジスタのTASSELxビットフィールド (2bit)です。4つのクロック源のうち ACLK, SMCLK は 別ページで解説してあるとおりです。 残りの2つ、TACLK, INCLKは外部ピンから入力するTimer_A 専用の クロック源のようです。それぞれのクロック源はTACTLレジスタの IDxビットフィールドを使って、1, 2, 4, 8分周可能です。

Timer_A の4つの動作モード(TACTLレジスタ→MCxビットフィールド)

Timer_A は 16 ビットのカウンタで、 Up, Continuous, Up/down の3つのTimer Modeがあります。簡単に説明すると…

となります。


MSP430 Timer A
これを指定するのがTACTLレジスタのMCx という2ビットのビットフィールドです ( MSP430x2xx Family User's Guideの12.3 節あたり参照)。 ソース中では以下の1文で MC__UPという定数を使って Up モードを指定しています。

TACTL = TASSEL__ACLK + ID_0 + MC__UP;

キャプチャ・コンペアレジスタ(TACCRx)

出力設定(Output unit)

さぁ、ここが今回の一番ややこしいところです。MSP430の中でも比較的 自由度が低いところなので、良く考えてハードウェアの設計をしないと 後から困ります。 MSP430固有と感じた注意点を以下にまとめます。


『マイコンを使った開発について』に戻る

Valid XHTML 1.0!