マイコン・メモ
RX220でビープ音を鳴らす
ホームページに戻るトップページに戻る前ページに戻る次ページに進む最終ページに進む
32ビットマイコンRX220の、マルチファンクションタイマパルスユニット(MTU)を使ったビープ音の発生方法を、これまで製作したものを基に紹介します。
■参考資料■
 ・RX220グループ ユーザーズマニュアル ハードウェア編 :ルネサス エレクトロニクス
1.ビープ音発生回路

ここで言うビープ音とは、音として聞こえる周波数の矩形波をスピーカで発した音を指すものとします。
矩形波の音は濁った音ですが、簡単な回路でも鳴らせるのでよく使用されます。
下図は、トランジスタを介した出力ポートで圧電スピーカを駆動する回路の例ですが、このような簡易な回路でビープ音を鳴らす方法を紹介します。
このような回路では、プログラムによって音に相当する周期で出力ポートをON/OFFさせるだけで音を出すことができます。しかし、発音中に割り込み等が入って周期が少しでもずれると、それがノイズとなって聞こえてしまうという欠点があります。そこで、タイマユニットの出力を使って安定した周波数で駆動するようにします。
使用したタイマユニットは、RX220の周辺機能の1つで「マルチファンクションタイマパルスユニット(MTU)」というのものです。
実は、下図で使っていたポートPB5(ポートBのビット5)は、MTUの1つであるMTU2の出力の1つで、MTIOC2Aという端子でもあります。
このMTU2とMTIOC2A端子を使ったビープ音の発生について、以降で詳しく説明します。
※ 図にあるマイコンボードは、64ピンのRX220(R5F52206BDFM)を搭載した、秋月電子通商で販売しているマイコンボードを想定しています。
圧電スピーカの駆動回路例

2.マルチファンクションタイマパルスユニット(MTU)を使う

RX220には、6本(6チャンネル)のマルチファンクションタイマパルスユニット(MTU0~MTU5)があります。それぞれが16ビットのタイマで構成されていて、パルス出力や波形出力、パルス幅や位相の計測などに使用されます。
以降では、MTU0~MTU5注1の中からMTU2を、そしてその波形出力機能を使ってビープ音を発生する例を紹介します。
まず、MTU2のレジスタ構成を以降に図で示します。MTUは多機能なため多数のレジスタがありますが、ここではビープ音発生に使用したレジスタを示します。図の中で網掛けになっている箇所は、ビープ音発生のために設定した値を示しています。図に示されていない、その他のレジスタは初期状態のままとします。
注1.MTU0~MTU5はすべて同じ機能・構成というわけではなく、異なるものがあります。別のMTUを使う場合、異なる点を確認してください。詳細は「RX220ハードウェアマニュアル」を参照してください。
タイマスタートレジスタ(TSTR)は、タイマカウンタ(MTUn.TCNT,n=0~4)を動作/停止させるレジスタです。各MTUの設定は、このレジスタによってタイマカウンタを停止した状態で行います。ちなみに、MTU2を動作/停止させるにはb2のCST2を操作します。
なお、MTU5のためのビットがないのは、MTU5は別のレジスタ(MTU5.TSTR)で行うようになっているためです。
MTUのタイマスタートレジスタ
タイマカウンタ(MTU2.TCNT)は、MTU2の動作の要となるカウンタです。16ビットのアップカウンタで、ビープ音の発生では音の波長を決める基になります(初期値は全ビット '0')。
タイマジェネラルレジスタA/B(MTU2.TGRA, MTU2.TGRB)は、波形出力で使用する場合にはアウトプットコンペアレジスタモードで、パルス幅測定で使用する場合にはインプットキャプチャレジスタモードで使用する16ビットレジスタです。したがって、ビープ音発生ではアウトプットコンペアレジスタモードで使用します。
アウトプットコンペアレジスタモードで、タイマカウンタと一致したとき注2波形出力端子(MTIOC2A, MTIOC2B)の 'H' , 'L' を反転させることで、希望の波長の矩形波を作り出すことができます。
なお、ここで紹介するビープ音発生では、MTU2.TGRAとMTIOC2A端子のみを使用し、MTU2.TGRBとMTIOC2B端子は使用していません。
注2.波形出力端子は、タイマカウンタ(TCNT)とタイマジェネラルレジスタ(TGRx)が一致した次のクロックで変化します。
MTU2のカウンタとジェネラルレジスタ
タイマコントロールレジスタ(MTU2.TCR)は、タイマカウンタの動作を設定します。
ここでは、クロックに下図に示す4種類の内部クロック(PCLK/1, … PCLK/1024)注3からPCLK/4(=5MHz, =200nS)を使い、TGRAのコンペアマッチでタイマカウンタがクリアされるようにします。
注3.PCLKは、システムクロック(ICLK)と同じ20MHzであるものとします。
MTU2のコントロールレジスタ
タイマモードレジスタ(MTU2.TMDR)は動作モードを決める設定です。
ビープ音の発生は波形出力なので、「PWMモード1」または「ノーマルモード」を使用します。TGRA,TGRBは通常動作です。
ただ、下表のように動作モードによってアウトプットコンペアレジスタで制御できる出力端子が異なります。しかし、このビープ音発生では、出力端子としてMTIOC2Aを使うのでどちらのモードでも使用可能です。
PWMモード1の場合、MTU2.TGRAとMTU2.TGRBをペアで使うことによって、出力波形のデューティ比を変えることが可能になります(これがPWMということです)。

