Home

  正弦波発生器のいくつかの方法                  ソースプログラムPWM 補足説明 Ver.2.3 '20/05/21                ソースプログラム更新(PWM、CPM方式両方) Ver.2.2 '15/09/26          回路図更新:フィルターに抵抗追加(PWM、CPM方式両方) Ver.2.1 '15/09/17                       PWM方式を追加し関連を変更 Ver.2.0 '15/09/09                                    Ver.1.0 '15/09/04                           All rights reserved JA3OOK 中村 利和  CWモニター用の正弦波の発生を試みました。いくつかの方式を比較検討し、その動作結果を記 載しました。私が一番気に入った方法についてはC言語のソースプログラムと回路図も載せました。   1.目標の仕様    周波数     400Hz〜1000Hz程度の範囲で、ボリュームで連続的に可変できること。    波形     正弦波またはそれにできるだけ近いこと。     CWモニター音としては高調波が混じっているほうが聞きやすいとの意見もあるが、     ここでは高調波が少ないことを目指した。    出力     ヘッドホンで聞いて十分な出力があること。ボリュームでの音量調節もできること。    部品数など     部品点数が少なく、簡単な回路、再現性が高いこと。 2.発生方式の検討と実験結果のまとめ    次の方式を検討し実験した。 これは、あくまでも数少ない実験の結果であって、   部品や回路、プログラムの違いによって変わることが予想される。   また、技術の進歩に応じて再検討し実験を重ねる必要がある。
MCU PWM方式 MCU CPM方式 MCU DAC方式 MCU はしご型抵抗方式 OP-AMP方式
基本原理 PWMモードを使用 CPMモードを使用 DA変換機能を使用 DA変換をプログラムと外部抵抗で実現 正帰還発振
基幹部品 PIC16F1936 PIC16F1936 PIC16F1936,OPアンプ MPU,OPアンプ OPアンプ
構造(部品点数) 簡単 簡単 入力インピーダンスが特別高い出力バッファ(OPアンプ)が必要 多数の抵抗が必要
入力インピーダンスが特別高い出力バッファ(OPアンプ)が必要
複雑
調整の容易さ 調整不要 調整不要 調整不要 調整不要、抵抗値をそろえること 調整必要
正弦波のきれいさ 良好 良好 上部と下部が歪む 良好 波形歪が多い
補足説明 欲しい周波数によってPICの型番を選ぶこと。
PICによっては正弦波にならない。
PICの型番によっては高い周波数で正弦波にならない。 つまり、波形カーブのきつい箇所が正弦波に似なくなる。 実験せず
文献1を参照
正弦波の周波数範囲が狭い
耳での評価 良好 周波数変更時などに
プツプツ音
未評価
たぶん良好
未評価
たぶん良好
 良
