R8C SDカードを使ったWAVファイルの再生

以前にSDカードをSPI接続で読み書きするテストを行ったが、パフォーマンスの評価
を行うのに、WAV形式の音楽を再生するのが丁度良いと思い実験してみた。

事前の懸念事項として:
・SDカードを読み書きするSPIポートは、完全なソフトウェアー仕様なので、あまり
速度が出ない。
※UARTと共有になっている同期式シリアル変換を使えば、速度は改善するものと思う
が、シリアル通信が使えなくなる為、今回は見送った。
・パラレル⇔シリアル変換では、C++ コンパイラの最適化度合いが非常に大きなファクタ
ーを占める。

以上の点を考慮して、コンパイルされたアセンブリコードを眺めながら、ソースコードに
修正を加えたりしながら、色々実験した。

8ビット、ステレオで、11.025KHz(44.1KHzの 1/4)くらいならギリギリ再生できる事が
判った。
これには、11.025KHz でサンプリングループを回す割り込みや、PWM で変換する為の処理
も含まれる。

再生させてみると、多少ノイズが乗る、PWM レジスターの書き換えは割り込みを使って行
っているものの、何かノイズが乗る要因があるものと思われるが、原因を究明できなかっ
たので、とりあえず、この状態で公開する。

タイマーCのPWMはB、Cチャネルを使っている。
それぞれ、ポートP12、P13から出力される。
これを、単純なRCフィルター(C:0.1uF、R:2200)に通している。
ライン出力のGNDは、VCCとGNDの中点(470オームで分圧)にしている。

IMG_0758

現在の実装では、「OHAYODEL.WAV」ファイルを再生するようになっている。
※再生するWAVファイルは、8ビット、ステレオ、11.025KHzにしておく必要がある。
※フォーマットが違う場合、エラーを出力する。
※再生開始時や終了時などにポップノイズが発生する場合があるので、ボリュームに注意する事。

SD_WAV_play

R8CタイマーJを使った周波数測定

前回からだいぶ間が空きましたが、パルス入力を使った、周波数測定を行ってみました。

タイマーJは、パルス出力と入力の機能があり、パルス幅測定、周期測定、パルスカウント
など沢山の機能があります。
今回は、周期測定機能を使って、周波数測定をしてみました。

サンプルなので、プログラムをあまり複雑にしない為、「単機能」で実装してありますが、
実用的な物にするには、カウンターがオーバーフローした場合にマスタークロックを切り
替えるとか、周波数が高い場合に、単位時間辺りのパルス数計測に切り替えるなどの工夫
を行う必要があると思います。

サンプルでは、シリアル接続したターミナルに、計測した結果を1秒毎に表示します。

ルネサス系では、タイマーJの構成で、良く出来ていると思うのは、割り込みを使わなく
ても、レジスターの状態が保持される為、簡単に厳密な計測が行えます。
このような、細かい点に配慮したハードウェアーの構成は、日本メーカーのマイコンな
らではと思います。

IMG_0757s

基本的な機能実装は、「common/trj_io.hpp」に集約させていますが、設定が複雑なので、
場合によっては、「trj_io」クラスの機能だけでは不足している場合もあると思います。

又、割り込みを使う場合は、パルス出力と入力で、登録する割り込み関数が違うので、
注意が必要です。

//-----------------------------------------------------------------//
/*!
    @brief  パルス計測の開始(TRJIO 端子から、パルスを入力)@n
            ※VCOUT1 端子から入力する場合は、TRJIOSEL を設定する。
    @param[in]  measur    パルス計測のモード
    @param[in]  s         クロック選択(measur::countの場合は無効)
    @param[in]  ir_lvl    割り込みレベル(0の場合割り込みを使用しない)
*/
//-----------------------------------------------------------------//
void pluse_inp(measurement measur, source s, uint8_t ir_lvl = 0) const;

「measurement」型として、

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
    @brief  パルス計測モード
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class measurement : uint8_t {
    low_width,     ///< Low レベル幅測定
    high_width,    ///< High レベル幅測定
    count,         ///< パルス数測定
    freq,          ///< 周期測定
};

4つの測定モードがあります。

クロック選択では、

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
    @brief  カウンターソース
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class source : uint8_t {
    f1 = 0,     ///< F_CLK
    f2 = 3,     ///< F_CLK / 2
    f8 = 1,     ///< F_CLK / 8
    fHOCO = 2   ///< fHOCO(高速オンチップオシレーター)
};

4つの中から選択が出来ます。

詳しい使い方は、「PLUSE_INP_test」を参照して下さい。