dsPIC33FJ128GP802

目次:


テスト回路

  回路図と実際の回路を以下に示します。回路は、ユニバーサル基板(Takasu IC-701-72)上で組んでいます。コンデンサーと固定抵抗は、すべてチップ型のもので、基板裏面に半田づけしています。また,水晶発振子(Xtal)には10MHzのものを用いています。PIC内部では40MHzがシステムクロックとなるようファームウェアで設定します。



回路動作確認

  PIC用のファームウェアをコンパイルするためには、あらかじめMPLAB X IDE v4.05をインストールした後、MPLAB XC16 Compiler v1.33 と PIC24/dsPIC Peripheral Libraries v2.00をインストールします。さらに、Microchip Libraries for Applications v2017-03-06もインストールします。

まず、作成した回路がきちんと働いているかどうかを確かめます。ファームウェアblinkGP802.zipをPICに書き込み、実行します。

1.ピンヘッダJP1にはファームウェア書き込み器(たとえばICD3)を接続します。また、3.3Vの電源も接続します。

2.blinkGP802.zipを解凍して出てくるblinkGP802フォルダーmicrochip\mla\v2017_03_06\appsフォルダーの中に入れます。

3.MPLAB X を立ち上げ、blinkGP802フォルダーの中にあるプロジェクトを読み込みます(MPLAB XのメニューからFile->Open Project...を選択)。

4.Projectsウィンドウにおいて、blinkGP802と書かれた箇所をマウスで右クリックして、サブメニューを出します。そのサブメニューのSet as Main Projectという項目がありますので、それを選択します。blinkGP802が太文字になったことを確認します。

5.ファームウェアを実行するために、MPLAB X のツールバーからRun Main Projectアイコン)をマウスでクリックします。一回目は、以下のようなウィンドウが現れ、お使いの書き込み器(プログラマー)を尋ねられますので適切に設定します。設定後、ウインドウの下方にあるOKボタンをマウスでクリックすると、ビルド(コンパイルとリンク)が実行され、ファームウェアがPICに書き込まれ、そして実行されます。

ファームウェアを実行すると、1秒周期のパルス( 3.3V, 0V, 3.3V, ...) がPICの14番ピン(RB5ピン)から出力されますので、テスターで、このピンの電圧を測定してください。もし、パルスが出ていなければ回路に問題がありますので、回路を再チェックしてください。 main.cmain(void)関数の中身をみれば、何をしているのかが簡単に分かると思います。



注意

1.以下のzipファイルを解凍して出てくるフォルダーは、microchip\mla\v2017_03_06\appsフォルダーの中に入れます。

2.以下、FFT(シミュレーション)のように、「シミュレーション」と書いてある節では、ファームウェアはシミュレーターで実行します。シミュレーターを使うためには、 MPLAB X を立ち上げ、プロジェクトを読み込み、Projectsウィンドウにおいて、プロジェクト名の箇所をマウスで右クリックして、サブメニューを出します。このサブメニューの一番下にPropertiesという項目がありますので、それを選択します。Project Propertiesウィンドウが現れるので、以下の図のように、Hardware ToolとしてSimulatorを選択します。

シミュレーターではPICは必要ありません。MPLAB XがPIC動作をシミュレート(模擬)します。

3.FFT(シミュレーション)BPF(シミュレーション)FFT(PIC回路での動作確認)BPF(PIC回路での動作確認)の各節におけるファームウェアでは、dspライブラリ(libdsp_elf.a)を使用しています。現在はXC16 Compiler v1.33のライブラリを使用していますが、今後バージョンアップが有った場合、ライブラリーのある場所(パス)が変わります。以下の図を参照して、パスを適切に設定し直してください。Librariesの箇所を右クリックして、Add Library/Object File...を選択します。

ライブラリファイルがある場所を聞かれますので、適切に設定します。

古いパスは消します。具体的には、消したいライブラリ名のところを右クリックして、Removeを選択します。

