PIC24で出力コンペアを使用して,指定した周波数で矩形波を出力するnanoblog(ナノブログ)HomeWordPressJavaScriptC#読書メモ電子回路RSSPIC24で出力コンペアを使用して,指定した周波数で矩形波を出力する2012年10月13日PIC24Fには、タイマモジュールを使用した出力コンペア機能があります。出力コンペア機能には、以下の3つのモードがあります。フォルト保護入力なし今回はこの中で、2.デュアル比較一致モードの連続出力パルスモード機能を使用してみます。この機能を使用すると、任意の周波数/デューティー比で矩形波を出力でき、矩形波の出力によってスピーカから音を出したり、モータのPWM制御を行えます。今回の動作確認にはPIC24FJ32GA002を使用しました。作業の流れ出力コンペアを使用した矩形波出力のプログラムは、以下の手順で設定を行います。出力コンペア機能を使用するためには、どのピンで波形の出力を行うかをRPピンの役割マッピングで定義する必要があります。コンペア対象となる値をタイマーで作成するため、タイマーモジュールも使用します。タイマーのカウントスピードはCPUのクロック周波数にも依存するため、クロックやコンフィグの定義も確認しておきます。それでは、各ステップの具体的な作業を順に確認していきます。出力コンペア機能の使用有無に限らず、PICのプログラムを作成する場合は、PICの振る舞いを決めるためにコンフィグレーションビットの設定が必要です。今回は以下の設定にしました。);コンフィグレーションビットでは、FNOSC_FRCで内部オシレータを使用させています。ほかの定義は、今回のプログラムの本質ではないので説明は省略します。次にクロックの定義をします。今回は、PIC内蔵のオシレータを8MHzで使用します。セカンダリオシレータ(32kHz)を有効にする内部オシレータを使用するには、_CONFIG2()でFNOSC_FRCの定義が必要です。今回は使用しませんが、オシレータの個体差によるずれを微調整するためのレジスタとしてOSCTUN.TUNが有ります。出力コンペアモジュールは内部的にタイマモジュール(TMRn)を使用します。このタイマーの周期にしたがって波形が出力されるため、この値は出力される周波数に関係します。ON出力コンペアを使用する場合、元にするタイマはTimer2かTimer3のどちらかが使用できますが、今回はTimer2を使うことにします。タイマモジュールも幾つかの動作モードが有りますが、今回は16bitタイマのモードを分周せずに使う事にします16bitモードなので、最大では0~65535までカウントさせる事が出来ますが、今回は説明を簡単にさせるために、4000までカウントしたらリセットさせる事にします。タイマーの最大値はPR2レジスタにセットします。値をセットした後、T2CONレジスタのTONを1にするとカウンタが動作します。デバッガやシミュレータで、ステップ実行させてTMR2レジスタを観察すれば値が増えていく事がわかります。RPピンの役割マッピング設定タイマが用意できたら、次は波形を出力させるピンを決めます。PIC24FJxxGA002では、出力コンペア結果の出力先をRP0~15のピンに割り当てる事が可能です。今回は、RP5のピンに割り当てる事にしました。19:OC2に割り当てるRPxの出力ピン機能割り当てはRPORxレジスタにFunctionCodeをセットすることで設定します。RP5の機能設定はRPOR2レジスタのRP5R、出力コンペア1(OC1)のFunctionCodeは18なので、上記のコードとなります。RP6ピンの機能を19:OC2に割り当てています。PIC24FJxxGA002では、出力コンペアモジュールが5個内蔵されているので、18:OC1~22:OC5のFunctionCodeが指定できます。次は、いよいよ出力コンペアモジュールの設定です。ここまでの設定でOC1,Timer2モジュールを使用する事にしたので、以下の様な設定になります。なるタイミング出力コンペアモジュールの1番目を使用するので、設定するレジスタは、OC1CON、OC1R、OC1RSになります。このモジュールが使用するタイマーはTimer2なので、OC1CONbits.OCTSELに0:Timer2を指定します。ここまでの設定で、出力される波形の周波数、On/Offの比率(デューティー比)が決まります。周波数は、以下の式で求まります。1/1000という訳で周期が1mSecとなり、1kHzの波形が出力されます。周波数は、式を見て分かるとおり、PRの値・Timer2の分周・CPUクロックに応じて決まります。矩形波がOn/OffするタイミングはOC1R,OC1RSの値で決まります。今回は、OC1RをPR2と同じ値、OC1RSがPR2の半分に設定したので、TMR2レジスタの値が0~2000の時はLow、2001~4000の時はHighというDuty比50%の波形になります。サンプルプログラムという訳で、今回作成したサンプルのプログラムです。}このプログラムを実行させると、RP5のピンから1kHzの波形が出力されます。本当に波形が出ているかは、オシロスコープなどを使用しないと分からないのですが、1kHzだったらスピーカを繋ぐことで確認する事ができます。手元にあった8オーム,0.5Wの小さなスピーカを直結してみましたが、十分な音量で聞くことが出来ました。1kHzの音がどれくらいの高さかは、以下のwavファイルで確認できます。1kHz.wav500Hz.wav440Hz.wavPR1レジスタの値を変えると周期(音の高さ)を変えることが出来ます。8000に変更すると周期が2倍になるので、500Hzになります。500Hzはドレミで言うと、”シ”(B3)の音に近いです。応用:スピーカーを使ってメロディを奏でてみる今回作成したプログラムでは、決められた周期の波形を出すものでした。これを、タイミングにあわせてPR1レジスタの値を変えていくことで音楽を奏でる事が出来ます。試しに”カエルの歌”を演奏させるプログラムを作成してみました。}pr2dataの配列に、各音階に応じたPR2の値をセットしています。値は近似値で誤差が有るので、ちょっと音痴なメロディーになっているかもしれません。こんな感じで再生されます。kaeru.wma演奏する曲は、melodyの配列で指定してます。簡単なサンプルなので音の長さは指定できませんが、値を色々変えてみて遊んでみてください(ループの130000を可変にすることで、音の長さを調整できます)。PR2に設定するデータ指定を配列からではなく、外部に接続したスイッチからにすれば電子オルガンを作ることも出来ます。コメントをキャンセルメールアドレスが公開されることはありません。29お勧め書籍webアプリのセキュリティ対策の為に。