拡張性など 正弦波のみ 正弦波のみ 三角波、矩形波なども発生可能と思われる(未実証)
DA変換のビット数強化に期待
三角波、矩形波なども発生可能と思われる(未実証)
総合評価
説明の項番
 MCU:Micro Computer Unit ワンチップマイコン、製品としてはPICやAVR、H8など  PWM:Pulse Width Modulation、パルス幅変調  CPM:レジスター値とレジスター値を比較して一致すると割り込みが発生する方式  DA変換:digital Analog 変換、数値に応じた電圧を発生させる機能  以下、各方式について説明する。  注意事項   ・スペクトル波形はパソコンで観測すると、周波数の低いほう、高いほうほど激しく上下に    揺れ動いていて、以降での説明で使用しているスペクトル図は揺れている一瞬を捉えている    だけである。    従って図と図を比較検討する場合は傾向として理解すること。   ・PICなど手持ちの部品を有効使用している。目的にそって選択し購入すればもっと良い成果が    でるかもしれない。 3.MCUを使用したPWM方式   今回の実現方法を次の図で説明する。    正弦波棒グラフ   このグラフは正弦波1サイクルを36個に分割し、近似した値を棒グラフで描いている。  このグラフで示される棒の値をこの順序で電圧として出力し、つないでいけば正弦波(に近い波)  が得られるであろうことが予測できる。   棒の値の電圧を得る方法としてPWM信号技術を利用する。それは、一定のパルス間隔において、    ・低い電圧が必要な場合はパルス幅を狭く    ・高い電圧が必要な場合はパルス幅を広く  し、信号を連続的に平均化する(ローパスフィルターを通す)ことで希望の電圧を得ることが  できるのである。   棒グラフの高さに応じた電圧を出力するのにPICが内蔵しているCAPTURE/COMPARE/PWMモジュー  ルをPWMモードで使用する。   PWMモードでの出力波形とスペクトル。500Hz、PIC16F1936 Fosc16MHz。    PWM    周波数が高くなるほどギザギザの目立たない波形になる。下記は600Hz。右は1000Hz。    600Hz 1000Hz    高調波が気になる場合は、ローパスフィルターの段数を増やすなどの方法で改善の余地はあ    る。       その後の追試:ローパスフィルターの出力に100kΩを追加した方が高調波の低減に効果       が高いことを確認した。(理由はローパスフィルターの性能が発揮されるからと思う)    4項CPM方式と比べると、    波形     どちらも同じ程度に正弦波に近い。(同等)    スプリアス     こちらの方が高い周波数成分が低い。(PWM有利)    耳で聞いた評価     問題なし。周波数変化ボリュームを左右まわしてもノイズもなく周波数変化もスムーズ。     (PWM有利)    実装の自由さ     ボリュームで可変できる周波数範囲がPICのクロック周波数に依存する。(PWM不利)      (Compareモードの場合はクロック周波数によらず、周波数範囲をプログラミングでき       る。もちろんFoscが低すぎるとだめだが)     具体的にはクロック周波数(Fosc)が例えば       16MHzなら 434Hz〜        20MHzなら 542Hz〜     となる。従ってPIC型番を自由に選べず、クロック周波数に注目する必要がある。      今回はPIC16F1936をFosc16MHzで動作させ、発生周波数は434Hzから1070Hz程度、     仕様をほぼ満たしている。          説明 オーディ周波数の下限が自由に設計できない理由は、        PICのPWM Frequency(つまりパルス間隔)が、         ・Fosc         ・プリスケーラ         ・PRレジスタ値       で決定されるから。(出典:PICデータブックのPWMの項)       参考:        オーディオ周波数=Fosc/4/プリスケーラ/(PRレジスタ値+1)/オーディオ分割個数                =Fosc/4/256/36          ただし、条件は次の通り。           ・プリスケーラは1:1           ・PRレジスタの最大値は周波数可変幅が大きくとれる255           ・オーディオ1サイクルを36個のパルスで構成   このPWM方式のC言語ソースプログラムはこちら。     ・PWM方式正弦波発生CソースプログラムPIC16F1936_16MHz 20150926更新     ・LCD_driverソースプログラムPIC16F1936_16MHz     ・LCD_headerソースプログラム     補足説明(Ver.2.3 '20/05/21)      そのメインプログラム:ファイル名:SideToneOsc_PWM_16F1936_16MHz_20150926submit.c      の122行目から割込みルーチンがある。      その中に次の2行がある。 CCPR1H = (wave_style_ccpr[tm2_count] >> 8); // パルス幅の設定 CCPR1L = (wave_style_ccpr[tm2_count] & 0x00FF) ; // パルス幅の設定      これは間違っていて、 CCPR1L = (wave_style_ccpr[tm2_count] >> 2); // パルス幅の設定 char k = ((wave_style_ccpr[tm2_count] << 4) & 0b00110000) ; // パルス幅の設定 CCP1CON = k | 0b00001100 ; // PWM      が正しいコーディングです。      さらに、196および231行目の wave_style_ccpr[i] = j_uint; //パルス幅(の計算の元)設定      は、 wave_style_ccpr[i] = j_uint << 2; //4倍する      が正しいコーディングです。      つまり、        1 デューティ サイクル値を計算する時に4倍しておき        2 CCPRxLレジスタには上位 8 ビット、CCPxCONレジスタのDCxB ビットに         下位 2 ビットを書き込む      のがデータシートに基づく素直な手順です。      ところが、その(ダウンロード用)プログラムでは        1 デューティ サイクル値を計算する時に4倍しなくて        2 割込ルーチン内でCCPR1LとCCP1CONレジスタに格納する時に4倍      しています。      動作結果に違いは出ません。      なので、ダウンロード用プログラムを修正しませんが、気になる方は補足説明とおり      に各行を修正するか、次の一行 CCPR1H = (wave_style_ccpr[tm2_count] >> 8); // パルス幅の設定      だけコメントアウト(コメントにすること)または削除してください。             補足 ソースプログラムのインデンテーション(段落付け)について。      上記のソースはMPLAB X IDE 対応で、4カラム毎のtabで書かれている。      メモ帳などは8カラム毎なので段落付けは変。(プログラムの動作には支障ない)      TeraPadだと4カラム毎のtab設定が簡単にできる。    開発環境は     ・MPLAB X IDE v2.10 (Microchip)     ・XC8 C Compiler Free mode v1.34 (Microchip)     ・チップへの書き込み PICkit3+秋月PIC書込アダプター     MPLAB X IDE にProjectを作るとき文字(Encoding)の種類はShift_JISを指定。   回路図。(ローパスフィルターに100kΩを追加したが、掲載の波形やスペクトル図は変更前のもの)     PWMでの回路図   参考にPIC16F88のPWMでの波形がこれ。700Hz、Fosc20MHz。    CCP方式出力スペクトラム    かなり歪んでいる。図はないが周波数変えてもだめ。ちなみに、Fosc8MHz で動作させても    同様に悪い。    PWMでもPIC型番によって得意、不得意があるようだ。        PIC16F1936のPWMモードで上記のように正弦波を得られたが、ここまでたどり着くまでに   は紆余曲折があった。興味がない方は読み飛ばしてください。    PWMモードでの実現のためにPIC16F88とPIC16F1936、PIC18F25K22のデータシートとWebを調   べて検討を始めた。   そして、PICのどのデータシートにも次の文と図があり、これがキーポイントと考えた。     The Timer postscaler is not used in the determination of the PWM frequency.     そしてタイトルが SIMPLIFIED PWM BLOCK DIAGRAM の図。          「ポストスケーラーはPWM周波数の測定で使われない」、そして     「図にはタイマー割込み発生フラグ(TMRxIF)を Setする線がかかれていない」 ので、     結論は「ポストスケーラーは働かず、割込みもプログラムで検出できない」と解釈した。    そこで、しかたなく、PWMモードでのパルス幅を変化させる方法として、   PWMパルス間隔(タイマー2)と同じ間隔で割込みをタイマー1で発生させ、割込みごとにパル   ス幅を変化させることとし、PIC16F88で実験した。   これでの動作結果。700Hzの波形 PIC16F88 TMR1sync Fosc20MHz。     PWM方式出力スペクトラム    かなり乱れた波形である。    タイマー2とタイマー1の周期が一致していないことが主な原因と推定できるが、他にもあ    りそうだ。   そして考えた・・・     割込みをプログラムが検出できるPICの仕様であれば綺麗な正弦波を発生できるように思     える。しかし、検出できない仕様ということは、何か深い理由があるのかも・・・     壁にぶち当たり、割込みの検出をあきらめていたが、どうにも寝つきが悪いので、PICを変更   して実験してみることにし、PIC16F1936で割込みでの発生を試みた。   そしたら、「割込みが発生」しているのだ。割込みルーチンが動き TMR2IF がONになっている。   PIC16F88でもやってみたら同じように「割込みが発生」しているのだ。   このPWM割込み方法で発生した波形が前述の(PIC16F1936とPIC16F88のそれぞれきれいな方の)波形。    データシートの文と図の真意は     「ポストスケーラーはPWM周波数の測定で使われない。       → ポストスケーラは使われず通過し、割込みも発生する。」   が正解なのだ。 私の考えすぎ!だったのかな? 4.MCUを使用したCPM方式   棒グラフの高さに応じた電圧を出力するのにPWM信号技術を利用することは前項PWM方式と同じ  だが、PWM信号の発生に、PICが内蔵しているCAPTURE/COMPARE/PWMモジュールをCompareモード  で使用する。   Compareモードで発生した出力波形とスペクトル。500Hz、PIC16F1936 Fosc32MHz。    CCP方式出力スペクトラム    周波数が高くなるほどギザギザの目立たない波形になる。下記は600Hz。右は1000Hz。    600Hz 1000Hz   参考にPIC16F88での波形。600Hz、Fosc20MHz。    CCP方式出力スペクトラム    波形の下側のカーブが良くなく、そのせいで高調波のレベルも高い。    ちなみに、PIC16F1936 を同じ20MHz で再現させても32MHzでの波形に近い綺麗な波形である。    PIC型番によって得意、不得意な分野があるようである。   耳で聞いた評価    ボリュームで周波数を上げていくときプツプツと音がする。ボリュームを止めていても出て    いるときがある。最大の難点。    波形を見ていてもわずかな違和感しか見えない。確かに波形表示の同期が飛ぶ。    耳はすばらしい測定器だ。    なお、周波数を下げていくときは問題ない。    従って、今回の使用目的からすれば、モニタートーン周波数を変えることは少ないので    実用上の問題はないと思うが、精錬された製品とは言いがたい。    なお、PIC16F88のCPM方式でも同様の現象がある。   以下は発生方法の説明。   正弦波周波数1000Hzを発生させるのに必要なパルス間隔を試算すると、    ・周波数1000Hzの1サイクルの時間間隔:1000μs    ・1サイクルを36分割  であるので、    ・パルス間隔は 1000μs/36=27.7μs   従って、プログラムの要点は    ・上記の棒グラフの値(0から100)を配列に定数として持たせておく。     (36分割点の正弦波対応の値はExcelで予め計算しておく)    ・タイマーを使って27.7μsごとに割り込みを発生させ    ・割込みごとに棒グラフの値のパルス幅を順に出させ、36回割込み毎に繰り返す。    ・モニター音の周波数の変更はパルス間隔を変更することで実現する。     つまり、36パルスでモニター音の1サイクルであるので、パルス間隔を変えるとモニター     音の周波数も変わる。    ・パルス間隔は、可変抵抗器からの外部電圧をAD変換で取り込んでタイマーの割込み間隔を     変化させる。    ・波形はCPUスピードが速いほど綺麗なので、使用するPICの最高速度で動作させる。     PIC16F1936においてはクロック周波数(Fosc)32MHz。    上記の試算では割込み間隔:27.7μsで1000Hzを発生できるが、実際に動作させると830Hzを    発生し試算と異なった。    従って、発生したい周波数に合わせて割込み間隔を実験で決める必要がある。    (計算と実際の割込み間隔が異なる理由は、プログラム上の割込み処理ルーチンのオーバー     ヘッドで割込み間隔が延びていると思われる)   プログラム上の留意点     CPM方式の場合、ずっと高い周波数まで正弦波を発生できるか?    この画像は一定以上の高い周波数(2400Hz程度)での乱れた波形。    乱れ波形    原因ははっきりしないが、症状としては次の条件がそろうと、      ・パルス間隔(割込み間隔)が狭い、つまり周波数が高い      ・デューティ比が高い(CCPレジスターに設定する値がオーバーフロー値に近い)         デューティ比:パルス幅とパルス間隔の比率    この現象になるようだ。確定的ではないが・・・    PIC16F1936 32MHz では2400Hz程度まで乱れなかったが、PIC16F88 20MHz では990Hz程度ま    でであった。     この現象をある程度高い周波数まで発生させないように、プログラム内の下記の計算式で    CCPレジスター(CCPR)値を決めている。分母を100にしないことがポイント。      CCPR値 = 正弦波カーブ値 / 分母 × パルス間隔 + タイマー設定値        正弦波カーブ値 :カーブに沿った棒グラフの値で、0〜100。        パルス間隔   :タイマーが1パルス間にカウントする値        分母      :128程度の値。本現象がなければ100。                 なお、分母の値が100に近いほど、                   デューティ比、分解能、出力される電圧                 が高くなり、ちょうど良い値を実験して決める。        タイマー設定値 :割込み間隔つまりパルス間隔をタイマーに設定する値。        詳細はC言語ソースプログラムを参照のこと。   C言語ソースプログラムと正弦波波形の値を計算したExcelはこちら。     ・CPM方式正弦波発生CソースプログラムPIC16F1936_32MHz 20150926更新     ・LCD_driverソースプログラムPIC16F1936_32MHz     ・LCD_headerソースプログラム     ・正弦波計算Excel     補足 ソースプログラムのインデンテーション(段落付け)について。      上記のソースはMPLAB X IDE 対応で、4カラム毎のtabで書かれている。      メモ帳などは8カラム毎なので段落付けは変。(プログラムの動作には支障ない)      TeraPadだと4カラム毎のtab設定が簡単にできる。    開発環境は     ・MPLAB X IDE v2.10 (Microchip)     ・XC8 C Compiler Free mode v1.34 (Microchip)     ・チップへの書き込み PICkit3+秋月PIC書込アダプター     MPLAB X IDE にProjectを作るとき文字(Encoding)の種類はShift_JISを指定。   回路図。(ローパスフィルターに100kΩを追加したが、掲載の波形やスペクトル図は変更前のもの)     CPMでの回路図 5.MCUを使用したDAコンバーター方式   棒グラフの高さに応じた電圧を出力するのにPICが内蔵しているDA変換機能を使用している点が、  3項PWM方式や4項CPM方式と基本的に異なる。   今回使用したPIC16F1963では、指定できる出力電圧の細かさ(分解能)が32段階(0から31)で  ある。   出力波形は次の通りギザギザ波形である。PIC16F1963 Fosc32MHz   DAC方式出力波形 DAC方式出力波形   この原因は分解能が32段階と粗いからである。ローパスフィルターを通せば直線に近いカーブ  の部分はあまり問題ないだろうが、上下端の部分は正弦波にくらべて違いが大きい。  上下端の問題はExcelで計算した時点から現れており、上端で値31が三つ、下端で値0が三つ並ん  でいて、31段階では正弦波を正しく表現できないことが分かる。  右の画像は三角波を出力している。綺麗な三角波である。   DAコンバーターからの出力インピーダンスが非常に高く、ローパスフィルターのような軽い負  荷でも波形が大きく乱れるので、上記の写真はオシロスコープだけを接続し撮影した画面。(オ  シロスコープは入力インピーダンスが格段に高い=負荷が軽い)  発振器として実用化する場合は、次段に入力インピーダンスが高いバッファを入れることが重要  である。出力のボリューム調整も必要で2〜3段のOPアンプ構成になるだろう。  分解能がもっと大きい(64段階とか)MCUを使用できれば魅力的な方式である。 6.MCUを使用した梯子(はしご)型抵抗方式   この方式は私は実験していず、参考文献1 「上野光博氏 ラダー抵抗回路によるD/A変換の  仕組み」 などで机上で検討した。  2項のDA変換方式を「外付けのはしご型抵抗とプログラム」で高い分解能を実現した優れた方式で  ある。   素直な正弦波を発生できるし、プログラム次第で三角波や矩形波なども自由に作れる。  出力インピーダンスが高いことと、値が揃った抵抗をチョイスする必要があることが留意点。    7.OPアンプ方式   OPアンプを使った方式に色々なバリエーションがあり、私が実際に製作したものとしては、  OPアンプ式オーディオ発生器がある。  1項の方式比較表はこの経験をもとに作成した。 謝辞  ・波形図やスペクトル図は efu さん提供の「WaveSpectra 高速リアルタイム スペクトラムアナ   ライザー」を利用しています。  ・回路図は水魚堂提供の「回路図エディタ」で作図しています。  ・画像のトリミングなどの編集や画像ファイル変換は ねたろ さん提供の「Dibas」を利用してい   ます。Windows7でも問題なく動作しています。  深く感謝します。 参考文献 1 上野 光博 PICで遊ぶ電子工作 の 7章.基礎知識など の (13) ラダー抵抗回路によるD/A変換の仕組み 2 Microchip社 PIC16F87/88 Data sheet 30487D.pdf 3 Microchip社 PIC16F193X.pdf 4 efu WaveSpectra 高速リアルタイム スペクトラムアナライザー 5 寺尾 進 TeraPad 6 水魚堂 回路図エディタ 7 ねたろ 横田 幸之介さん Dibas フリーのお手軽レタッチソフト

 直前の画面へは ブラウザの戻る をクリックしてください。Topに戻るにはHome