4.DataSheets.zipは、以下のファームウェアを作成するときに利用したデータシートです。Microchip社が用意してるものですが、分かりやすいようにファイル名を変えています。



タイマー2割り込み

  dsPIC33FJ128GP802は16ビット・タイマーを5つ持っています。それぞれのタイマーを個別に16ビットタイマーとして使用できます。ここでは タイマー2割り込みを使い、周期0.8秒のパルスを作ります。 ファームウェアはtimer2GP802.zipです。このファームウェアを走らせる(実行する)と、0.8秒周期のパルス( 3.3V, 0V, 3.3V, ...) がPICの14番ピン(RB5ピン)から出力されます


タイマー23割り込み

  タイマー2と3、あるいはタイマー4と5を繋げて、32ビットタイマとして使用できます。長い時間のタイマーが必要なときに使用します。ここでは、 タイマー23割り込みを使い、周期10秒のパルスを作ります。ファームウェアはtimer23GP802.zipです。このファームウェアを走らせる(実行する)と、10秒周期のパルス( 3.3V, 0V, 3.3V, ...) がPICの14番ピン(RB5ピン)から出力されます


12ビットADC(DMAなし)

  dsPIC33FJ128GP802は12ビット・アナログ・デジタル変換器を持っています。テスト回路では、10KΩの可変抵抗器でVCC(+3.3V)を分圧して得られた電圧をPICのAN9ピン(26番ピン)に入力しています。このアナログ電圧をタイマー3の割り込み時に読み込み(250 msecの繰り返し)、デジタル変換して、その結果(符号なしの整数)、変数adcBuffer(system_init.cの中にある)に入れています。以下の図のように、system_init.cの132行目にブレーク・ポイントを設定し、デバッグモードでファームウェアを実行します。

この図の場合には、変数adcBufferには0x0B6Eが入っています。10KΩの可変抵抗器を変化させると、それに伴って、この値が変わります。デジタル変換結果を符号なしの整数に設定していますので、0x0000(ADSSの電圧)が0Vで、0x0FFFが3.3V(AVDDの電圧)を意味します。変数adcBufferに入る結果に3.3V掛けて、0x0FFF割れば、PICのAN9ピンに印加されている電圧値が計算できます。ファームウェアはadcGP802_2.zipです。


12ビットADC(DMAあり)

  上記 adcGP802_2 で、測定値を格納するメモリ(DMAピンポン・バッファ:32ワード)を2個用意して、これら2個のメモリを交互に使っています(ピンポン動作:卓球の玉が2つのコートの間を行ったり来たりすることになぞらえているのだと思います)。 以下の図のように、 system_init.cの172行目にブレーク・ポイントを設定し、デバッグモードでファームウェアを実行します。

この図ではDMAバッファの1つであるBufferBの内容を表示させています。10KΩの可変抵抗器を変化させると、それに伴って、この値が変わります。なお、変数 aa は、2回DMA割り込みがかかったとき、すなわち、BuuferABufferBの両方に測定値が入ったときに、ファームウェアが一時停止するようにするためのものです。 デジタル変換結果を符号なしの整数に設定していますので、0x0000(ADSSの電圧)が0Vで、0x0FFFが3.3V(AVDDの電圧)を意味します。変数adcBufferに入る結果に3.3V掛けて、0x0FFF割れば、PICのAN9ピンに印加されている電圧値が計算できます。ファームウェアはadcGP802_3.zipです。タイマー3で25msecごとにPICのAN9ピンの電圧を読んでいます。バッファの1つが32ワードなので、バッファの1つ分の電圧を読むのに、25 × 36 = 0.9 sec掛かります。バッファーは2つなので、合計1.8秒掛かります。


UART2

ファームウェアはuart2GP802.zipです。使用方法は以下の通りです。

1.UART2でシリアル入出力がきちんとできていることを調べるために、既存のプロジェクトの利用方法(MPLABX)の章で紹介した「USB シリアル変換器」回路(PIC16F1455の章で紹介した回路が元)を使いました。念のため、回路を以下に再録します。以下、この回路を単に「USB シリアル変換器」と呼ぶことにします。

