MTUでブザーを鳴らして、“あの”レベルアップ音を再現したい!:マイクロマウスで始める組み込み開発入門(9)(3/3 ページ)
マイクロマウスの市販組み立てキットを完成させた北上くんとえみちゃん。サンプルのソースコードに頼らず、オリジナルプログラムをイチから組もうと奮闘中。今回は、MTUのPWMモードを使ってブザーの制御にチャレンジする。
ドライバとコントローラの作成
続いて、ブザードライバの作成に入ります。「drv.h」にブザー用のポートやレジスタの定義を追加します(ソースコード6)。
void drv_bz(int, int); //ブザードライバ //ブザーMTUポート #define MTU_BZ MTU2.TSTR.BIT.CST2 //ブザー用MTU //ブザーMTU発振数 #define MTU_BZ_CLOCK 24000000 //ブザー用MTUの発振数(24MHz) //ブザーMTUレジスタ #define MTU_BZ_CYCLE MTU22.TGRB //ブザー周期を設定 #define MTU_BZ_PULSWIDTH MTU22.TGRA //ブザーパルス幅を設定
「drv.c」にブザードライバ「drv_bz」を作成します。引数には「周波数」「時間」「ボリューム」の3つを与えます(ソースコード7)。
/************************************************/ /* 周波数、時間(ms)を指定してブザーを鳴らす */ /*----------------------------------------------*/ /* IN :int i_freq … 周波数 */ /* int i_ms … 時間(ms) */ /************************************************/ void drv_bz(int i_freq, int i_ms) { //ブザードライバ float cycle; float pulsWidth; // if (i_freq == 0) { //Wait drv_wait_ms(i_ms); } else { //周波数を設定 cycle = (float)MTU_BZ_CLOCK / (float)i_freq; pulsWidth = cycle /2.0; MTU_BZ_CYCLE = (short)cycle; MTU_BZ_PULSWIDTH = (short)pulsWidth; //発振 MTU_BZ = BZ_ON; //ブザーの発振を開始 drv_wait_ms(i_ms); //指定時間 待つ MTU_BZ = BZ_OFF; //ブザーの発振を終了 } }
「ctrl.c」にブザードライバを呼び出す処理を追加します(ソースコード8)。
void ctrl_bz(int i_freq, int i_ms) { //ブザー処理 drv_bz(i_freq, i_ms); //鳴らす }
アプリケーションの作成
ここまでの処理で、ブザーを鳴らすことができるようになりました。まずは、前回作成した“スイッチを押してLEDを2進数で点滅させるプログラム”に、ブザー音も追加してみましょう。「app.c」内のapp_dispMode関数に、音階の配列「freq[15]」とブザー鳴動を追加します(ソースコード9)。
void app_dispMode(int i_mode) { int freq[15] = {BZ_FREQ_DO ,BZ_FREQ_RE ,BZ_FREQ_MI ,BZ_FREQ_FA ,BZ_FREQ_SO ,BZ_FREQ_LA ,BZ_FREQ_SI ,BZ_FREQ_DO2 ,BZ_FREQ_RE2 ,BZ_FREQ_MI2 ,BZ_FREQ_FA2 ,BZ_FREQ_SO2 ,BZ_FREQ_LA2 ,BZ_FREQ_SI2 ,BZ_FREQ_DO3 }; //モード表示 ctrl_led_num(i_mode); //LEDにモードを表示 ctrl_bz(freq[i_mode-1], 100); //ブザー鳴動 }
ブザーが音階で鳴ることが確認できました(動画1)。それでは、えみちゃんのやる気に応えて、“あの”レベルアップ音が鳴るようにプログラムを組んでみましょう。「ctrl.c」に、ブザーでメロディーを鳴らすプログラムを追加します。
メロディーを奏でるためには、周波数の他に拍数とテンポが必要になります(ソースコード10)。
/************************************************/ /* IN :int i_freq … 周波数 */ /* int i_beat … 拍数(四分音符=2) */ /* int i_tempo … テンポ(1分間の拍数) */ /************************************************/ void ctrl_bz_melody(int i_freq, int i_beat, int i_tempo) { //ブザー処理(メロディ) int ms = (i_beat * 60 * 1000 / 2) / i_tempo; // drv_bz(i_freq, (int)(ms * 0.9)); //鳴らす drv_bz(BZ_FREQ_REST, (int)(ms * 0.1)); //間隔を空ける }
今回は、モード1を実行したときに、レベルアップ音を呼び出せるようにしておきます。アプリケーションでは、テンポを設定して、ctrl_bz_melody関数に音階と拍数を指定するだけで、メロディを奏でられます(ソースコード11)(動画2)。
void app_mode1(void) { //レベルアップ音 int tempo = 200; // ctrl_bz_melody(BZ_FREQ_SO,1, tempo); ctrl_bz_melody(BZ_FREQ_SO,1, tempo); ctrl_bz_melody(BZ_FREQ_SO,1, tempo); ctrl_bz_melody(BZ_FREQ_FA,1, tempo); ctrl_bz_melody(BZ_FREQ_REST,1, tempo); ctrl_bz_melody(BZ_FREQ_LA,1, tempo); ctrl_bz_melody(BZ_FREQ_SO,4, tempo); }
>>ソースコード(Mouse201301.lzh)のダウンロードはこちら
は〜。今日は、いろんなことを覚えたんで頭がクラクラですよ。
MTUとPWMは、マイコン制御の“要”と言ってもいいくらい大事なところだからね。
自分がレベルアップできた感じでうれしいです!!
それはそうと……、そろそろご飯食べに行きませんか?
うん。じゃあ、寒いからモツ鍋とかどう?
あっ、いいですね! 温まりそう〜。
ちゃららっ、ちゃっちゃっちゃーん♪ えみちゃんもマイコンプログラムに慣れて、徐々にレベルアップしてきたようですね。
マイクロマウス競技では、センサーが走行中に壁の切れ目を見つけたときや、迷路データを解析している間にブザーを鳴らして、ユーザーにマイコンが現在どのような処理をしているか知らせることがよくあります。タイミングよくブザーを鳴らすためには、前回学んだ「割り込み処理」が必要になります!
次回は、センサーの処理について解説します。お楽しみに! (次回に続く)
ロボット/ロボット開発 コーナー
Copyright © ITmedia, Inc. All Rights Reserved.