2016年2月11日木曜日

オーディオ用DACを使ったファンクションジェネレータ ファームウェアを改良

PSoCだけではなくてmbedでもやってみようと思って調べてみたが、I2Sのライブラリがいまいちで、DMAが簡単には使えないようだ。

手持ちのNUCLEO-F401REはCortex-M4なのでもう少し調べてみたいところですが。


というわけで、引き続きPSoC 5LPで。

Github:
https://github.com/ryood/I2S_FG/tree/master/PSoC/I2S_FG


波形の振幅を小さくする。

PCM5102aの電源電圧が3.3Vだとフルスケール出ないようなので、波形テーブルの値を0.9倍にしてみた。

フルスケール

0.9倍

振幅が小さくなって波形の頭打ちがなくなった。

波形テーブルをリッチにする。

間に合わせで、16bit/1024個のテーブルにしていたのを32bit/32768個に拡張した。32bit×32768/8bit=131,072Byteのテーブルになる。PSoC 5LPはFlashメモリが256kBあるのでまだ余裕がある。32bit版も振幅は0.9倍している。

10kHz 16bit/1024

10kHz 32bit/32768

20kHz 16bit/1024

20kHz 32bit/32768

50kHz 16bit/1024

50kHz 32bit/32768

100kHz 16bit/1024

100kHz 32bit/32768

192kHz 16bit/1024

192kHz 32bit/32768

理屈で言うと32bit/32768の方がサンプリングポイントがなめらかになるはずだがオシロで波形を見た限りではよくわからない。

100kHzで32bitの方が悪化して見えるのは、ちゃんと波形が出力されていないのが原因のようだ。メモリ転送が間に合っていないのかも。

2ch出力をやめて1ch出力にしてみる。

CPUの処理を短縮するために、32bit/32768のままI2Sコンポーネントの設定を変更してLchのみ出力するようにしてみた。また、PCM5102aからの出力にかけている470Ω/2200pFのLPFの手前での波形も見てみた。

100kHz

ch1:LPF通過後 ch2:LPF通過前

1ch出力にしたら100kHzの波形(ch1)は綺麗になった。LPFを通す前を見ると高い周波数では相当ガタガタなので1次LPFを通すだけでもかなり波形は綺麗になっている方だろう。

プログラムで振幅を絞る。

POTによるレベル調整ではなくプログラムで出力振幅を絞る実験もしてみた。出力値(整数)をシフト演算したもの。

シフト0 (1倍)

ch1:LPF通過後 ch2:LPF通過前

(1)Vk(RMS):1.889V

シフト1 (1/2倍)

(1)Vk(RMS):954.4mV
1.889V / 2 = 944.5mV

シフト2 (1/4倍)

(1)Vk(RMS):483.0mV
1.889V / 4 = 472.25mV

シフト3 (1/8倍)

(1)Vk(RMS):250.8mV
1.889V / 8 = 236.125mV

シフト4 (1/16倍)

(1)Vk(RMS):142.5mV
1.889V / 16 ≒ 118mV

だいたい想定通りに振幅が小さくなっている。振幅が小さくなると誤差が出ているのはノイズの影響かな。

拡大

周期性がありそうなのでクロックノイズかな?300mV~500mV(p-p)ぐらいなので結構でかい。

メモ:

オシロのFFT機能を使って高調波歪を見てみる。

テーブルの要素数は増やせば良くなるかと思ってたが、どうだかわからない。出力周波数とサンプリングレートの比率でジッターになる?

1次LPFを通す前の波形も出力できるようにして、外付けで高次のActive LPF(+レベル調整)を入れられるようにする?