タイマ動作モード アウトプットコンペアレジスタ 出力端子
ノーマルモード MTU2.TGRA MTIOC2A
MTU2.TGRB MTIOC2B
PWMモード1 MTU2.TGRA MTIOC2A
MTU2.TGRB
MTU2のモードレジスタ
タイマI/Oコントロールレジスタ(MTU2.TIOR)は、入出力端子MTIOC2A, MTIOC2Bの動作を設定します。
MTIOC2A端子をビープ音の波形出力とするので、「コンペアマッチでトグル出力」とします。ただし、それは発音中のことで、最初は鳴らさないので「出力禁止」としておきます。
プログラム例にありますが、指定のタイミングで「出力禁止」と「コンペアマッチでトグル出力」を切り換えることで、断続音とすることができます。
MTIOC2B端子は使用しないので「出力禁止」にしておきます。
MTU2のI/Oコントロールレジスタ
タイマ割り込み許可レジスタ(MTU2.TIER)は、タイマジェネラルレジスタA/B(MTU2.TGRA, MTU2.TGRB)によるコンペマッチまたはインプットキャプチャ発生時の割り込み許可/禁止の設定です。
ビープ音発生では割り込みは使用しないので、すべて初期状態のまま「割り込み禁止」です。
ちなみに、MTU2では「TGR割り込み許可C」「TGR割り込み許可D」「A/D変換開始要求許可2」は使用できません。
MTU2の割り込み許可レジスタ

3.MTU2の設定例

下記に、MTIOC2A(PB5)端子から4kHzの矩形波を出力する、MTU2の設定例を示します。
最初にある、マクロ IOA_HZ_TCNT で発生周波数が決まります。実際にMTIOC2A端子が変化するのは、タイマカウンタがタイマジェネラルレジスタと一致した次のクロックなので、正確にしたければ1カウント少ない値(IOA_HZ_TCNT -1)をセットします。しかし、ビープ音の場合は多少の違いを聞き分けられないので、数カウントの違いは問題ありません。
なお、下記の設定を行った状態ではMTIOC2A端子は「出力禁止」になっていて波形は出力されません。次項に示すプログラム例にあるように、定周期割り込みによって指定したタイミングで「出力禁止」と「コンペアマッチでトグル出力」を切り換えることで、断続音を出すようにしています。

#define  IOA_HZ_TCNT  (5000 / 4 / 2)

