今回はPDM方式のデジタルマイクの音声信号をSTM32L4マイコンのDFSDMという周辺機能を使用して読み取る方法を紹介します。

デジタルマイクとは、従来のアナログ電圧を出力するアナログマイクの出力段にΣΔ方式のAD変換器を内蔵し、それをPDM(Pulse Density Modulation:パルス密度変調)方式でデジタル信号として出力するマイクです。
チップ内部にADCを内蔵することで伝送線上にノイズが入りにくくなるため、容易に高分解能な音声信号を得ることができます。
今回の検討では、100Hzの可聴音領域から80kHzの超音波領域まで読み取ることができる Knowles社のSPH0641LU4H-1が搭載されているブレイクアウトボードと、STM32L476RGマイコンが載っているNUCLEO-L476RGを使用しました。

このデジタルマイクの信号をSTM32L4マイコンのDFSDM (Digital Filter for Sigma-Delta modulators interface)を使って読み取ります。
DFSDMは、ΔΣ変調のデジタル信号をハードウェアで復調しADCのように読み取ることができるようにする周辺機能です。
具体的には、多段化されたSincフィルタ(CICフィルタ)と積分器が入っており、パラメータを変更することでデジタルマイクに与えるクロック周波数、復調信号の周波数と分解能を調整することができます。

ダウンロード

STM32CubeMXのデータやソースコード、マイコンのピンアサインなどはこちらのGitHubページに上げました。

DFSDMの設定方法

ここからはDFSDMの設定方法について説明します。

まず、使用するデジタルマイクSPH0641LU4H-1のデータシートからデジタル信号のクロック周波数を確認します。


データシートより、超音波モードのときの最大クロック周波数は4.8MHzです。

次に、DFSDMの出力クロック設定を行います。

クロック設定の項目より、DFSDM1には80MHzのクロックが供給されます。

これをデジタルマイクの最大クロック周波数4.8MHz以下に収まるよう分周します。

ここでは17で分周することで、80MHz÷17≒4.7MHzのクロックが供給されます。

次にDFSDMのフィルタ設定を行います。

まず、前段フィルタであるSincフィルタの次数を3、Sincフィルタのオーバーサンプリング比(デシメーション比)を32、後段フィルタの積分器の積分回数を1に設定します。
したがって、このフィルタを通して得られる信号の周波数は4.7MHz÷32÷1≒147kHzとなります。
よって、最大帯域幅は147kHz÷2≒73.5kHzとなります。
また、デジタルマイクからの音声信号取得中に別の処理を行ったり、連続的に信号を取得したい場合はDMAモードをEnableにします。

なお、DFSDMに入っている多段化SincフィルタはCICフィルタ(Cascaded Integrator-Comb filter)とも呼ばれ、積分器・デシメータ・微分器で構成されたローパスフィルタです。演算回路の観点から言うと、乗算器が不要であるため演算に必要なハードウェアの規模が小さく抑えられ、FPGA等による実装に適しています。
参考:https://www.architek.ai/old/design/ex_cic1.html

次に、フィルタ後の出力設定を行います。


DFSDMの内部データレジスタ分解能は31ビット、出力データレジスタの分解能は24ビットですので、この24ビットに収まるように右ビットシフトを行います。 CICフィルタのビット幅は以下の計算式によって計算されます。

$$ B_{\mathrm{out}} = \lceil N \log_{2} (RM) + B_{\mathrm{in}} \rceil $$

ここで、\(B_{\mathrm{out}}\):出力ビット幅、\(B_{\mathrm{in}}\):入力ビット幅、\(N\):タップ数(フィルタ次数)、\(R\):デシメーション比、\(M\):微分器の遅延段数 です。
今回の設定値は\(B_{\mathrm{in}}=1\)、\(N=3\)、\(R=32\)、\(M=1\)ですので、\(B_{\text{out}}=16\)となります。24ビット以下に収まっているので右ビットシフトは不要ですが、今回の検討ではオフセット値を0、右ビットシフト値を2としました。
また、ゲイン\(G\)は以下の式で与えられます。

$$G=(RM)^N$$

したがって、今回の設定値だとゲインは32768となります。
参考:http://dspguru.com/files/cic.pdf

ピンアサイン

マイクとの接続は、以下のピンアサインの"DFSDM1_CKOUT"をデジタルマイク基板の"CLK"に、“DFSDM1_DATIN0"をデジタルマイク基板の"DATA"に、デジタルマイク基板の"SEL"はGNDに繋げます。

HALコード

DFSDMのDMAモードによる変換を行う際は、HAL_DFSDM_FilterRegularStart_DMA関数を用います。 第一引数にはDFSDMのハンドル、第二引数には音声信号が入るint32_t型のデータポインタ、第三引数にはデータ数を渡します。
変換が完了すると、HAL_DFSDM_FilterRegConvCpltCallback関数が呼ばれます。

デジタルマイクの周波数特性

デジタルマイク+DFSDMによって得られた音声信号について、FFTによる周波数解析を行いました。

まず、iPhoneアプリのトーンジェネレーターで10kHzの音声信号を与えたときの周波数特性を示します。


周波数特性を見る限り問題なく10kHzでピークが立っているのがわかります。

次に、超音波領域の音が拾えているのを確認するため、手元にあった超音波洗浄機TKS-210の動作音を計測してみました。


結果はこのようになりました。40kHz近辺でピークが立っており、超音波領域の音も問題なく取れることがわかりました。

今回のまとめ

本記事ではSTM32L4マイコンのDFSDM機能を使ったPDM方式のデジタルマイクの音声信号の取得方法を紹介しました。
次回はDFSDMを使わず、SPIとソフトウェアCICフィルタを使ってデジタルマイクの信号を取得する方法を紹介する予定です。