上記、「USB シリアル変換器」の左側に、4ピンのピンヘッドがありますが、上から1,2,3,4番ピンと呼ぶことにします。「PIC回路」の右下にも4ピンのピンヘッドがあります(このページの一番上に載せた回路図ではJP2です)。これも、上から1,2,3,4番ピンと呼ぶことにします。両ピンヘッドの1,2,4番ピンどうしを、それぞれ接続します。3番ピンはどこにも配線されていませんので、接続する必要はありません。下図を参照してください。

2.uart2GP802フォルダー中のcdc_installerフォルダーのなかに、CDCのインストーラ「USBDriverInstaller.exe」がありますので、これを実行してCDC用のデバイストライバーをインストールします。

3.「USB シリアル変換器」とPCをUSBケーブルで接続します。

4.「PIC回路」にファームウェアuart2GP802.zipを書き込み、実行します。PIC基板がCDC機器になります。

5.PC上でTera Termを起動して、メニューから”設定->シリアルポート”を選択すると、シリアルポート設定画面が以下の様に現れるので、ボーレートを57600 bps、データビットを8ビット、 パリティはなし, ストップビットを1、フロー・コントロールはなし、と設定してください。 設定が終わったら、シリアルポート設定画面を閉じ、メニューから”設定->設定の保存”を選択して、シリアルポート設定内容をファイルに保存しておくと、次回の接続時には、自動的に保存した設定内容が反映されます。

6.PCのキーボードから適当なキーを押下すると、押したキーに対する文字を含む文が、下図のように、Tera Termの画面に現れるはずです。たとえば、”a”なるキーを押下すると、”という文がTera Termの画面に現れるはずです。polling modeと出力されるのは、UART通信(受信)がポーリングで行われていることを示すためです。

なお、ファイル uart2.h の最終行にあるコメント文 //#define UART_INTERRUPT //comment out if interrupt mode is preferredのコメントを外すと、UART通信(受信)が割り込みで行われます。コメントを外したファームウェアを実行すると、下図のようにinterrupt modeと出力されます。


12ビットADC(UART2出力あり、DMAなし)

  上記12ビットADC(DMAなし)のファームウェア adcGP802_2.zip において、変数adcBuffersystem_init.cの中)の値(AD変換された値)をUART2で出力させるようにしたものです。timer3で設定した時間(約400 msec)ごとに値が出力されているように思います。ファームウェアはadcGP802_4.zipです。


12ビットADC(UART2出力あり、DMAあり)

  上記12ビットADC(DMAあり)のファームウェア adcGP802_3.zip において、DMAピンポン・バッファの中身(ファイルsystem_init.cのなかで定義されているBufferA[32]BufferB[32])をUART2で出力させるようにしたものです。timer3割り込みを約25 msecごとに掛けているので(これで1ワードのAD変換データが1個得られる)、32ワードのデータを取得するのに25×32=0.9 秒かかります。UART出力には十分な時間です。ファームウェアはadcGP802_5.zipです。

上図で、mVの後のAは、BufferA[32]の中身であることを示しています。


オーディオ DAC

  dsPIC33FJ128GP802はオーディオ帯域のデジタル・アナログ変換器(DAC)を持っています。この変換器の入出力関係を調べるのに使用したファームウェアがdacGP802_1.zipです。main.cの中のmain(void)関数の中の変数をDAC1RDAT = 0x8000;(Singed Fracsion Q15:dsp.hにQ15というマクロ関数が定義されているので使ってみると良いと思います)とすると、PICのDAC1RPピン(23番ピン)の電圧は約1.05Vとなり、DAC1RDAT = 0x7ff0;とすると、約2.16Vとなります。これらの電圧は個々のPICに依存するかも知れません。一方、DAC1RNピン(24番ピン)にはDAC1RPピン(23番ピン)と逆の電圧が出ます。 DAC1RDATに0x8000(10進数で-1)から0x7ff0(10進数で+0.999)までの間の数値を入力して、DAC1RPピン(23番ピン)DAC1RNピン(24番ピン)から出力される電圧を測定すると良いと思います。

  なお、固定小数点Q15(fractional)と10進数(float)の変換は、dsp.hに定義されている関数 Q15()、Float2Fract()、Fract2Float() で実行できます。

  ところで、dsp.hに定義されているPIの値が間違っていますので直しましょう。ただ、直さなくても、Long Doubleの精度では問題はありません。


