gombeのブログ

マイコンの電子工作系PIC32/KiCad/C/C++/3D/

dsPICによる音楽Player

音楽Playerを作りました。

[caption id="attachment_71" align="alignnone" width="960"]外観 外観[/caption]

フルカラーLED&ロータリーエンコーダが手に入ったので(1年位前)これをつかうという目的でPCM Playerを作りました。けどなんか超巨大でiPod nanoの20倍の大きさになってしまいましたorg...

まあさておき解説に入ります。今回用いたPlayerの構成は以下のとおりになります。

  • dsPIC33Fワンチップ構成(と入ってもオペアンプは通しました())
  • 128倍のオーバーサンプリングにより滑らかな音(?
  • SDカードからぷちFatFSを使ってLPCMまあいわゆるwaveを読みだして再生します。SDHCも使えるのでたくさん曲が入ります。
  • ロータリーエンコーダですべての操作を行います。
  • 状態表示もロータリーエンコーダのフルカラーLEDで行います。
  • 電池駆動です。充電池でも再生できます。
  • 一応曲を記憶し、SDカードに保存します。でも、ぷちFatFSはファイル作成ができないので予め作成しておきます。
  • ただマイコン内臓のDACだけあってSNRが悪すぎ:'(で音量絞るとノイズが。。。ってなります。ディジタル演算にしたのも悪いかも。DACを切ると消えるのでたぶんみんなDACによるものだと思われます。電源分離とかもしたのになあ。。。

まあこんなかんじですかね。今回は消費電力が命なのでソレについてメモしたいと思います。

まず何も気をつけないで適当に組んでたら消費電力が再生だけで100mAを越しましたXDなので目標値を定めたいと思います。50mAです。

>結局のところ4/2現在電源回路やLEDやOPAMPやSD Cardやらで60mAくらいかと思います。テスターが不調で電流測ると起動しないorgけど充電池は12時間以上持つので念の為

>さらに調べていくとIdle時も消費電力があまり下がらない模様。Clockを落とすことで消費電力下げられますがそれでもあまりにも消費電力が高いと思います。理論上1400kbps出れば再生できるので2MHzのClockでも動くのでしょうが私の場合はこれ以上下げられませんでした。。。色々定格外(SPIのクロックプリスケーラとかPLL出力値とか)での動作なのでもうしょうがないかな?マイコンだけで30mA以上って。。。

音声データはSD->SPI->DMABuffer->PlayBuffer->DMABuffer->DACという感じで転送されます。間にPlayBufferが混じっている理由については後述します。

DMA使ってメモリー転送を行います。DMAとはDirectMemoryAccessの略でCPUがかかわらなくても転送先と転送元とかイベント(転送するための条件)を指定すると勝手メモリー間でに転送してくれます。今回はSDカードの読み出し時に用いたSPI(SDIOとかあったらいいのになあ)とDACモジュールで使いました。結局これによるメモリーアクセス次のオーバーヘッドはほとんど解消され、これにより消費電力が大幅に下がりました。

SPIでSDカードと通信する際、DMA使うんですが、SPIには便利なことにNULLData送信機能があるので1chだけで送信できるそうですとマイクソチップはってるんですが、そんなに世の中甘くありません。からデータは固定値のリテラル値(決められる値)ではなく0x00の固定値なのでSDカードが要求する0xFFではなく、データを受け付けてくれません:-(まあこんなこともあろうかとは思ってましたけどね。だから送信側に0xFFデータが詰まったバッファを用意する必要があります。今回は送信中に別の処理をすればクロックが下げられて消費電力も下がったのでしょうけど頭が回らないというかめんどくさかったのでIdle状態で待つことにしました。

DAC間でも用いりました。LRで別々のバッファに格納する必要があるので2chのDMAが必要です。更にバッファを2つ用意して交互に送信することもできるのでその機能を使いました。あまり送信間隔は広くはないんですけどIdle状態の時間が伸びて消費電力が下がるみたいです。

しかしDMAで転送できるメモリーは限られていて、今回使うdsPIC33FJ64GP802では2048Bまでです:'(

そんなこんなでバッファ間での転送のオーバーヘッドは少し残ったままになってしまいました。まあPIC32MXとかこのような制限がないのでもっと良くなると思うんですが。。。

そんなこんなでClockは少々アンダークロックですが30MHzくらいで動かすことが出来ました。内部は15MHz位です。(きちんと計算はしていない)。

ClockはPLLを通すんですが、そうするとジッターが交じるのでDACのClockはClystal発振子から直接通しています。そうするとCPUのクロックにかかわらず処理が追いつけば再生速度は一定になります。そうすると好き勝手にアンダークロックができるというわけです.XD

あと充電池の過放電対策しないとって思いながら使ってたら電池切れで電源が切れました。電圧が1.1V下回るとPICがリセットがかかるみたいです。なので特に対策しなくても良さそう:)

回路についてもあとで書こうかな?