void Init_Beep(void)
{
    PORTB.PMR.BIT.B5 = 0;
    MPC.PWPR.BYTE = 0x00;
    MPC.PWPR.BYTE = 0x40;
    MPC.PB5PFS.BYTE = 0x01;
    MPC.PWPR.BYTE = 0x80;
    PORTB.PMR.BIT.B5 = 1;

    SYSTEM.PRCR.WORD = 0xA502;
    MSTP(MTU) = 0;
    SYSTEM.PRCR.WORD = 0xA500;

    /* MTU2初期化 */
    MTU.TSTR.BIT.CST2 = 0;
    MTU2.TCR.BYTE = 0x21;
    MTU2.TMDR.BYTE = 0x02;
    MTU2.TIOR.BYTE = 0x00;
    MTU2.TIER.BYTE = 0x00;
    MTU.TSYR.BIT.SYNC2 = 0;

    MTU2.TCNT = 0x0000;
    MTU2.TGRA = IOA_HZ_TCNT;
    MTU2.TGRB = 0xFFFF;
    /* MTU2コンペアマッチ割り込み禁止 */
    IEN(MTU2, TGIA2) = 0;
    IEN(MTU2, TGIB2) = 0;
    /* MTU2オーバ/アンダーフロー割り込み禁止 */
    IEN(MTU2, TCIV2) = 0;
    
    ~
    
    /* MTU2カウント開始 */
    MTU.TSTR.BIT.CST2 = 1;
}
/* 出力周波数 4kHz(5MHz÷4kHz÷2) */



/* PB5をI/Oポートとして使う設定 */
/* 書き込みプロテクトレジスタ(先にBOWI=0にすること) */
/* PFSレジスタ書き込み許可 */
/* PB5端子をMTIOC2A出力として使用する */
/* PFSWEビット,PFSレジスタへの書き込みを禁止 */
/* PB5を周辺機能として使う設定 */

/* 動作モード関連レジスタへの書き込みを許可する */
/* MTU0~MTU5のモジュールストップ解除 */
/* 動作モード関連レジスタへの書き込みを禁止する */


/* MTU2.TCNTのカウント停止 */
/* クロック=PCLK/4(5MHz:200nS), TGRAのコンペアマッチでTCNTクリア*/
/* タイマの動作モードはPWMモード1 */
/* MTIOC2A端子,MTIOC2B端子出力禁止 */
/* 割り込み要求(TGIA,TGIB,TCIV,TCIU)を禁止 */
/* MTU2.TCNTは独立して動作、他のチャネルと無関係 */

/* タイマカウンタクリア */
/* 出力周波数を決めるコンペアマッチ値をセット */
/* タイマジェネラルレジスタBは不使用 */






// ←他に初期化があれば記入





※この設定例では、MTU2をPWMモード1で使用しています。

"MPC.~"はマルチファンクションピンコントローラです。MPC.PWPRは書き込みプロテクトレジスタで、機能制御レジスタ(MPC.PmnPFS:m=ポート番号,n=ビット番号)への書き込みを保護するものです。機能制御レジスタ(MPC.PmnPFS)は、同一のI/Oポート端子に割り当てられた複数の機能から、1つを選択して割り付けるレジスタです。機能制御レジスタに書き込むためには、書き込みプロテクトレジスタ(MPC.PWPR)で「書き込み許可」にしておかなければなりません。詳細は こちら を参照してください。

"SYSTEM.PRCR"はプロテクトレジスタで、モジュールストップコントロールレジスタ(MSTPCRx)などの重要なレジスタへの書き込みを保護するものです。モジュールストップレジスタなどに書き込むためには、プロテクトレジスタで「書き込み許可」にしておかなければなりません。詳しくは こちら を参照してください。