オーディオ ADC/DAC ループバック

  AN9ピン(26番ピン)にオーディオ信号を入れ、それをPIC内蔵AD変換器でデジタル数値に変換した後、PIC内蔵のオーディオDACでオーディオ信号に戻して、DAC1RPピン(23番ピン)とDAC1RNピン(24番ピン)に出力させます。ファームウェアはdacGP802_2.zipです。

  まず、AN9ピン(26番ピン)に接続されている可変抵抗器を回すと、それにつれ、DAC1RPピン(23番ピン)やDAC1RNピン(24番ピン)の出力電圧が変わりますので、これを確認します。

  次に、可変抵抗器をほぼ真中の位置にし(バイアス電圧を3.3/2 Vにする)、直流カット用のコンデンサを介して、AN9ピン(26番ピン)にオーディオ信号(PC等からの音楽信号)を入力するようにします。そして、ヘッドホーンの右か左の入力端子をDAC1RPピン(23番ピン)に直流カット用のコンデンサを介して接続し、そしてヘッドホーンのアース端子をDAC1RNピン(24番ピン)に接続します。 DAC1RNピン(24番ピン)は、PIC回路のGNDには接続しないようにします。以下の図を参照ください。これでオーディオ信号を聞くことができます。気になるような雑音もなく音質も良好です。なお、ICD3などの書き込み器は雑音のもとになるので、ファームウェアを書き終わったら外しましょう。

ところで、音楽信号が小さい場合、以下の写真のように「2石マイクアンプキット(プリアンプキット)」(秋月電子通商)などを追加することを考えます。 また、実用的には、DAC1RPピン(23番ピン)とDAC1RNピン(24番ピン)は差動出力なので、これらを差動増幅器をつなぎ、その出力にヘッドホーンをつなぐと良いかもしれません(実証してはいません)。

  このファームウェアはMicrochip社の、dsPIC33FJ128GP802にあるCode Examples:CE154 - ADC to DAC Loopbackを参照して作成しました。


FFT(シミュレーション)

  fft_sim1.zipは、高速フーリエ変換(FFT:Fast Fourier Transform)のシミュレーション用ファームウェアです。仮想入力信号として1 kHzの正弦波(サンプリング・レート:8 kHz)を用いています。以下の図のように、main.cの79行目にブレーク・ポイントを設定して、デバッグ・モードでファームウェアをシミュレータ実行します。PIC回路は必要ありません。なお、シミュレータ実行に関しては、注意の節を参照してください。


1.FFTの結果のグラフ化

  上図で矢印で示した変数powerSpecにFFTの結果が入っています。これをグラフ化するために、Michrochip社が提供しているdsPICworksを用います。これをインストールしておきます。

まず、変数powerSpecの中身をファイルに書き出します。以下の図のように、MPLAB XのメニューでWindow -> Debugging -> Variablesを選択します。

下方にVariablesウインドウが、次の図のように現れます。

変数powerSpecの箇所を右クリックして、以下の図のようにHexadecimal Formatを選択します。変数を格納するファイル名の入力を求められるので、適当な名前を付けて保存します。

保存したファイルはCVS形式のもので、エクセルやテキスト・エディッタ(たとえば、秀丸エディタ)で見ることができます。エクセルを使えれば、ファイルを開いてB列の数値をコピーして、下図のように、テキスト・エディッタに貼り付けます。エクセルが使えなければ、テキスト・エディッタ上で編集して、2列目のデータだけを残します。

