2015年7月17日金曜日

dsPIC33FJ64GP802でmicroSDの読み書きをしてみた


MDDFS (Microchip's Memory Disk Drive File System) を用いてmicroSDの操作をしました。

既に、MDDFSを用いた操作についていくつかのサイトでまとめられていますが、その時、その時のバージョンや環境での説明なので、手元にあるライブラリと異なる点が多々ありました。

その点混乱しないよう、違いがある可能性もあるよという言葉を添えながらまとめたいと思います。
では、極力箇条書きで説明していきます。


/********************************************************
 記事 更新履歴
'15/09/02(水) main関数内にて、システムクロックの設定が狂っていたので修正しました。

'15/07/22(水) システムクロックの設定が動作周波数の上限を超えていることに気づきました。Foscは80MHz以下、Fcyは40MHz以下となっています。時間ができたら直ぐに修正しますのでこの記事を参考にされる際はお気をつけ下さい。

*********************************************************/

1.大まかな手順

(1) MDDFSライブラリをMicrochip社ホームページからダウンロード、インストールする。
(2) 必要なファイルを揃える。
(3) SD操作に使用するSPI端子をPPS機能で設定する。(Peripheral Pin Select)
(4) SD操作に使用するピンアサインにライブラリを修正する。
(5) 不要なプログラムのコメントアウト
(6) クロックの設定
(7) SDにファイルが作成出来るか確認する。

2.具体的な手順

(1) MLAのダウンロード、インストール

MDDFSを使用するためには、Microchip社ホームページからMicrochip Libraries for Application(MLA)をダウンロード、インストールする必要があります。
その中にMDDFSも含まれています。
(URL -> http://www.microchip.com/pagehandler/en-us/devtools/mla/home.html )

私がダウンロードした時のバージョンは v2013-06-15 となっておりました。
(MLA保存時のフォルダ名です)

(2) 必要なファイルを揃える

・main (自分で作成する)
https://drive.google.com/open?id=0BzFKG7_PKHJ9Y201MWcxajhfa0U
・HardwareProfile.h
https://drive.google.com/open?id=0BzFKG7_PKHJ9NjBXbE5OOTA3VEU
・FSconfig.h
https://drive.google.com/open?id=0BzFKG7_PKHJ9SncxbHZTcjFBT28
・FSIO.c
https://drive.google.com/open?id=0BzFKG7_PKHJ9dlRmMTIwS24xa3M
・FSIO.h
https://drive.google.com/open?id=0BzFKG7_PKHJ9dlRmMTIwS24xa3M
・SD-SPI.c
https://drive.google.com/open?id=0BzFKG7_PKHJ9b2kwUUxtOG5QUVk
・SD-SPI.h
https://drive.google.com/open?id=0BzFKG7_PKHJ9TmlVQTV3VmNXZDA
・FSDefs.h
https://drive.google.com/open?id=0BzFKG7_PKHJ9SEZmYmU1UVRWRW8
・GenericTypeDefs.h
https://drive.google.com/open?id=0BzFKG7_PKHJ9dlhlZng3bGpPN2M
・Compiler.h
https://drive.google.com/open?id=0BzFKG7_PKHJ9T0JndWlhMnp1dzA

面倒なことに、全てまとまったフォルダに格納されていません
MLAのインストールされたフォルダ内を漁って探してください。
どうしても見つからない場合はGithubなどから頂戴しましょう。
但し、ファイルがどう改変されているか分からないので、いろいろ問題が増える可能性があります。

ファイル名ごとにあるURLは私のファイルを丸々GoogleDriveに載せたものです。

また、この記事の中で行数を指定する時、それらは全て添付したURL先の行数をさします。お手元のファイルとは一致しない可能性が高いです。
また、型番が異なる場合は設定を書き込む場所も異なります。
今回の場合は _dsPIC33E_ と定義されている場所が記入場所です。

私の添付したファイルをそのまま利用するのは避けてください。
コメントアウト部分が鬱陶しかったため、他の型番のPICでは使用するであろう部分を多く消してしまいました。書き直す予定もありません。

(3) PPS機能で使用するピンを指定する

PPS機能の詳細はMicrochip社公式のyoutube動画を見て欲しい。非常に分かりやすい。
これを使ってSD読み書きに使うSPI通信端子を設定しなくてはならなりません。

私のmain.cファイルでいえば、L62~L106 に記述してあります。
これらの設定の意味は上の動画を見ていただければわかると思います。

<ピンアサイン>
_____<SDpin>_______________<PIC pin>
___DO(SDO)____________RP2(SDI1   :RB2)
___CLK(SCK1)_________RP4(SCK1OUT:RB4)
___DI(SDI)_______________RP3(SDO1   :RB3)
___CS_____________________RB4

(4) ピンアサインを修正する

主に HardwareProfile.h 内で設定します。

定義が必要なものは
a) SD_CS              (L277)
b) SD_CS_TRIS      (L279)
c) SPICON1          (L298)
d) SPISTAT          (L300)
e) SPIBUF            (L302)
f) SPISTAT_RBF   (L304)
g) SPICON1bits     (L306)
h) SPISTATbits     (L308)
i) SPIENABLE      (L310)
j) SPIBRG           (L312)
k) SPICLOCK       (L317)
l) SPIIN              (L319)
m) SPIOUT           (L321)

