スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。



にほんブログ村 その他趣味ブログ 趣味の工作へ にほんブログ村 その他趣味ブログ ビデオ撮影・編集へ

PICでSDカードからデータを読む

PICでSDカードからデータを読んでみましょー

前回のマトリックスLEDに顔を表示するために
予め顔に関するファイルをSDカードに保存し
それをPICで読み込んでマトリックスLEDに表示します

まずはカードの制御
カードとの通信方式にはネイティブモードとSPIモードがあり
前者はカード本来の方式、後者は比較的容易な方式でPICのようなチープなCPUで制御するのに向いてます
従ってSPIモードで通信します

SPIモードは信号線4本(電源を考慮すると6本)で制御できます
CLK:同期クロック  DI:データイン  DO:データアウト  CS:カード選択
2014/5/31追記:画像のピンアサインは左右逆です。


制御方法はいたって簡単
PICからコマンド・フレームを送って応答を待つだけ

コマンド・フレームは8bitのコマンドと32bitの引数、8bitのCRCから成ります


今回使ったコマンドは以下の通り

この4つのコマンドにはどれも8bitの応答が返ってきます
CMD0には0x01、それ以外には0x00が正常な応答です

以下、SDカードの任意の場所からデータを読むまでの流れです
※SDC ver2.00の場合
○初期化
(1) CSをLOWにする (2)へ
(2) CMD0(引数:0)を送信、応答0x01がくるまで送信を繰り返す (3)へ
(3) CMD1(引数:0)を送信、応答0x00がくるまで送信を繰り返す (4)へ
(4) CMD16(引数:ブロックサイズ)でブロックサイズを512に設定、応答0x00がくるまで送信を繰り返す (5)へ
○データ読込
(5) CMD17(引数:任意のアドレス)を送信、応答0x00がくるまで送信を繰り返す (6)へ
(6) 応答0xfeが来るまで受信を繰り返す (7)へ
(7) データを512byte受信する (8)へ
(8) CRCを2byte受信する

(7)で取得した512byteが任意のアドレスを始めとした512byte分のデータです
例えば任意のアドレスを1024とすれば、1024~1535までのデータを取得できます
512byte分というのは(4)で指定したブロックサイズに依存します
例えば(4)で64に設定すれは64byte分受信することになります

これでカードの任意の場所からデータを読めるようになりました
しかし、これだけではファイルは読めません

ファイルと一言いっても・・・
ファイルには中身以外にも名前とか作成日時とか色々な情報が必要です
その情報を整理して記録するためにSDカードやHDDのような記憶媒体には
ファイルシステムというものが採用されています

ファイルシステム無しではただの散らかったタンスですが
ファイルシステム有りでは何処に何を入れたか記録する専用の引きだしがあって
そこから入れたものがすぐにわかるように整理されたタンスのようなイメージです

種類はFATやNTFSなど色々ありますが
普通SDカードにはFATが使われています

面白いのでこれも説明すると・・・
FATはカードの中身をこんな感じに5つの領域に分けます

これは私が使っている2[GB]のカードの例です
データ領域以外は全部データの管理用です
全容量1.9[GB]中400[KB]くらいがデータ管理に使われていることがわかります

ここで余談ですが、ファイルシステムではセクタという概念が使われています
私のカードの場合セクタ1個は512byte分のデータの集合です

FATではセクタ単位でのアドレスの管理をしているため今後アドレスというのは
セクタ単位での数値とします

以下、ファイル名を指定してファイルを読み込むまでの流れです
○FAT基本情報読込
(1) MBR のアドレス(*1)454-457から予約領域の先頭アドレスを取得する (2)へ
(2) 予約領域のアドレス(*2)14-15から予約領域のサイズ、16からFAT領域のFATの数、22-23からFAT1つのサイズを取得し
    ルートディレクトリ領域の先頭アドレス(*2)を計算する (3)へ
  = 予約領域サイズ + FAT領域のサイズ = 予約領域サイズ + FATの数 * FAT1つのサイズ
(3) 予約領域のアドレス(*2)17-18からディレクトリエントリー数を取得し
    データ領域の先頭アドレス(*2)を計算する (4)へ
  =  ルートディレクトリ領域の先頭アドレス + ディレクトリエントリー数 / 1セクタ当たりのディレクトリエントリー数
○ファイル検索
(4) ルートディレクトリ領域にはファイルの名前や作成日時などのファイルの情報が32byte単位で記憶され
  そのうち0-10bye目に名前が記憶されている
  よってルートディレクトリ領域の先頭アドレスから32byteごとにファイルを検索
    名前のマッチするものを見つける (5)へ
(5) 26-27byte目からデータ領域におけるファイルデータの位置を取得する
○ファイルデータ読み込み
(6)(5)で得られたデータ領域におけるファイルデータの位置からファイルデータの先頭アドレス(*1)を計算する
   = 予約領域の先頭アドレス(*1) + データ領域の先頭アドレス(*2) + データ領域におけるファイルデータの位置

*1:物理アドレス(カード先頭を0としたアドレス)
*2:論理アドレス(予約領域先頭を0としたアドレス)
注:この手順で読めるのはルートディレクトリにあるサイズ512byte以内のファイルに限る

以上より任意の名前のファイルデータを取得できました

ただファイルを読むだけでも結構手間がかかりますね
事前に勉強はしていましたがプログラムを完成させるのに丸3日もかかってしまいました
PICでSDカードを制御する整ったプログラムを公開している方はなかなかいないので
そのうち公開しようと思いますっ 現在整理中です

動作様子は現在オシロスコープでの波形とLED2進数表示でしか確認できず全然パッとしませんw




読み込んだファイル


表示結果

2進数 0b0011 0001 0011 0010 0011 0011 0011 0100
=16進数 0x31 32 33 34
文字コード変換すると '1' '2' '3' '4'

はやく顔をドットマトリクスLEDに表示できるようにしたいですね
そのためにも次は顔のデータファイルを作っていきたいと思います

=参考文献等=
FATファイル・システムのしくみと操作法 ChaN様 http://elm-chan.org/docs/fat.html
MMCの使いかた ChaN様 http://elm-chan.org/docs/mmc/mmc.html
記憶メディアの構造 natu様 http://www.mars.dti.ne.jp/~m7030/yellow_hos/fat.html
Twitterやブログの方々



にほんブログ村 その他趣味ブログ 趣味の工作へ にほんブログ村 その他趣味ブログ ビデオ撮影・編集へ

コメントの投稿

非公開コメント

非常にわかりやすい

大変参考になります。

ありがとうございます

どうもありがとうございます(*^-^*)
プロフィール

回路師

Author:回路師
趣味がロボットと動画製作です。
便利な機械やあほなマシンの動画を投稿しています.

最新記事
最新コメント
カテゴリ
電子工作キット








月別アーカイブ
書籍






Twitter
リンク
RSSリンクの表示
ソーシャル

検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。