このファイルを.mchなるファイル拡張子を付けて保存します。

つぎに、dsPICworksを実行し、メニューからFile->Import File ... を選択します。 すると、下図のようなImport Fileウィンドウが現れます。

Sorce Fileと書かれた箇所の右側にあるボタン(Click to Select File Name)を押して、先ほど保存した拡張子.mchのファイルを指定します。さらに、下図のように、「Import File TypeをFrequency Domain File」、「Sampling Rateを8000」、「Import File FormatをFluctional / Integer ASCII Hexadecimal」、「FFT Frame Sizeを32」に設定して、OKボタンを押します。

すると、次のように、FFTの結果である変数powerSpecがグラフ化されます。

1 kHzの周波数成分が多いことが分かります。


2.ハミング窓関数(hamming window function)の使用

  ファームウェアの57行と60行目のコメントを、以下のように外します。

79行目にブレーク・ポイントを設定して、デバッグ・モードでファームウェアをシミュレータ実行した後、変数powerSpecの内容をdsPICworksでグラフ化します。

ハミング窓関数以外の窓関数も有りますので、dsp.hを見てください。


3.仮想正弦波入力信号の作成方法

  信号周波数(Signal Frequency)を 1 kHz、サンプリング・レート(Sampling Rate)を 8 kHz、サンプル数(Number of Samples)を64として仮想正弦波入力信号を作成します。サンプル数は2のN乗(2の整数乗)でなければいけません。今の場合 N = 6です。

dsPICworksを実行します。下図のように、メニューからGenerator->Sinusoidalを選択します。

Generating Sinusoidal Wave なるウィンドウが現れるので、以下の図のように設定します。

上図で、Click to Select File Nameと書かれたボタン(前に保存したファイル名が書かれているかも知れません)を押して、保存ファイル名と保存場所を指定します。そして、OKボタンを押すと、正弦波波形が表示され、指定した保存ファイルには正弦波データが格納されます。保存ファイルをエディタ・ソフトで開くと、データを見ることができます。このデータを配列データになるよう編集して、ファームウェア(main.c)の中の変数fractional square1k[FFT_SIZE]の中身として貼り付けます。配列データ化するのに、コンソール・アプリケーションdsPICworks_out1.zipが参考になるかも知れません。このアプリケーションはC++(Visual Studio 2017 community)で作成しました。

仮想正弦波入力信号の作成方法については以上です。

  ところで、仮想正弦波入力信号の周波数が1000 Hzの場合、サンプリング・レートが8000 Hzとして64点サンプリングすると、丁度8周期分の正弦波信号となります。これでは、窓関数の威力が分かりません。そこで、仮想正弦波入力信号の周波数を1032 Hzにして、信号が時間軸の最後で急激に途切れさせて(高周波成分が入ってくることが予想されます)、FFTの結果を見てみます。まず、窓関数がない場合です。

次に、ハミング窓関数を適用した場合は

となります。ハミング窓関数を用いることにより、信号が時間軸の最後で急激に途切れる悪影響が回避されています。



4.回転因子の計算

  ファームウェアの54行目のTwidFactorInit関数で計算できます。

上図のように、53行目と54行目のコメントを外し、64行目にブレークポイントを設定して、ファームウェアをデバッグ・モードでシュミレーション実行します。Variablesウィンドウに表示される変数twiddleFactors1の中身をCVSファイルに書き出せば(書き出し方法はすでに説明しています)、回転因子が得られます。ファームウェアでは、この回転因子をtwiddleFactors[FFT_SIZE/2]の中身として貼り付けて、それをPSV(プログラムメモリー)領域(X-memory領域)に置いています。X-memory領域に置かないとdsp計算が遅くなります。

なお、TwidFactorInit(LOG2N, &twiddleFactors[0], 0)の第1引数のLOG2Nは、サンプル数(2のN乗)のNの値「log_2 (2^N)= N」で、今の場合 6。第2引数は、 固定小数点fluctional型のtwiddleFactors[32]の先頭アドレス(配列要素はサンプル数64の半分)、最後の引数はFFTか逆FFTかを決める数値で、 0 はFFT、1は逆FFTです。