モジュールストップとは、周辺機能を停止させて消費電力を抑える機能です。リセット直後はモジュールストップ状態になっているので、周辺機能の使用を始める前に解除しておく必要があります。MTUの場合、モジュールストップコントロールレジスタA(MSTPCRA)の MSTPA9 ビットを '0' とすると解除になります(MSTPA9はMTU0~MTU5共通)。
具体的には、統合開発環境CS+が生成するファイル"iodefine.h"にあるマクロを使って、
「SYSTEM.MSTPCRA.BIT.MSTPA9 = 0;」と書きますが、
「MSTP(MTU) = 0;」と書くこともできます。
参考:IEN( ) もマクロを使った記述です。

MTU2の動作をグラフで表すと下図のようになります。
MTU2.TGRAによるコンペアマッチでMTIOC2A端子の'H', 'L' が反転するので、デューティ50%(='H'と'L'の幅が同じ)の矩形波が出力されます。もし、デューティ50%以外の波形が必要なときは、MTU2.TGRBによるコンペアマッチも使ったPWMモード1によって、自由に出力することができます。詳しくは「RX220グループユーザーズマニュアル ハードウェア編」を参照ください。
MTU2による矩形波発生動作タイミング例

4.プログラム例

下記に、MTU2を使ってMTIOC2A(PB5)端子から4kHzの矩形波を出力するプログラム例を示します。

ビープ音発生プログラム例

このプログラム例にある関数Beep( )を紹介します。

    void Beep(short nBitMax, int nRepeat, DWORD dwBitPattern);

1番目の引数nBitMaxがdwBitPatternの有効ビット数(b0からのビット数、最大32)を、2番目の引数nRepeatが鳴らす回数(繰り返し回数)を、3番目の引数dwBitPatternが発音パターンを示しています。例えば、Beep(9, 1, 0x00000057);とすると、"ピー、ピ、ピ"と1回鳴ります。

下図に各引数の意味と発音動作をまとめました(各引数の値は例です)。図にあるように、50mS周期でdwBitPatternをb0から順に評価し、'1'ならばMTIOC2A端子を「コンペアマッチでトグル出力」にして4kHzを出力、'0'ならば「出力禁止」にして発音を止めます。つまり、'1'が続けば連続音になり、'0'を挟めば断続音になります。
関数Beepの動作説明図
注4.発音を止めたいとき、タイマスタートレジスタ(TSTR)でカウント動作を停止させることによって停止させると、波形出力のMTIOC2Aは 'H' のまま停止することがあります。その場合、スピーカ駆動用トランジスタがONのままとなり、圧電スピーカに電圧がかかったままとなるので推奨できません。
プログラム例にあるBeep( )を使用した、その他の関数を一部紹介します。
    Beep_Stop(void); … 発音中の音を停止します。
    Beep_once(void); … "ピッ"と1回鳴らします。
    Beep_pi(int nRepeat); … "ピ"と鳴らすことを、nRepeatで指定した回数だけ繰り返します。
    Beep_pipipi(int nRepeat); … "ピピピピピ"と鳴らすことを、nRepeatで指定した回数だけ繰り返します。
    Beep_peapy(int nRepeat); … "ピー"鳴らすことを、nRepeatで指定した回数だけ繰り返します。

ここで示したプログラム例は4kHzの音を発生するだけですが、指定した周波数を指定した時間だけ発生できるようにすれば、音階を表現することもできます。つまり、矩形波のビープ音ではありますが、メロディを鳴らすことも可能です(音の大小は変えられません)。興味がある人は挑戦してみてください。→こちらも参照ください。

ホームページに戻るトップページに戻る前ページに戻る次ページに進む最終ページに進む
■■■ 注 意 ■■■
1.ここに掲載された内容(写真,図,表などを含む)の、全てまたは一部を無断で使用しないでください。
2.ここで紹介した手法(構造や仕組み,回路,プログラムなどを含む)を使用したことにより、問題や不利益が発生したとしても一切関知しません。
3.ここで紹介したプログラム例は、正常なコンパイルおよび正常な動作を保証するものではありません。