【MP3プレーヤの概要】
新たな挑戦としてMP3プレーヤを試作してみることにしました。
MP3のデコードをPIC自身に実行させたいところですが、ちょっとまだ性能が
追いつきませんので、MP3デコーダ専用のICを使っています。
使ったICは有名なVLSI社の「VS1011e」というMPEG AUDIO CODECです。
48ピンのLQFPパッケージでちょっと扱いにくいのですが、いろいろ実験できる
ようにMP3デコーダの部分だけをサブ基板として作っています。
今回の試作結果は、下記の写真のように基板ユニットのままです。
これでも250kサンプルのMP3も再生できますので、意外と良い音で聞くことが
できました。これは使えるという感じです。
SDカードもマイクロチップ社のFATファイルシステムを使うと、ファイルアクセス
のプログラム部分は何も作らなくて済むので意外と簡単にできました。
次はポケッタブルにするか、インターネットラジオでも作るかと期待できます。
サブ基板にVS1011eを実装
メイン基板のはんだ面側にSDカードを実装
操作部はスイッチが4個だけです。
【全体構成】
基本機能だけに絞りましたので、下図の構成のようにMP3のステレオ音声出力
以外には、SDカードと操作用のスイッチが4個あるだけです。
SDカードもSPIインターフェースですし、MP3もSPIインターフェースですので
PIC24Fの2チャネルあるSPIがうまく使えます。またピン割り付けを使うことで
ピン接続も片面基板でパターンがうまく通せるような配置としています。
【VS1011eの使い方】
今回使用したMP3コーデックICであるVS1011eは多くの製作例が紹介されています
ので情報はたくさんあります。
【VS1011eの内部構成】
このICの機能をブロック図で表すと、「New Mode」と呼ばれている通信モードの場合
には下図のように表されます。(VS1001からバージョンアップされたもの)
この場合の外部インターフェースのポイントは、SPI通信なのですが2種類のSPI通信
で行われるようになっていることです。
つまり、動作モードや音量、音質などの制御するための制御用インターフェースと
音楽データを送信するための音楽データ用インターフェースです。
ICは1個なのですが、内部はSPI通信で接続された2つのデバイスがあるようになって
います。
その2つのSPI通信をCSピンで区別して通信するようになっていて、制御側はXCSピン
データ側はXDCSピンで制御します。
SPI通信そのものは、標準的な3ピン(SO、SI、SCLK)で8ビットモードで行います。
これ以外にもう1ピンDREQという信号が用意されていて、制御の場合は、これが
BUSY信号となり、制御コマンド送信後コマンドを実行している間この信号がLowとなり
ますので、マイコン側は、このDREQ(BUSY)をチェックしてから次のコマンド送信をする
必要があります。
データの場合はこのピンがデータ要求ピン(DREQ)となり、音声データが受信できる
ことを示すためのタイミング用となっていて、このDREQが出力される都度、音楽データを
送れば良いようになっています。つまり、音楽に関するタイミングはすべてVS1011e側が
行いますので、マイコン側は何も考えなくても良いようになっています。
【制御用コマンド】
上記の制御用SPIインターフェースを使ってコマンドやステータスを送受しますが
そのときには下記のようなフォーマットで送受信します。
まず、最初のバイトで送信か受信かを指定します。次にVS1011e内の制御用レジスタの
アドレスを指定してから、それに書き込む2バイトのデータを送るか、データを受信します。
【制御用レジスタとアドレス】
上記のアドレスで指定するレジスタは下表のようになっています。この中で
今回使用したのは白抜きの4個だけです。
アドレス 略称 説明 実行時間 0x00 MODE モード制御 70 0x01 STATUS ステータス 40 0x02 BASS 低音高音強調 2100 0x03 CLOCKF クロックダブラ 80 0x04 DECODE_TIME デコード時間 40 0x05 AUDATA オーディオデータ 3200 0x06 WRAM RAM Read/Write 80 0x07 WRAMADDR RAMのベースアドレス 80 0x08 HDAT0 ストリームヘッダ0 -- 0x09 HDAT1 ストリームヘッダ1 -- 0x0A AIADR アプリプログラムの開始番地 3200 0x0B VOL 音量制御 2100 0x0C AICTRL0 アプリ制御レジスタ 50 0x0D AICTRL1 0x0E AICTRL2 0x0F AICTRL3
【MODEレジスタ詳細】 (MODE)
MODE制御レジスタの内容は下表にようになっています。これで基本的な
動作を設定することになります。今回の設定では表の赤字の部分だけです。
ビット 略称 説明 設定内容 0 SM_DIFF 差動動作指定
左チャネルの位相を逆させる0:通常
1:左側位相反転1 SM_LAYER12 MPEGレイヤTとUを有効化
MPEGレイヤVに追加する0:無効
1:有効2 SM_RESET ソフトウェア リセット
このビットは自動的にクリアされる0:通常
1:リセット3 SM_OUTOFWAV WAV再生をジャンプ
再生したくないときセットしてからゼロのデータ
をこのビットがクリアされるまで送信する0:しない
1:する4 SM_SETTOZERO1 ゼロにする 0:する
1:しない5 SM_TESTS SDIテストの有効化 0:無効
1:有効6 SM_STREAM ストリームモードにする
データを一定間隔でストリームとして送信する0:しない
1:する7 SM_SETTOZERO2 ゼロにする 0:する
1:しない8 SM_DACT DCLKの有効エッジ指定
SDIのデータをサンプリングするタイミングの指定0:立上り
1:立下り9 SM_SDIORD SDIのビット並び順 0:MSbから
1:LSbからA SM_SDISHARE SPIのCSを共用する
XDCSとXCSを共用とする0:しない
1:するB SM_SDINEW 新SPIモードにする 0:しない
1:するC SM_SETTOZERO3 ゼロにする 0:する
1:しないD SM_SETTOZERO4 ゼロにする 0:する
1:しない
【低音高音強調】(BASS)
この制御は下記フォーマットの制御データとして設定します。
実際に送信するときのデータは下記のようになります。
0x02、0x02、0xTT、0xBB
この中のTTとBBの部分が下図のようになりますが、 今回は低音ブーストだけ
使っていますので下位8ビットだけ制御し上位バイトは0x00のままとしています。
【クロックダブラーの詳細】(CLOCKF)
使用する外部クリスタル振動子の周波数から、VS1011eが内部で使用する
標準周波数(24.576MHz)を生成するための機能で、内部で微調整ができるように
なっています。
CLOCKFレジスタに設定する値は下記の計算式で求めます。
(1) 高い周波数のクリスタルの場合
CLOCKF設定値 = XTAL周波数 ÷ 2000
(例) 26MHzの場合 26000000÷2000=13000 → 0x32C8
(2) 低い周波数のクリスタルの場合
CLOCK設定値 = 0x8000 + (XTALの周波数 ÷ 2000)
0x8000を加えることで周波数が2倍化されます。
(例) 12.288MHzの場合 12288000÷2000 + 0x8000 = 0x9800
(3) 24.576MHzの場合
CLOCKFの制御は不要(デフォルト)
今回は12.288MHzのクリスタルを使いましたので、実際には下記のデータ
を出力します。
0x02、0x03、0x98、0x00
【音量制御の詳細】(VOL)
音量制御のデータは下図のようになっていますので、2バイトで左右の音量を
自由に制御できます。実際に送るデータは下記となります。
0x02、0x0B、0xLL、0xRR
この中のLLとRRのデータが下図のようになります。
【リセット】
VS1011eのリセットにはXRESETピンを使ったハードウェアリセットと、MODE
レジスタのSM_RESETビットを使ったソフトウェアリセットがあります。
(1) ハードウェアリセットの場合
XRESETピンをLowにします。XRESETをHighに戻し、約2msec後にDREQピン
がHighになるのを待ちます。
(2) ソフトウェアリセットの場合
MODEレジスタのSM_RESETビットを1にセットすると自動的に内部がリセットされ
約250μsec後にDREQがHighとなりますので、これを待ってから次の制御を実行します。
ソフトウェアリセットをする前に、バッファ内の音楽データを出し切りたい場合には、
2048バイトの0x00のデータを送信します。
【正弦波テスト】(Sine Test)
VS1011eには自身で正弦波を出力するテスト機能を持っています。
音楽データを再生するまでにテストで動作確認をする場合や、BEEP音を出したいときに
この機能が使えます。
テストモードに入るには、MODEレジスタのSM_TESTSビットがセットされていることが
必要です。テストを実行するには、下記の8バイトのシーケンスを出力します。
0x53、0xEF、0x6E、0xXX、0x00、0x00、0x00、0x00
ここで0xXXのXXは下記で求めます。
テストの終了には、下記シーケンスを出力します。
0x45、0x78、0x69、0x74、0x00、0x00、0x00、0x00
【実際の動作手順】
実際にVS1011eを動かすときの手順はマニュアルに従い、下記の順序で制御
します。
(1)VS1011eの電源ををオンとする
(2) XRESETピンを一定時間待ってからHighとして解除する
(3) DREQがHighになるのを待つ
(4) MODEレジスタの設定、SM_SDINEWとSM_TESTSをセットする
(5) クロックが24.576MHzでない場合にはSCI_CLOCKFを設定クロックダブラを設定する
(6) 音量制御と低音ブーストを好みに設定制御する
ここまでで準備完了
(7) DREQがHighになるごとに曲データを出力する
これを繰り返せばこの間オーディオ出力が行われる
(8) 曲データの転送終了後,未再生のオーディオ・データが残っていないことを確実に
したい場合には,さらに2048個の0を出力する
(9) MODEレジスタのSM_RESETビットをセットする(ソフトウェア・リセット)
これで一巡完了、次の曲に移るにはステップ(6)へ戻る
【回路】
まずVS1011eを実装したサブ基板の回路は下図のようになっています。
ほぼVS1011eのデータシートどおりになっています。R10の0Ωの抵抗は
アナロググランドとデジタルグランドの接続用ですので、実際にはジャンパ
で接続します。
メイン基板は下図の回路となっています。簡単な回路で済みました。
スイッチやSDカード、VS1011eの入力に必要なプルアップ抵抗は全て省略し
PIC24Fの内蔵プルアップ抵抗を使っていますので、非常に少ない部品点数
となっています。
セラミック発振子は使わず、PIC24Fの内蔵発振器を使いましたので実装は
していません。
ポケッタブルにする回路の場合は、ICSP用のモジュラージャック、リセットスイッチ
など省略できますから、かなり小型化可能だと思います。
電源をバッテリにする場合にはチャージポンプICを使えばさらに小型化できます。
【基板組み立て】
基板構成はPIC24Fを実装したメインの基板と、VS1011eを実装した
サブ基板で構成されています。
組み立て完成状態の部品面
サブ基板のはんだ面にVS1011eが見える
このサブ基板の下側にSDカードがある
スイッチだけの操作部
メインボードの裏面にはSDカードを実装
3端子レギュレータもはんだ面に実装
このパターン図は下記でダウンロードできます。
PDFファイルですのでそのまま印刷してお使い下さい。
★★★ メイン基板パターン図
メインボードの部品面
サブボードの部分には何も実装していない
サブ基板の部品面
ステレオジャックは直接サブ基板に実装
抵抗はリード線型のものを使った
サブ基板のはんだ面側
こちらにVS1011eのICと、チップコンデンサ
が実装されている
このサブ基板のパターン図は下記でダウンロード
できます。PDFファイルですのでそのまま印刷して
お使い下さい。
★★★ サブ基板パターン図
VS1011eの実装状態
ちょっとはんだ付けにはコツが必要
【プログラム製作】
このMP3プレーヤのプログラムはMPLAB C30のC言語だけで記述しています。
またSDカードのファイル操作用のプログラムはすべてマイクロチップ社のフリーの
FATファイルシステムを使っています。
これでファイル操作に関するプログラムは何も作る必要がなくなります。
あとはVS1011e制御用のプログラムですが、こちらは独立のソースとしてライブラリ
のような構成にしました。
これでメイン関数の部分はほんのわずかのプログラム状態になりすっきりしました。
またC言語だけで記述していますので、PIC18などへの移植も簡単にできると思います。
機能としては単純なものとしていて下記のようになっています。
(1) SDカードのルートにのみMP3ファイルがあるものとします。
(2) 電源オンで任意の「*.mp3」ファイルを見つけて再生を始めます。
(3) そのままにしておくと、SDカード内にあるMP3ファイルを順番に再生し
全部終わるとまた最初から再生しなおすので永久に再生します。
(4) 曲をスキップしたいときは、SW3を押すと直ぐ次の曲に移動します。
(5) 音量のアップダウンはSW1とSW2で行います。
(6) 低音ブーストの変更はSW4で行い、SW4を押すごとに1dBずつアップし、15dBを
超えると0dBに戻ります。
このMP3プレーヤのプログラムはMPLAB IDEのプロジェクト全体として下記から
ダウンロードできますので、そのままお使い下さい。
★★★ MP3プレーヤ試作プログラム
メインのプログラム部は下記のようになっています。
まず初期化部では、コンフィギュレーション設定のあといくつかの変数の宣言を
しています。
次にメイン関数に入って初期化作業を行います。最初はポートの初期設定で
入出力モードを決めます。次にスイッチはすべて状態変化割り込みを使うことに
しましたので、内蔵プルアップの指定と割り込みを許可しています。
次にSPI1とSPI2のピンを割付けています。これで自由になるので配置は楽です。
続いてVS1011eの初期化と再生のための音量と低音ブーストの初期設定を行います。
これで再生の準備はすべて整いましたので、FATファイルシステムを初期化後
最初のファイルをサーチし、見つかればオープンします。
次がメインループ部で、ここが繰り返されます。オープンされたファイルの音楽データを
ひたすら送信出力しますが、その前に、音量と低音ブーストのスイッチが押されていたら
その制御を行います。次はファイルから256バイト単位でデータを読み出し、DREQの都度
データを送ります。
この音楽データやファイルアクセスのSPIの送信中に割り込みで中断されると動作が
ハングアップしますので、この間は割り込み禁止としてスイッチの割り込みで中断され
ないようにしています。この間が約25msec程度ですので、スイッチ操作には何の影響も
ありません。
ファイルの終わりまで行って再生が完了したら終了処理をしてから次のファイルをサーチ
します。このサーチで見つからなかったら、最初に戻って繰り返します。
次がスイッチの入力の状態変化割り込み処理部です。ここはすべて割り込みで
入ってきますので、どのスイッチが押されたかをチェックしてそれぞれの処理をします。
音量と低音ブーストは再生しながら変更する必要がありますから、ここでは変数の値だけ
変更しフラグをオンとするだけで、実際の設定制御はメインループの中で行っています。