BPF(シミュレーション)

  bpf_sim2.zipは、Remez法によるFIR型バンドパス・フィルター(BPF:Band-pass filter)のシュミレーション用ファームウェアです。仮想入力信号として1 kHzの矩形波(サンプリング・レート:8 kHz)を用いています。以下の図のように、main.cの108行目にブレーク・ポイントを設定して、デバッグ・モードでファームウェアをシミュレータ実行します。PIC回路は必要ありません。

フィルターの出力は、変数FilterOutに入っていますので、1.FFTの結果のグラフ化で書いたと同じようにしてdsPICworksでグラフ化します。ただし、Import Fileウィンドウの設定からが少し違います。グラフの横軸がFFTでは周波数でしたが、BPFでは時間になるためです。具体的には、以下の図の設定します。 サンプリング・レートは8 kHz(8000 Hz)です。

OKボタンを押すと、次のように、BPFの結果である変数FilterOutがグラフ化されます。

矩形波がBPFによって正弦波になったことが分かります。仮想入力信号である矩形波のグラフは、この節の最後の図を見てください。



1.BPFの係数の求め方

  フィルター係数は、DIGITALFILTER.COM社のフリーソフトウェア DSPLinks Web Editionを使用して求めました。同社のチュートリアル(デジタルフィルタ研究室)も充実しており、それにしたがって、Remez法におけるバンドパス・フィルター係数を求めます。バンドパス・フィルターの中心周波数は1 kHzとしました。サンプリング・レートは8 kHzです。

DSPLinks Web Editionを実行します。下図のように、メニューの下にあるアイコンから、トランジスタが描かれたものを選択します。

そして、Untitled1と書かれたウィンドウ(グリッドを持つウィンドウ)の適当な所で、左クリックすると、下図のように、Parts Selectウィンドウが現れるので、RMZBPFを選択し、OKボタンを押します。

すると、ウィンドウに次のようなRMZBPF部品が現れます。

この部品をダブルクリックすると、Parts Attributeウィンドウ

が現れるので、Change Parametersボタンを押します。FIR type BPFウィンドウが現れるので、下図のように設定します。繰り返しますが、サンプリング・レートは8 kHz(8000 Hz)です。

Tap Count N(フィルターのタップ数)は設定する必要がありません。他の項目を設定した後、Tap Count Estimationボタンを押すと、Tap Count Nの項目が設定されます。設定されたタップ数を記憶しておきます。設定が終了したら、一番下にあるQuantize Coefficientsボタン(フィルター係数の数値化)を押します。すると、フィルター係数を書き出す際の、データのフォーマットを聞いてきますので、適当に設定します。

今回は、フィルター係数を16進数(Hex)で書き出すことにしました。以上の3つのウィンドウにてすべてOKボタンを押してウィンドウを閉じ、RMZBPF部品だけがUntitled1ウィンドウにあるだけの状態にします。



こんどは、RMZBPF部品の所を右クリックします。現れたサブメニューでOpen a Monitor(M)を選択します。

すると、設計したバンドパス・フィルターの周波数特性と位相特性のグラフが現れます。

ここで、DSPLinks Web Editionのメニューから以下のように、Tools->Save Coefficientsを選択します。ファイル名やファイルを保存する場所を聞かれますので適当に設定します。

保存したファイルをテキスト・エディッタ(例えば秀丸エディッタ)で開くと、データ(フィルター係数)を見ることができます。このデータを配列データになるよう編集して、ファームウェア(main.c)の変数bpfCoeffs[NUM_TAPS]の中身として貼り付けます。配列データ化するのに、コンソール・アプリケーションDSPLinks_out.zipが参考になるかも知れません。このアプリケーションはC++(Visual Studio 2017 community)で作成しました。