SD_CS はチップセレクトピンで、ピンの書き込みをONにしたりOFFにしたりという操作を行うようです。ですので、SPI通信のピンには含まれず、適当なGPIOを指定します。

SD_TRIS はCSピンの入出力を指定してもらうために指定します。

(c)~(j)はSPIxのxを使用するSPIの添字に書き換えるだけです。
デフォルトではSPI2ホニャララというようにSPI2が指定されていた気がします。
SPI2を使う場合は、PPSで指定するピンも SDI2、SDO2というように変更が必要です。

SPICLOCK はPPSで指定したピンを指定してください。但しRPxと指定するのではなく、TRISレジスタで指定してください。
SPIIN、SPIOUTも同じです。

(5) 使わないピン、プログラムのコメントアウト

必要のない操作ピンやプログラムはコメントアウトを施さないとエラーが発生します。
次の説明通りにコメントアウトしても、環境によってまだエラーが出る可能性も有りますが、その際はエラーに従ってください。

・HardwareProfile.h

a) SPI関係端子の入出力設定(TRIS) をコメントアウトする。

コメントアウトせずにここで指定しても構いませんが、あえてここで任せる必要もありません。
かえって頭がこんがらがると思うのでメインプログラム内で指定するのがベターだと思います。

b) アナログディジタル設定(ANSEL) 

※dsPIC33fj64gP802では ADPCFGレジスタです。
こちらも(a)と同じところでディジタル出力に設定してしまいましょう。
不要なのでコメントアウトします。

c) CD端子、WE端子のコメントアウト

これらは、カード検出端子とライトエネーブル端子です。
無くても読み書きには影響しないため、コメントアウトします。
しかし、設定できるならするに越したことはありません。

d) #include "uart.h"

このMDDFSライブラリはLCDを使ってデバッグを出来るように各所デバッグ処理が書かれています。
それを使用するならuartが必要なのでインクルードしているようです。
使うかは任意ですが、私はLCDを使ったことがないのでコメントアウトしてしまいました。

d) 各ファイルごとにインクルード先のディレクトリを指定しなおす。

ファイルが見つからないというエラーに度々出くわしました。その際はファイルがあるか今一度確認し、正しく指定しましょう。

(6) クロックの設定と指定

今回、内蔵FRCに更にPLLで周波数を上げて使います。
はじめのコンフィギュレーション設定で FRCPLL を指定します。
どの解説サイトを見ても、コンフィギュレーション設定ではFRCとし、その後にクロックをPLLに切り替える処理を施しているようなのですが、意味が分かりません。
何故ならクロックの切り替えは普通のプログラムと異なり、ロックを解除するという面倒な手間がかかるからです。
どうせPLLを使うのですからはじめからFRCPLLとコンフィグで指定するのが簡単そうです。

a)

Foscは次のように計算されます。
Fosc = FRCPLL(MHz) / N1 * M / N2
また Fcyは
Fcy = Fosc / 2
です。
細かいクロックの解説は次のサイトが非常にわかりやすいです。
dsPIC33FJ64GP802のクロック設定

b) HardwareProfile.h 内でクロックを指定しましょう。

(a)で求めた周波数Foscを (L62)のように
#define GetSystemClock()   Fosc / 2
というように書き換えてください。 ただし、Foscは(a)で求めた周波数の数値を単位(Hz)で書き換える。
※システムクロック Fcy が Fosc / 2なので、わかりにくい方は直接 Fcy の値を書いても構いません。

(7)コンパイルしてみる

コンパイルしてエラーが出たら焦らず修正します。
私としてはエラーが出ないほうが不思議です。

microSD内にファイルが作成されていれば成功です。

また、添付したメインソース・ファイルのなかで大きくコメントアウトしている部分は
アルファベットを書き込んだテキストファイルを読み込んで、それらを比較するプログラムです。

何か有りましたらお気軽にコメントを下さい。

3.参考文献

F1VRR(also JR3QZS)の無線日記 様
クロックの設定方法についてこちらのサイトが無ければどうにもなりませんでした。
日本語版データシートもあるので読めば分かりますが、概要をつかむのにとてもよいです。

WAVプレーヤ本体の製作 (Wi-FiソフトAPモード)
SDカードとの配線やDAC出力の配線など参考になりました。

マイコン風雲録 様
クロックの設定から音声再生まで、MDDFSのプログラムも一式添付してくださっており、こちらのサイトを比較しながらプログラムを修正していきました。

0 件のコメント:

コメントを投稿