13,005
回編集
(ページの作成:「== 概要 == PWM (Pulse Width Modulation, パルス幅変調) は、電力を制御するための技術である。<br> PWMMは、ON / OFFを高速で切り替えることにより、平均電力を制御したり、パルスのデューティ比 (ON時間とOFF時間の比率) を変えることで出力を調整することができる。<br> <br> DCモータの速度制御、LEDの調光制御、ヒータ等の温度制御、オーディオ信号の増幅 (Class…」) |
|||
91行目: | 91行目: | ||
P1DIR |= LED_PIN; // LEDピンを出力に設定 | P1DIR |= LED_PIN; // LEDピンを出力に設定 | ||
// | // タイマA0の設定 | ||
TA0CTL = TASSEL_2 | MC_1 | ID_0; // SMCLK (1[MHz]), アップモード, 分周なし | TA0CTL = TASSEL_2 | MC_1 | ID_0; // SMCLK (1[MHz]), アップモード, 分周なし | ||
TA0CCR0 = 1000 - 1; // PWM周期を1[mS] (1[kHz]) に設定 | TA0CCR0 = 1000 - 1; // PWM周期を1[mS] (1[kHz]) に設定 | ||
// タイマA0のカウント値が0から999までカウントアップするのに1[mS]掛かるため、-1減算している | |||
TA0CCR1 = 500; // デューティ比を50%に設定 | TA0CCR1 = 500; // デューティ比を50%に設定 | ||
// デューティ比を10%に設定する場合は、100を指定する | |||
TA0CCTL1 = OUTMOD_7; // リセット / セットモード | TA0CCTL1 = OUTMOD_7; // リセット / セットモード | ||
115行目: | 117行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
PWM信号の生成は、タイマA0のハードウェア機能により自動的に行われる。<br> | |||
1度設定されたPWM信号は、割り込みを使用しなくても継続的に出力される。<br> | 1度設定されたPWM信号は、割り込みを使用しなくても継続的に出力される。<br> | ||
<br> | <br> | ||
127行目: | 129行目: | ||
割り込みを使用する場合は、対応する割り込みベクタ内で必要な処理を行う。<br> | 割り込みを使用する場合は、対応する割り込みベクタ内で必要な処理を行う。<br> | ||
例えば、タイマA0の割り込みを使用してPWMのデューティ比を変更する場合は、Timer_A0関数内でTA0CCR1の値を更新する。<br> | 例えば、タイマA0の割り込みを使用してPWMのデューティ比を変更する場合は、Timer_A0関数内でTA0CCR1の値を更新する。<br> | ||
<br><br> | |||
== サンプルコード : LEDの調光制御 (割り込み処理) == | |||
以下の例では、PWMのLED調光制御を割り込みを使用して並列に実行して、メイン処理では他の処理を実行している。<br> | |||
<br> | |||
メイン処理で変数duty_cycleの値を変更することにより、割り込み処理でPWMのデューティ比が更新されて、LEDの超高制御を動的に調整できる。<br> | |||
<br> | |||
# タイマA0の設定を行う。 | |||
# TA0CCR1の値を設定する。 | |||
# グローバル割り込みを有効化する。 | |||
# 以下の例では、必要に応じて、変数duty_cycleの値を変更することにより、LEDの調光制御が調整できる。 | |||
# タイマA0 CCR1割り込み内で、TA0IVレジスタ (タイマA0の割り込みベクタレジスタ) の値に応じて処理を行う。<br>以下の例では、TA0CCR1レジスタの割り込みが発生した場合に、変数duty_cycleの値でTA0CCR1レジスタを更新する。 | |||
<br> | |||
<u>※注意</u><br> | |||
<u><code>volatile</code>を付加して変数duty_cycleを宣言しているが、これは割り込み処理とメイン処理の両方からアクセスされるためである。</u><br> | |||
これにより、最適化によって問題が発生することを防ぐ。</u><br> | |||
<br> | |||
<syntaxhighlight lang="c"> | |||
#include <msp430.h> | |||
#define LED_PIN BIT6 // P1.6ピンにLEDを接続 | |||
volatile unsigned int duty_cycle = 100; // デューティ比の初期値を10%に設定 | |||
void main(void) | |||
{ | |||
WDTCTL = WDTPW | WDTHOLD; // ウォッチドッグタイマを停止 | |||
P1DIR |= LED_PIN; // LEDピンを出力に設定 | |||
// タイマA0の設定 | |||
TA0CTL = TASSEL_2 | MC_1 | ID_0; // SMCLK (1MHz), アップモード, 分周なし | |||
TA0CCR0 = 1000 - 1; // PWM周期を1[mS] (1[kHz]) に設定 | |||
TA0CCR1 = duty_cycle; // デューティ比を設定 | |||
TA0CCTL1 = OUTMOD_7; // リセット / セットモード | |||
P1SEL |= LED_PIN; // LEDピンをタイマA0の出力に設定 | |||
__enable_interrupt(); // グローバル割り込みを有効化 | |||
while (1) { | |||
// ...略 | |||
// 例: 変数duty_cycleの値を変更することにより、LEDの調光制御が調整可能 | |||
// duty_cycle = 500; // デューティ比を50%に変更する場合 | |||
} | |||
} | |||
// タイマA0 CCR1割り込み | |||
#pragma vector=TIMER0_A1_VECTOR | |||
__interrupt void Timer_A1(void) | |||
{ | |||
switch (TA0IV) { | |||
case 0x02: // タイマA0のカウンタが、TA0CCR1レジスタの値に達した場合に発生する割り込みがある時、TA0IVレジスタの値は0x02となる | |||
// TA0IVレジスタの値が0x02になる場合は、PWM周期ごとにTA0CCR1に関連する割り込みが発生していること | |||
TA0CCR1 = duty_cycle; // デューティ比を更新 | |||
break; | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||