今回は、タイマを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の明るさを調整する処理は以上になります。