STM8S-Discovery (5)

「STM8SDP」のバグふたつの修正および機能追加をした 3 月 5 日付けの新しい版で古い版を置き換え、(→こちら) に置きました。
一つ目のバグは、LRCK の各エッジで起動される割り込みサービスルーチン内での L/R 判定ロジックが反転していたために、出力の左右が逆転し、さらに、左と右で1サンプル時間だけずれて再生されるというものです。
LRCK はデューティーが完全に 50 % であることが要求されるので、サンプリング周波数の倍の周波数、たとえば 44.1 kHz なら 88.2 kHz をタイマで発生し、LRCK 信号自体は、PWM 出力のトグル機能を使って「2分周」してデューティー 50 % の 44.1 kHz を得ています。
この L/R のトラッキングには変数を使わず、割り込みルーチン内で LRCK 信号の値そのものをポートから読み込んで L か R かの判定をしているのですが、この判定のロジックが逆だったため、R 信号のタイミングで行わなければならない処理を L 信号のタイミングで実行していたのです。
サンプル時間のずれは、左と右の位相ずれとなって現れ、高音になるほど影響が大きくなります。
二つ目のバグは、サンプリング周波数を発生しているタイマに設定する定数を、「定数式」として書いて、プログラムの実行時ではなくコンパイル時にコンパイラに計算させているのですが、四捨五入のつもりで書いた部分がうまく機能していなくて、切捨てになっていたというものです。
丸めがうまくいっていないため、サンプリング周波数の誤差が最適値より大きくなる状態でした。
機能の追加としては、PG1 (コネクタ CN2-12 番ピン) に接続したスイッチの状態をプログラム起動時に読み込んで、コンパイル時に指定しておいた2つのサンプリング周波数のどちらかを選択するようにしました。
回路図を下に示します。 スイッチ部分が追加されただけです。

サポートしている CPU クロック周波数とサンプリング周波数の組み合わせでの周波数誤差の表を次に示します。

CPU クロック
(MHz)
サンプリング
周波数(kHz)
実際の fs
(kHz)
誤差
(%)
  16.0000    22.050    22.039    -0.05  
  32.000    32.000     0  
  44.100    44.199    +0.22  
  48.000    47.904    -0.20  
  16.3840    22.050    22.022    -0.13  
  32.000    32.000     0  
  44.100    44.043    -0.13  
  48.000    47.906    -0.19  
  16.9344    22.050    22.050     0  
  32.000    31.952    -0.15  
  44.100    44.100     0  
  48.000    48.109    +0.23  
  18.4320    22.050    22.048    -0.01  
  32.000    32.000     0  
  44.100    44.096    -0.01  
  48.000    48.000     0  
もちろん、CPU クロック周波数を変えるには、基板に実装されている 16 MHz の水晶振動子を取り外し、目的の周波数の水晶振動子に付け替える必要があります。
16.9344 MHz の周波数は一般的ではありませんが、44.1 kHz サンプリングの場合には「定番」と言える周波数で、fs = 44.1 kHz に対し 384 fs = 2 * 192 fs = 16.9344 MHz となっています。
この周波数およびその2倍の 33.8688 MHz は CDROM ドライブや CD プレーヤでよく使われており、実際に古い CDROM ドライブを分解して基板から取り外した 16.9344 MHz のクリスタルを使って実験しました。
何台かを分解しましたが、セラミック振動子を使っているものが多く、16.9344 MHz のクリスタルを使っているのは1台だけでした。
一般的な周波数ではなく、どの販売店でも手に入るわけではありませんが、たとえばサトー電気ならHC49US タイプのクリスタルを単価 126 円で購入できます。
16.9344 MHz は 44.1 / 22.05 kHz に対しては誤差ゼロですが、32 / 48 kHz に対しては、少し誤差が大きくなります。
クリスタルを換装するなら、約 15 % のオーバークロックになりますが、全てのサンプリング周波数で誤差が小さくなる 18.432 MHz をおすすめします。
もともとボーレート・クロック発生に適した周波数なので、230.4 kbps までの UART ボーレート・クロックでは誤差ゼロになります。 一方、MIDI の 31.25 kbps に対しては、 -0.4 % ほどの誤差になります。