2.仮想矩形波入力信号の作成方法

  FFT(シミュレーション)3.仮想正弦波入力信号の作成方法で書いたと同じようにしてdsPICworksで作成します。dsPICworksを実行します。下図のように、メニューからGenerator->Square ...を選択します。

Generating Square Wave なるウィンドウが現れるので、以下の図のように設定します。周波数は1 kHzで、サンプリング・レートは8 kHzです。Number of Samplesは、以前に算出したタップの数Tap Count Nの196と同じにしています。

上図で、Click to Select File Nameと書かれたボタン(前に保存したファイル名output.timが書かれているかも知れません)を押して、保存ファイル名と保存場所を指定します。そして、OKボタンを押すと、

のように、矩形波波形が表示され、指定した保存ファイルには矩形波データが格納されます。保存ファイルをエディタ・ソフトで開くと、データを見ることができます。このデータを配列データになるよう編集して、ファームウェア(main.c)の中の変数square1k[FFT_SIZE]の中身として貼り付けます。



3.入力データ数について

  ファームウェアbpf_sim2.zipでは、フィルターに入力するデータ数をフィルターのタップ数と同じとしました。つまり、N個(196個)のデータをサンプリングして、それをフィルターにかけ、フィルタリングされたデータを出力しています。

ただ、このようにすると、N個のデータをサンプリングするのに時間がかかり、入・出力で時間的に遅滞が発生します。この時間的遅滞を最小限に抑えるにはN=1とします。ところが、フィルター演算にはタップ数分だけのデータが必要で、入力データが1個(N=1)では演算ができません。そこで、入力データの時点から、時間的に遡って、過去にサンプリングしたN-1個のデータをPIC内部に記憶させておき、入力データと合わせて合計N個のデータでフィルター演算を行います。その演算結果は1つですが、これがフィルタリングされた出力です。

結局、N=1とすると、1つデータが入力されると、1つのデータが出力されるフィルターとなります。

過去にサンプリングしたN-1個のデータは、ファームウェアbpf_sim2.zipの中のmain関数の85行目の配列delay[NUM_TAPS] (リングバッファになっています)に保存されて行きます。すこしだけ、この動作を確認してみましょう。下図のように、ファームウェアの101から103行目のコメントをはずし、106行目をコメント文にします。


103行目にブレーク・ポイントを設定して、デバッグ・モードでファームウェアをシミュレータ実行します。PIC回路は必要ありません。 ブレーク・ポイントで停止したら、変数FilterOut[0]配列delay[NUM_TAPS]の中身をVariablesウインドウで確認します。Variablesウインドウに変数が現れていなければ、追加してください。以上の2つの変数がすべてゼロになっていると思います。


もう一度ファームウェアをシミュレータ実行します。ブレーク・ポイントで停止した時の変数FilterOut[0]配列delay[NUM_TAPS]の中身は以下のようになります。

入力信号である変数square1k[0]の値が変数delay[0]に記憶され、フィルター演算の結果が変数FilterOut[0]の中に格納されています。いまの場合、過去のN-1個のデータはゼロです。1回目のブレーク・ポイントで停止したときに、配列delay[NUM_TAPS]の中身がゼロでした。これは、そのように初期化しているためです。過去にサンプリングされたN-1個の入力信号はないので、それらをすべてゼロとしている訳です。


さらに、もう一度ファームウェアをシミュレータ実行します。ブレーク・ポイントで停止した時の変数FilterOut[0]配列delay[NUM_TAPS]の中身は、以下のようになります。

入力信号である変数square1k[1]の値が変数delay[195]に記憶され、フィルター演算の結果が変数FilterOut[0]の中に格納されています。

以上にように、入力信号は変数delay[195]に順次記憶されて行きます。また、フィルター演算の結果が、ただ1つの変数FilterOut[0]に、0x000D、0xFFC9....のように順次出力されて行きます。

この様に、変数FilterOut[0](変数は、あくまで1つだけです)に順次出力される値は、N個(196個)のデータをサンプリングして、それを一括してフィルターにかけ、フィルタリング出力させたデータ(配列変数FilterOut[NUM_TAPS]に格納される値)と一致していることが分かります。

