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カードのソケットは、秋月電子で購入
ソケットの裏に、丸い突起が2つあります。
径の大きい突起は、削り落としました。
径の小さい突起は、スルーホールにピッタリ
はまるので、ソケットの位置決めに丁度良いです。
7,8,10,11の部分のスルーホール(2個)は、
表からザグリ加工すると、配線が楽になります。

ソケット内部にSWがあり、カード挿入有無、書き
込みロックSWの状態で、ON/OFFします。

左の写真では、ソケットの端子は、上部が9、
下部が11と上の回路図とは、位置が逆になります。

裏はこうなってます

プルアップ、プルダウン抵抗など
真中のチップ部品は、4.7μFのコンデンサ

22uHのコイルはまだ未購入
(電源を制御しないなら不要ですね)

裏からスルーホールに半田を流す場合は、表側に
半田が盛り上がり、SDCARDと干渉する恐れがあ
るので、表側からスルーホールをザグり、カプトン
テープを貼ってあります。

上記のをここに刺して使用します。
カードの有無、ライトプロテクト、電源の制御線は、
未配線です。
電源制御は、常にオン状態。
上は、電源
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程度なので、
5Vでは壊れると思います。

SH2−7144につないだ場合は、こんな形です。
こちらも、うまいこと動作してます。


SPIの通信をソフトで行っている為、Atmega168
より遅いです。
手元にあるのは、みんな使えました

左から

miniSDカード(16MB) と SDカードアダプター
microSDカード(32MB)と SDカードアダプター
SDカード (16MB)
SDカード(256BM)

256BMのみFAT16
その他は、FAT12

 コンバージョンのポイント
   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             
10msタイマー

8ビットタイマー コンペアマッチ割り込みを使用する。
レジスタ内部のBIT構成が異なるため、修正が必要
1秒タイマー 32768hzの時計用クロック
を使用して、タイマーA
 使用せず(必要な場合は10msタイマーより作成可能)
RS232C通信 USARTを使用しRS232C用IC
等を使用して、論理反転する。
chanさんのソフトで実現(アセンブラ) 384kbps
接続は、簡易回路。
クロック 外付け 9.216Mhz  内臓8Mhz RS232Cで意識する
SPI通信用 SPI通信機能を使用
PB0〜PB3を使用

SPI通信用  制御レジスタは変更無く使用可能
PB2〜PB5を使用(ソフト・ハードの変更が必要)
       
       
       
       
       
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カードコネクタ(沢山買った人は私に分けて下さい)


        

inserted by FC2 system