AVRでSDカードを使う
2007.03.21
改定 2007.04.04
工事中ですが、UPしました。 説明は、時間をみて書き加えます。
(1) AVRでSDカードのアクセス
chanさんのFATファイルシステムでAtmega64を使用したサンプルがあります。
http://elm-chan.org/fsw/ff/00index_j.html
ATMEGA168でSDカードを読み書きしようとコンバージョンしました。
ROMは、16KBありますが、RAMは、1KBしかありません。
Tiny-FatFsなら、RAMが1KBでも可能とあったので試してみました。
運良く動作したので、UPしました。
chanさんのFATファイルシステムを使う人が参考になれば幸いです。
SDカードとの接続は、SH2−7144で接続したものをそのまま使用しました。
回路図です。 chanさんのそのまま流用 10、11のプルアップ抵抗がありませんが、H8 やAVRではマイコンのプルアップの機能を使用し てました。 ここをプルアップで使用した場合 10(INS#)は、H:カードなし、L:カード挿入状態 11(WP)は、H:WPなし、L:WPあり となります。 プルアップが無いと、Hにならずオープン状態になります。 FETは、ゲートがLで電源オン。 CSに接続しているLEDの電流制限抵抗は、1KΩ では、LEDにより少し暗いかも。 アクセス時に一瞬光るだけだから。 ここは輝度を上げるようにした方が良いです。 |
|
黒いチップは、電源制御のFET(2SJ355) 上部のledは、電源とアクセスランプ SDカードのソケットは、秋月電子で購入 |
|
裏はこうなってます プルアップ、プルダウン抵抗など 真中のチップ部品は、4.7μFのコンデンサ 22uHのコイルはまだ未購入 |
|
上記のをここに刺して使用します。 カードの有無、ライトプロテクト、電源の制御線は、 未配線です。 電源制御は、常にオン状態。 上は、電源 SPI制御は、左側で上から CS PB.B2を SDカードのCS DO PB.B3を SDカードのDI DI PB.B4を SDカードのDO CLK PB.B5を SDカードのCLK に接続します。 |
|
RS232Cとの通信は、抵抗のみの簡易回路。 COMポートに直接つなぎます。 接続の確認は、 TXD(送信)は、電圧ゼロの端子。 RXD(受信)は、−9V前後の端子。 SDカードとのWPとINS#は、結線なし。 |
|
接続してatmega168につないだ状態 電源電圧は、3.3Vです。 SDCARDは、使用電圧が、2.7V〜3.6V程度なので、 |
|
SH2−7144につないだ場合は、こんな形です。 こちらも、うまいこと動作してます。 SPIの通信をソフトで行っている為、Atmega168 より遅いです。 |
|
手元にあるのは、みんな使えました 左から miniSDカード(16MB) と SDカードアダプター |
コンバージョンのポイント
SH2-7144 と Atmega168 をコンバージョンしました。 その経験を書きますと
1.FATを使用しないなら、ff.c(tff.c)を使用する必要がありません。
他とのデータ互換を考えなければ、セクタ単位の読み書きで使用できます。
mmc.c
は、プラットフォームに依存した部分があるので、変更が必要になります。
2. 1に加え、FATファイルシステムを使用すれば、パソコン等の他とデータのやり取り
が可能になります。 ff.c (tff.c) を使用しますが、プラットフォームに依存する部分が無いので、
mmc.c が動作すれば、問題なく動くと思います。
3. 10ms秒のタイマー割り込みを使用し、ディレイ、処理タイムアウトで使用しています。
ここを、プラットフォームに合わせて、コンペアマッチの機能を使用して実現する必要があります。
割り込み処理の中で、
disk_timerproc();
を呼び出せばOKです。 10msタイマーが機能しているか 試すのは、 (avr版の例として)
for (Timer1 = 100; Timer1; );
で 100x10ms = 1秒 のディレイが機能することで確認できます。(LEDの点滅等で。)
ただしこのテストをする際、mainで
static volatile volatile BYTE Timer1,
Timer2;
としましたが、mmc.cとのデータ共有がうまく行かず(mapで確認)、両者でstaticを外したら成功しました。
原因は良く分かりません。
4. AtmegaでSPIをサポートすれば、SPIの制御レジスターは、たぶんどれも同じと思うので変更は必要ないはず。
ただし、 ポートが異なる場合は、変更が必要になります。
SPIがサポートされていない場合で、自力でSPIを操作する場合は、H8用のソースが参考になります。
5. SDCARDの電源のON/OFFは、行わず常時電源ONのままでも、特別不便は、感じていません。
(保証できませんが)電源ONのまま、カードの抜き差しを行っていますが、SDカードはまだ壊れていません。
6. 書き込みのロック、カード挿入の有無の線も配線していませんが、これも不自由を感じていません。
ここを配線しない場合は、 disk_status() で、 考慮する必要があります。
7. FATファイルシステムで、ファイルを生成する場合、ファイルのタイムスタンプに使用する、年月日時刻が
必要です。 いつも固定値でよければ、 get_fattime() で固定値を返せば、OKです。
chanさんので、1秒のタイマーを使用しているのは、リアルタイムで、現在時刻を更新している為です。
ファイルのタイムスタンプがゼロは、パソコンからファイルの削除でトラぶったことがあったので、お勧めしません。
秋月電子のRTC-8564NBを使用すれば、リアルタイムクロックを実現できます。このICを電池でバックアップ。
8. diskio.h や ff.h (tff.h)の先頭で、マクロの定数指定で機能の選択ができます。これで、ROMサイズを削減できます。
今回変更した点
この表は、工事中です。
NO | Atmega64(オリジナル) | Atmga168 | |
1 | 10msタイマー | 8ビットタイマー コンペアマッチ割り込みを使用する。 レジスタ内部のBIT構成が異なるため、修正が必要 |
|
2 | 1秒タイマー | 32768hzの時計用クロック を使用して、タイマーA |
使用せず(必要な場合は10msタイマーより作成可能) |
3 | RS232C通信 | USARTを使用しRS232C用IC 等を使用して、論理反転する。 |
chanさんのソフトで実現(アセンブラ) 384kbps 接続は、簡易回路。 |
4 | クロック | 外付け 9.216Mhz | 内臓8Mhz RS232Cで意識する |
5 | SPI通信用 | SPI通信機能を使用 PB0〜PB3を使用 |
SPI通信用 制御レジスタは変更無く使用可能 PB2〜PB5を使用(ソフト・ハードの変更が必要) |
8 | SDカード電源制御 | 制御せず常時ON |
手持ちの全てのSDカード SDカード16MB(FAT12)、256MB(FAT16)、miniSDカード16MB(FAT12)、
microSDカード32MB(FAT12)が使用可能でした。
どれも、安定してアクセスできています。エラーになることは、ありません。
FAT16がOKでしたので、2GBのカードも使用できるはずです。
オリジナルソースとの比較は、このコンペアツールFDが見やすいと思います。フォルダーの比較が可能。
http://www.vector.co.jp/soft/dl/win95/util/se113286.html
chan さんの 元になったソース日付けは,07.
2. 4 で最新ではありません。
1. 最初の版
ソースなど、これです。 mega168-sd-01.lzh
main.c
の 5行目から 下記のようになっています
#define _EX_MODO 0
// _EX_MODO :
// 0 : disk_read 等 のFATファイルシステムを使用しない
// 1 : f_open f_read 等 のFATファイルシステムを使用する
(1) #define _EX_MODO 0 とした場合
0を指定し、makefile の4行目で tff.o を指定しなければ、rom、ram がコンパクトになります。
尚tff.o を指定しても、サイズは大きくなりますが動きます。
セクタ単位(512バイト)の読み込み書き込みができます。 FATファイルシステムを無視することで
かまわなければ、セクタ番号を変えて自由にI/Oできます。
サンプルソースの操作手順は、キーボードからコマンドを出します
I : SDカードの初期化(formatや、fdiskではありません)。 ゼロで成功。
他のコマンドを実行する前に、最初に実行する必要があります。
r
: 1セクタ読んで(ゼロで成功)、ダンプする。読み込み位置(セクタ番号)を+1
R : 1セクタ読んむ(ゼロで成功)。 読み込み位置(セクタ番号)を+1
B : 1セクタ読んむ(ゼロで成功)。 読み込み位置(セクタ番号)を−1
d : 読み込んだデータをダンプ
w
: バッファの内容を書き込みます。事前にSコマンド等で内容を変更した場合は、一旦電源を落とし、
再度立ち上げて書き込んだことが確認できます。
ただし、FATファイルシステムで使用している場所に書き込んだ場合は、パソコンに接続した
カードリーダ(ライタ)からアクセスできなくなる場合や、内容が破壊される場合があるのでその覚悟
が必要です。解決する場合は、SDカードのフォーマットが必要になります。
フォーマットを避ける場合は、未使用のセクタ(番号を大きくして)を使用して書き込む事をお勧め
します。
フォーマットにより、アクセスが極端に遅くなる場合が、あるそうです。(クラスターのサイズ等が
変わるため。)
S
: バッファの内容を一部変更しています。 変更内容に意味はありません。
読み込み(書き込み)位置を変える場合は、
CnnnnP とします。 nnnnは、10進数。例えば
C0P : セクタ番号を0に。
C2000P : セクタ番号を2000に。
使い方としては、まず I コマンドで初期化を行い。 r コマンドで読んだデータがダンプされます。
(2) #define _EX_MODO
1 とした場合
FATファイルシステムを使用した、ファイルを意識した扱いのサンプルです。
makefile の4行目で tff.o が必要になります。
コマンド X を入力すると、 file9876.txt を dstf000.txtとして新規にコピーを作成します。
これを確認するには、 file9876.txt 事前に書き込んでおいて下さい。 ファイル作成日付は
固定した値が入ります。 現在バッファ長は、80バイトとなっていて、読み書きする度に ステータス
を表示するので、ファイルサイズが大きいと、その表示が延々と出ますので注意してください。
ステータス(resの値)が全てゼロなら、コピー成功です。
バッファサイズを多くすれば、read/write回数が減りますが、ram の残りサイズにより何処まで大きくできるか
わかりません。(試していません)
2. 上記の機能を1つにした版です。 512バイトのバッファーを兼用してるので、少し分かりにくいかも。
ソースなど mega168-sd-02.lzh 2007.3.29
3. 1の改造版です。
mega168-sd-03.lzh 2007.4.4
1に加えて
s : 1セクタ読んで、16バイトダンプする。読み込み位置(セクタ番号)を+1
b : 1セクタ読んで、16バイトダンプする。読み込み位置(セクタ番号)を−1
f :
ゼロセクタ(MBRレコード)、BPBレコード、ディレクトリエントリの最初のセクタ
をダンプする。
T : ルートディレクトリーの全ファイルの、全セクタを読み出す。
f
コマンド実行後に行う必要があります。
disk_read
を使用し、クラスタのチェインをたどっています。 FAT12,FAT16に対応。
セクタ番号の表示は、16bitまでの対応なので、それ以上は、正しく表示されません。
参考
http://panasonic.jp/support/audio/sd/download/sd_formatter.html SDカード用フォーマットソフト
(SDカードを正しくフォーマットする)
http://elm-chan.org/docs/spi.html chanさん SPIについて
http://elm-chan.org/docs/mmc/mmc.html MMCの使い方
http://elm-chan.org/fsw/ff/00index_j.html FTAファイルシステム
http://naruken.cweb.tk/labo/mmc/index.html なる研 マルチメディアカード
http://www.geocities.jp/kabavm/fat.html FAT構造
http://www.mars.dti.ne.jp/~m7030/yellow_hos/fat.htm
FAT構造
http://www.cek.ne.jp/~kunio.h/fat.htm FAT構造
http://nishikawa.or.tv/shop/e_shop.cgi 西川電子部品 miniSDカードコネクタ(沢山買った人は私に分けて下さい)