結論:時間的遅滞を最小限に抑えるには関数FIR(1, &FilterOut[0], &square1k[i], &BPF)の第1引数を1(N=1の意)とし、第2引数に出力用のfractional変数(1個)のアドレス、第3引数に入力用のfractional変数(1個)のアドレス、第4変数にFIRStruct変数のアドレスを設定します。


FFT(PIC回路での動作確認)

  PIC回路でオーディオ信号のFFTをとり、その結果をUSB(CDC:UART2の節を参照)でPC(パーソナル・コンピュータ)に送り、PCでグラフ化することを考えます。ファームウェアはfft_uart.zipです。また、PC用のアプリケーション・ソフトウェアはFFTapp.zipです。このソフトウェアはC#(Visual Studio 2017 community)で作成しました。COMポート番号は自動的に設定されます。

以下、CDCドライバーをPCにインストールしてあることを前提とします。

オーディオ ADC/DAC ループバックの節と同じように、AN9ピン(26番ピン)に接続されている可変抵抗器をほぼ真中の位置にし(バイアス電圧を3.3/2 Vにする)、直流カット用のコンデンサを介して、AN9ピン(26番ピン)にオーディオ信号を入力するようにします。オーディオ信号源としてはPCのオーディオ出力(例えばフリーソフトウェアの「萬屋」による正弦波、矩形波出力やMedia Playerの音楽出力など)を利用すると良いでしょう。なお、以前にも書きましたが、PCからの出力のパワーが不足する場合は、「2石マイクアンプキット(プリアンプキット)」(秋月電子通商)などを追加することを考えます。

  以下は、PC用のソフトウェアを実行した例です。まずは、「萬屋」を用いて、1 kHzの矩形波をPIC回路に入力したときの図です。1 kHzの矩形波が3 kHz成分を持っていることが分かります。

次の図は、Media Playerによる音楽出力信号のFFTです。

  今回作成したPIC回路用のファームウェアでは、サンプリング周波数を8 KHzで、サンプリング数を64としています。したがって、周波数分解能は125 Hzです。分解能をあげれば、もう少しなめらかな図になると思います。

PCから"s"(startの意)なる命令をPIC回路に送ると、PIC回路は64点のサンプリングを行い、それにFFTをかけた結果をPCに返します。PCでは、この結果を上図の様にグラフ化した後、すぐにまた、"s"(startの意)なる命令をPIC回路に送ります。これの繰り返しです。 このようにすると、最も速く、かつ確実にデータ転送を行うことができます。ただ、今回はUARTのボーレートを57600bpsにしています。もっと高速にデータ転送を行いたい場合は、ボーレートを高く設定すると良いと思います。

  ここでは、FFTの結果をPC画面に表示させました。しかし、液晶ディスプレイーやTFT液晶モジュールを購入して、そこにFFTの結果を表示させることもできるはずです。興味があればご検討ください。


BPF(PIC回路での動作確認)

  オーディオ ADC/DAC ループバックの章のファームウェア(dacGP802_1.zip)を元に、2 kHzから4 kHzまでの帯域のバンドパス・フィルタを付け加えました。出来上がったファームウェアはdac_bpf1.zipです。サンプリング周波数は104,167 Hzです。例えば、入力に2 kHzから4 kHzまでの周波数を持つ矩形波を入力すると、同じ周波数の正弦波が出力されます。また、入力に2 kHz以下、または4 kHz以上の周波数の正弦波入れると出力が小さくなります。バンドパス・フィルタが機能していることが分かります。なお、以前にも書きましたが、PCからの出力のパワーが不足する場合は、「2石マイクアンプキット(プリアンプキット)」(秋月電子通商)などを追加することを考えます。

  以上dsPICのファームウェアを開発するに当たり、DIGITALFILTER.COM社のホームページのファームウェアダウンロードが大変参考になりました。コピー・ペーストをした部分もかなりあると思います。お礼いたします。


戻る