C言語

PWM出力を行い、LEDの明るさを調整する

今回は、タイマを2つ使用し、PWM出力させることにより、LEDの明るさを変更するプログラムを作成していきます。

PWM出力とは

PWM出力とは、高速にONとOFFを切り替えることにより、出力される平均電力を制御する方式です。
電圧がHIの時間の割り合いを変えることで、負荷がかかる電力を制御します。このHIになっている時間の割り合いをDUTY(デューティ)とよびます。
PWMは、主に、モータの回転数を変化させたり、LEDの調光を行ったりします。

PWMの設定

基本的に、「IOポートの設定」で設定したIOポートの設定値と、「インターバル・タイマを使ってLEDを点滅させる」で設定したタイマの設定値を元に変更していきます。

今回は、PWM出力に使用できるのは、LED0のため、マスタチャネルをユニット0のチャネル0で、スレーブチャネルをユニット0のチャネル2で行います。
マスタチャネルでは、1ms周期のインターバル・タイマを使用し、スレーブチャネルでは、デューティ比は20%くらいにして、LEDの調光を暗めにすることにより、見た目でもわかるようにしようと考えています。
そして、マイコン機能により、TO02端子を使用してLED0の出力を制御するため、特に割り込み処理も不要です。

まずは、タイマの設定をする前にIOポートのレジスタ設定を変更する箇所があるため、その変更を先に行います。

IOポート設定の変更

IOポートのLED0が割り当たっているP17の設定値は 1 (LED0が消灯)となっていますが、TO02端子として使用するため、初期値の 0 としておきます。

変更内容は、「RL78G14_init.c」 ファイルの「#define RL78G14_INIT_P1 (0x80U)」の値を0x00Uに変更します。(「 #define RL78G14_INIT_P1 (0x00U) 」

タイマ設定の変更

次にタイマ設定の追加・変更を行っていきます。

変更内容は、「RL78G14_init.c」 ファイルの タイマ初期値の定数定義を次のように変更します。

/***************/
/* タイマ初期値 */
/***************/
#define RL78G14_INIT_TAU0EN (1U)         /* 変更なし */
#define RL78G14_INIT_TMR00  (0x0001U)    /* 0x0000Uから0x0001Uに変更 */
#define RL78G14_INIT_TMR02  (0x0409U)    /* 新規追加 */
#define RL78G14_INIT_TPS0   (0x0000U)    /* 0x000AUから0x0000Uに変更 */
#define RL78G14_INIT_TDR00  (0x7D00U)    /* 0x7A12Uから0x7D00Uに変更 */
#define RL78G14_INIT_TDR02  (0x1900U)    /* 新規追加 */
#define RL78G14_INIT_TIS0   (0x00U)      /* 変更なし */
#define RL78G14_INIT_TOE0   (0x0004U)    /* 0x0000Uから0x0004Uに変更 */
#define RL78G14_INIT_TO0    (0x0004U)    /* 0x0000Uから0x0004Uに変更 */
#define RL78G14_INIT_TOL0   (0x0004U)    /* 0x0000Uから0x0004Uに変更 */
#define RL78G14_INIT_TOM0   (0x0004U)    /* 0x0000Uから0x0004Uに変更 */
#define RL78G14_INIT_ISC    (0x00U)      /* 変更なし */
#define RL78G14_INIT_NFEN1  (0x00U)      /* 変更なし */

設定値の説明を行います。

  • TMR00
    タイマ・モード・レジスタ00は、マスタとするチャネル0の設定です。基本的に、インターバル・タイマと同じ動作なのですが、MD000を1にしています。これは、カウント開始時にタイマ出力を行うために設定を変更しました。
  • TMR02
    タイマ・モード・レジスタ02は、スレーブとするチャネル2の設定です。マスタチャネルの割り込み信号によりタイマをスタートさせるため、STS020~STS022を100b(ワンカウント・モード)に設定し、MD020をカウント動作中のスタート・トリガを有効とする 1 に設定しています。
  • TPS0
    タイマ・クロック選択レジスタ0は、1msのタイマなので、クロックを分周する必要がなくなったので、0 にしました。このため、32MHzになりますので、1カウントが31.25ナノ秒です。
  • TDR00
    タイマ・データ・レジスタ00は、1msのため、32000カウントの0x7D00です。正確には、この値に-1をするのが正確なのですが、わかりにくくなると思ったのでこのままとしました。
  • TDR02
    タイマ・データ・レジスタ02は、1msの20%の6400カウントの0x1900です。上記と同様に-1はしていません。
  • TOE0
    タイマ出力許可レジスタ0は、スレーブのチャネル2をTO02端子を使用して出力するため、チャネル2に該当するビット2を1に設定しています。
  • TO0
    TO02信号の初期値を 1 (LED0消灯)にしています。
  • TOL0
    タイマ出力する値の反転設定を行うレジスタですが、LEDは、LOがアクティブになるため、チャネル2を反転設定にしています。
  • TOM0
    タイマ出力モード・レジスタ0は、チャネル2がスレーブ・チャネル出力モードになるため、設定を変更しています。

設定値については、以上です。

これを踏まえて、RL78G14_init.cファイルのRL78G14_init_Timer関数を変更します。
ここでは、新規に追加した設定値のみ、設定処理を追加します。

static void RL78G14_init_Timer( void )
{
    TAU0EN = RL78G14_INIT_TAU0EN;
    TMR00 = RL78G14_INIT_TMR00;
    TMR02 = RL78G14_INIT_TMR02; /* 新規追加 */
    TPS0 = RL78G14_INIT_TPS0;
    TDR00 = RL78G14_INIT_TDR00;
    TDR02 = RL78G14_INIT_TDR02; /* 新規追加 */
    TIS0 = RL78G14_INIT_TIS0;
    TOE0 = RL78G14_INIT_TOE0;
    TO0 = RL78G14_INIT_TO0;
    TOL0 = RL78G14_INIT_TOL0;
    TOM0 = RL78G14_INIT_TOM0;
    ISC = RL78G14_INIT_ISC;
    NFEN1 = RL78G14_INIT_NFEN;
}

次にmain.cファイルのmain関数を変更します。
インターバル・タイマを使ってLEDを点滅させる」 で作成したmain.cファイルを変更します。
まず、割り込み処理は、不要なので、TimerCtrl関数も削除し、main関数のみにします。
main.cの内容は次のようになります。

#include "iodefine.h"

void main(void);

void main(void)
{
    TS0 = 0x0005U;

    while( 1 )
    {
        /* 処理が終わってしまうため、無限ループにて割り込みを待っている状態にする */
    }
}

main関数ですが、割り込みは必要なくなったため、削除しています。
タイマはチャネル0とチャネル2を使用しているので、タイマ開始は、チャネル0のビット0と、チャネル2のビット2を1に設定した、0x0005Uとしています。

タイマを開始したら、後は、マイコン機能の動作のみになるため、処理はありません。

動作確認すると、LED0が暗めに点灯していることがわかると思います。これは、短い時間に点灯・消灯を繰り返しているため、暗く見えています。

PWM出力を行い、LEDの明るさを調整する処理は以上になります。

-C言語