カテゴリー「SD」の11件の記事

2010年5月27日 (木)

MDD File System 1.2.5

 今回SDカードを取り付けることで使用した「Microchip Memory Disk Drive File System」はバージョン1.2.5で、現時点での最新版です。

画像
 Microchip Solutionsに収録されているMicrochip Memory Disk Drive File Systemに必要なファイル
 (但し、Demonstration.cはmain.cを含むデモプログラムのファイル)

 “バージョン1.2.0でのWEやCD端子がない場合の改変のしかた”で紹介した1.2.0と、ファイル構成などは同じです。WE端子、CD端子が基板にない場合の改変のしかたも同じです。

 「Microchip USB Framework バージョン2.6」を使用しているPIC24USBテスト基板の場合、この「Microchip Memory Disk Drive File System バージョン1.2.5」を組み込むと、3つのファイルが重複します。

 Compiler.h
 GenericTypeDefs.h
 HardwareProfile.h

 「Compiler.h」と「GenericTypeDefs.h」は「Microchip USB Framework バージョン2.6」のそれと内容が同じなのでUSB Frameworkの「Compiler.h」「GenericTypeDefs.h」がそのまま使えますが、「HardwareProfile.h」は変更が必要になります。
 PIC24USBテスト基板のプログラムでは、USB Frameworkの「HardwareProfile.h」を、次にようにPIC24F256GB106及びPIC24USBテスト基板には必要がないコード部分を削除して使っています。

/*
 HardwareProfile.h
*/

#ifndef HARDWARE_PROFILE_H
#define HARDWARE_PROFILE_H

#define DEMO_BOARD USER_DEFINED_BOARD


#if !defined(DEMO_BOARD)
  #error "Demo board not defined.  Either define DEMO_BOARD for a custom board or select the correct processor for the demo board."
#endif

  //#define USE_SELF_POWER_SENSE_IO
  #define tris_self_power     TRISFbits.TRISF1   
// Input
  #define self_power          1

  //#define USE_USB_BUS_SENSE_IO
  #define tris_usb_bus_sense  U1OTGSTATbits.SESVD 
//TRISBbits.TRISB5    // Input
  #define USB_BUS_SENSE       U1OTGSTATbits.SESVD
 
  #define CLOCK_FREQ 32000000
 
  /** I/O pin definitions ********************************************/
  #define INPUT_PIN 1
  #define OUTPUT_PIN 0

#include "sd_hdp.h" // Microchip Memory Disk Drive File Systemで使うもの。下記の文章を参照のこと。

#endif  //HARDWARE_PROFILE_H

 これに今回Microchip Memory Disk Drive File Systemに必要な次のコード部分をMicrochip Memory Disk Drive File Systemの「HardwareProfile.h」から追加します。
 新たに「sd_hdp.h」という名のファイルを作成し、上記の「HardwareProfile.h」にインクルードする方法をとっています。

/*
 sd_hdp.h
*/

#define GetSystemClock()    32000000
#define GetPeripheralClock()  GetSystemClock()
#define GetInstructionClock()   (GetSystemClock() / 2)

// Clock values
#define MILLISECONDS_PER_TICK 10        
// Definition for use with a tick timer
#define TIMER_PRESCALER    TIMER_PRESCALER_8 
// Definition for use with a tick timer
#define TIMER_PERIOD      20000       
// Definition for use with a tick timer

#define USE_SD_INTERFACE_WITH_SPI

  // Description: SD-SPI Chip Select Output bit
  #define SD_CS      LATGbits.LATG9
  // Description: SD-SPI Chip Select TRIS bit
  #define SD_CS_TRIS    TRISGbits.TRISG9

  // Description: SD-SPI Card Detect Input bit
//  #define SD_CD      PORTFbits.RF0
  // Description: SD-SPI Card Detect TRIS bit
//  #define SD_CD_TRIS   TRISFbits.TRISF0

  // Description: SD-SPI Write Protect Check Input bit
//  #define SD_WE      PORTFbits.RF1
  // Description: SD-SPI Write Protect Check TRIS bit
//  #define SD_WE_TRIS   TRISFbits.TRISF1

  // Registers for the SPI module you want to use

  // Description: The main SPI control register

  #define SPICON1     SPI1CON1
  // Description: The SPI status register
  #define SPISTAT     SPI1STAT
  // Description: The SPI Buffer
  #define SPIBUF      SPI1BUF
  // Description: The receive buffer full bit in the SPI status register
  #define SPISTAT_RBF   SPI1STATbits.SPIRBF
  // Description: The bitwise define for the SPI control register (i.e. _____bits)
  #define SPICON1bits   SPI1CON1bits
  // Description: The bitwise define for the SPI status register (i.e. _____bits)
  #define SPISTATbits   SPI1STATbits
  // Description: The enable bit for the SPI module
  #define SPIENABLE    SPISTATbits.SPIEN

  // Tris pins for SCK/SDI/SDO lines

  // Description: The TRIS bit for the SCK pin
  #define SPICLOCK    TRISGbits.TRISG8
  // Description: The TRIS bit for the SDI pin
  #define SPIIN      TRISGbits.TRISG6
  // Description: The TRIS bit for the SDO pin
  #define SPIOUT      TRISBbits.TRISB4
  // Will generate an error if the clock speed is too low to interface to the card
  #if (GetSystemClock() < 100000)
    #error Clock speed must exceed 100 kHz
  #endif

 この中の

  // Description: SD-SPI Card Detect Input bit
//  #define SD_CD      PORTFbits.RF0
  // Description: SD-SPI Card Detect TRIS bit
//  #define SD_CD_TRIS   TRISFbits.TRISF0

  // Description: SD-SPI Write Protect Check Input bit
//  #define SD_WE      PORTFbits.RF1
  // Description: SD-SPI Write Protect Check TRIS bit
//  #define SD_WE_TRIS   TRISFbits.TRISF1

 の部分は例によって、PIC24USBテスト基板のSDカード回路にWE端子、CD端子がないためのコメントアウト処置です。
 WE端子、CD端子がない場合はこのほかに、「SD-SPI.c」の次のコードの変更が必要になります。

■CD端子がないとき
197行
  return(!SD_CD);
   ↓
  return(1);   //return(!SD_CD);

317行
  SD_CD_TRIS = INPUT;  //Card Detect - input
   ↓
//  SD_CD_TRIS = INPUT;   //Card Detect - input

■WE端子がないとき
320行
  SD_WE_TRIS = INPUT;   //Write Protect - input
   ↓
//  SD_WE_TRIS = INPUT;   //Write Protect - input

834行
  return(SD_WE);
   ↓
  return(0);   //return(SD_WE);

 CD端子、WE端子の有る無しに関わらず、あと必要なのは、ユーザープログラムに、次のSPIモジュールのピン割付けコードを書くことです。

  // SDOにRP28ピンを割り付ける
  POR14bits.RP28R = 7;
  // SCKにRP19ピンを割り付ける
  POR9bits.RP19R = 8;
  // SDIにRP21ピンを割り付ける
  PINR20bits.SDI1R = 21;

 *このピン割付けは下のような回路図の場合です。

画像

 これで、Microchip Memory Disk Drive File Systemはデフォルトの設定のまま使えます。


| | トラックバック (0)

2010年5月24日 (月)

SDカードのBMPファイルの液晶表示

画像

画像

 ■プロジェクト一式
   sd.lzh(284KB)

 やりかたは次のような方法をとりました。

画像

 こんな感じでまずSDカードに記憶されている「.BMP」の拡張子のついたファイルを検索、収集し、そのリストファイルを作成します。

画像

画像

 このSDカードですが、Windowsのエクスプローラーで内容を表示させるとこんな具合です。

画像

画像

画像

画像

 上記の作成したリストファイルをもとに液晶に表示をさせていきます。
 ただし、当然ながら、128X128ピクセル、16ビットカラーのZY-FGD1442701Vに表示できるBMPファイルを選別しながら表示をします。
 このBMP描画関数は、BMPファイルのヘッダー部分を取り除かなくても、128X128ピクセル(高さのほうは、横幅さえ128ピクセルであれば、何ピクセルであろうと下限から順にピクセル分だけ描画します)、16ビットカラーのBMPファイルであればZY-FGD1442701Vに描画します。逆にヘッダー部分を取り除くと描画しません。
 また、「0RRRRRGGGGGBBBBB」と「RRRRRGGGGG0BBBBB」の両方のフォーマットに対応しています。

// 関数 PhotoFrame()から呼ばれて引数のファイル名のBMPファイルをZY-FGD1442701Vに描画する関数。
int vbmp(const char * filename)
{
    FSFILE *pReadFile;
    int readsize, Ypos = 128, Xpos = 128;
    unsigned int * p;
    unsigned int i1, i2, d;
    unsigned int rgb_f;
    union bmpVAL ui;
    union bmpVAL *up = &ui;

// リードモードでファイルをオープンする。
    pReadFile = FSfopen (filename, "r");
    if (pReadFile == NULL)
    {
        return(1);
    }


// BMPファイルか否かの確認。
    readsize = FSfread((void *)up->Type, 1, 2, pReadFile);
    if(!readsize)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(3);
    }
    up->Type[2] = NULL;
    if(strcmp(up->Type,"BM"))
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(11);
    }


// 16ビットカラーか否かの確認。
    if(FSfseek(pReadFile, biBitCount, SEEK_SET ))
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(5);
    }
    readsize = FSfread((void *)up->BitCount, 2, 1, pReadFile);
    if(!readsize)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(3);
    }
    if(up->BitCount[0] != 16)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(12);
    }


// 画像の幅が128ピクセルかどうかの確認。
    if(FSfseek(pReadFile, biWidth, SEEK_SET ))
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(5);
    }
    readsize = FSfread((void *)up->Width, 4, 1, pReadFile);
    if(!readsize)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(3);
    }
    if(up->Width[0] != 128l)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(13);
    }


// 画像の高さの確認。
    if(FSfseek(pReadFile, biHeight, SEEK_SET ))
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(5);
    }
    readsize = FSfread((void *)up->Height, 4, 1, pReadFile);
    if(!readsize)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(3);
    }
    if(up->Height[0] < 128l)
    {
        Ypos = (int)(up->Height[0] & 0xffff);
        Clr_GLCD(WHITE);
    }


// 圧縮形式の読み込み(BI_RGBかBitfieldsか)と、その結果をrgb_fに格納。
    if(FSfseek(pReadFile, biCopmression, SEEK_SET ))
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(5);
    }
    readsize = FSfread((void *)up->Copmression, 4, 1, pReadFile);
    if(!readsize)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(3);
    }
    rgb_f = ((unsigned int)(up->Copmression[0] & 0xffff));


// 画像データが始まる番地のファイル先頭からのオフセット値の読み込みと、ファイルポインタのセット。
    if(FSfseek(pReadFile, VbfOffBits, SEEK_SET ))
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(5);
    }
    readsize = FSfread((void *)up->Offset, 4, 1, pReadFile);
    if(!readsize)
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(3);
    }
    if(FSfseek(pReadFile, up->Offset[0], SEEK_SET ))
    {
        if( FSfclose(pReadFile) == EOF )
            return(2);
        return(5);
    }


// 画像の表示方向をBMP形式に合わせ、左下から右方向に向って描画する表示方法にセット。
    bmp_madctl();


// VRAMの横軸、縦軸のそれぞれの始点のセットと、VRAMへの画像データの書き込み。
    Out_Cmd(CASET);
    Out_Data(0);
    Out_Data(2);
    Out_Data(0);
    Out_Data(129);
    Out_Cmd(RASET);
    Out_Data(0);
    Out_Data(03);
    Out_Data(0);
    Out_Data(130);
    Out_Cmd(RAMWR);

    for(i1 = 0; i1 < Ypos; i1++)
    {
        readsize = FSfread((void *)up->buf, 2, Xpos, pReadFile);
        if(!readsize)
        {
            normal_madctl();
            if( FSfclose(pReadFile) == EOF )
                return(2);
            return(0);
        }
        if(readsize < Xpos)
        {
            Xpos = readsize;
        }
        p = up->buf;
        for(i2 = 0; i2 < Xpos; i2++)
        {
            d = *p++;
            if(!rgb_f)   
// 圧縮形式のがBI_RGBであれば実行。
                d = ((d & 0x7fe0) << 1) | (d & 0x001f);
            Out_Data(d >> 8);
            Out_Data(d);
        }

    }
    normal_madctl();
    if( FSfclose(pReadFile) == EOF )
        return(2);
    return(0);
}


// “フォトフレーム”の実行関数。
// 引数「wait」は一枚の画像の表示時間。 ms単位。

int PhotoFrame(long wait)
{
    char fn[13];
    char dir[PATHNAME_MAX];
    unsigned int attr = 0;
    char buf[512];
    char keep_dir[PATHNAME_MAX + 10];

    while (1)
    {
        if(!FSInit())
        {
            attr++;
            if(attr > 5)
            {
                putsWord((unsigned char *)"Card not present or wrong format.\r\n");
                return(9);
            }
        }
        else
            break;
    }

    OpenFindFile_Write();
    strcpy(fn,"*.BMP");
    strcpy(dir,"\\");
    attr = ATTR_READ_ONLY | ATTR_HIDDEN
        | ATTR_SYSTEM | ATTR_VOLUME
        | ATTR_DIRECTORY | ATTR_ARCHIVE ;
    if((Dir((const char *)dir,(const char *)fn, attr, 1)))
    {
        putsWord((unsigned char *)"Errer Dir!\r\n");
    }
    CloseFindFile();

    if(FSchdir("\\") == EOF)
        return(6);
    OpenFindFile_Read();
    if(pFindFile == NULL)
        putsWord((unsigned char *)"Not open");
    while(!(fgetl(pFindFile, buf)))
    {
        char * bp;
        char * wp = buf;

        while(*wp)
            WriteLB2((unsigned char)*wp++);

        bp = strtok(buf, SEPARATORS);
        if(*bp == '\\')
        {
            if(strcmp(keep_dir,bp))
            {
                strcpy(keep_dir,bp);
            }
        }
        else
        {
            if( FSchdir(keep_dir) == EOF )
                return(6);
            vbmp(bp);
            delay_ms(wait);
        }
    }
    CloseFindFile();

    homeCSL();
    putsWord((unsigned char *)"Photo Frame");

    while(WriteUSB());

    return(0);
}

 リストファイルの内容はUSBでPCに送って表示させています。

画像

| | トラックバック (0)

2010年5月18日 (火)

テスト用のSDコネクタ

画像

 PIC24USBのテスト基板にSDカードのコネクタをつけました。とはいっても、microSDカードに付属していたプラスチック製のSDカード変換アダプタです。
 単に様々なテスト用に使うだけなのでこれで十分です。

画像

 ディレクトリやファイルの情報などをグラフィック液晶に表示させるなどのテストをおこなうつもりです。

画像

 こちらはmicroSDカードのちゃんとしたコネクタです。最近手に入れました。

画像

 これはminiUSBソケットとmicroUSBソケットです。
 USBインターフェースモジュールを内蔵したDIP28ピンのPIC24F64GB002も入手したので、その基板を作製したときに使用するつもりでいます。


画像
公園にて

| | トラックバック (0)

2008年11月17日 (月)

バージョン1.2.0でのWEやCD端子がない場合の改変のしかた

 PIC24Fをマイクロプロセッサに使用した基板のSDカードコネクタにWEやCD端子が存在しない場合、Microchip社のFATシステムのファイルの数箇所を変更する必要があり、その箇所と変更内容を『WEやCD端子がない場合の改変のしかた』で書きました。
 しかし、それはMicrochip社のFATシステムのバージョン1.0.1の場合のものでした。
 その中で記したように、現在Microchip社のWebサイトで公開されているFATシステムはバージョン1.2.0(FAT16、FAT32に対応しています)になっています。
 今回は、そのバージョン1.2.0のFATシステムでWEやCD端子が存在しないSDカードコネクタを使う場合の変更箇所を述べます。

 バージョン1.2.0では、ファイル構成もバージョン1.0.1とは一部変わっており、FATシステムを構成するのに必要なファイルが2個増えています。

 一つは¥Microchip Solutions¥Microchip¥Include にあるCompiler.h 、もう一つは¥Microchip Solutions¥MDD File System-SD Data Logger (デモ用プログラムのフォルダです)にあるHardwareProfile.h です。
 これにより、FATシステムを構成するのに必要なファイルが次のように合計9個になりました。

¥Microchip Solutions¥Microchip¥Include¥MDD File System

  FSDefs.h
  FSIO.h
  SD-SPI.h

¥Microchip Solutions¥Microchip¥Include

  Compiler.h
  GenericTypeDefs.h

 * このGenericTypeDefs.h は¥Program Files¥Microchip¥MPLAB C30¥src¥peripheral_24F¥include¥Generic.h と代替可能です。
 PIC24Fの周辺モジュールのC30のライブラリでは、各周辺モジュールがヘッダファイルでこのGeneric.h をインクルードしています。それらの各周辺モジュールのライブラリやヘッダファイルをFATシステムと一緒に使う場合、FATシステムでGenericTypeDefs.h を追加してインクルードすると、コンパイルで多重定義エラーになります。
 バージョン1.0.1のときなどは、Generic.hGenericTypeDefs.h の代替として使えず(コンパイルでエラーとなりました)、仕方なく各周辺モジュールのヘッダファイルのインクルードファイルのほうを一つ一つGenericTypeDefs.h に書き換えて(こっちのほうはOK でした)使っていました。
 Generic.h を代替に使う場合は次の各ファイルの冒頭の
#include "GenericTypeDefs.h"
 を、
#include "Generic.h"
 に変更する必要があります。

FSDefs.h
FSIO.h
SD-SPI.h
FSIO.c

¥Microchip Solutions¥MDD File System-SD Data Logger

  FSconfig.h
  HardwareProfile.h

 HardwareProfile.h の610行にある「#include

」は、FATシステムとは無関係です。デモプログラムでしか使用しないものなので削除して使って下さい。

¥Microchip Solutions¥Microchip¥MDD File System

  FSIO.c
  SD-SPI.c

 そして、それに伴い、変更箇所が一部変わり、また変更箇所の減少もおこっています。

 まず変更箇所の減少ですが、バージョン1.0.1にはあった次の箇所がバージョン1.2.0では消失しています。

 SD-SPI.h にあった
#define MediaIsPresent()       (!SD_CD)
 と、
#define MediaIsWriteProtected()       (SD_WE)
 です。

 また、そのSD-SPI.h  にあったSPI モジュールの各ピンのTRISレジスタのビット位置の設定、及びCS、CD、WEへのポートI/O の割り当て設定のコードなどが、バージョン1.2.0ではHardwareProfile.h 内に移動しています。
  したがって、SD-SPI.h における変更箇所はなくなりました。

HardwareProfile.h に移動した各設定について次に少し述べます。

 SD-SPI.h から移動したのは次の各設定です。

   #elif defined __PIC24F__
222行
      // Description: SD-SPI Chip Select Output bit
        #define SD_CS              PORTBbits.RB1
      // Description: SD-SPI Chip Select TRIS bit
        #define SD_CS_TRIS       TRISBbits.TRISB1
       // Description: SD-SPI Card Detect Input bit
        #define SD_CD              PORTFbits.RF0
      // Description: SD-SPI Card Detect TRIS bit
        #define SD_CD_TRIS       TRISFbits.TRISF0

       // Description: SD-SPI Write Protect Check Input bit
        #define SD_WE              PORTFbits.RF1
      // Description: SD-SPI Write Protect Check TRIS bit
        #define SD_WE_TRIS       TRISFbits.TRISF1

256行
       // Description: The TRIS bit for the SCK pin
       #define SPICLOCK        TRISFbits.TRISF6
       // Description: The TRIS bit for the SDI pin
       #define SPIIN                 TRISFbits.TRISF7
       // Description: The TRIS bit for the SDO pin
       #define SPIOUT             TRISFbits.TRISF8


 FATシステムを使用する際には、この222行からと256行からの定義を常に基板のPIC24Fにほどこした設定に合わせて記述する必要があります。この2箇所の定義を基板のPIC24Fの設定に合わせておかないとFATシステムが使えません。
 しかし、基板のPIC24Fの設定に合わせて書き換える箇所はこの2箇所だけで、WE、あるいはCDを使わない場合を除き、他はいっさいFATシステムのファイルを書き換える必要はありません。

 222行からの設定は、CS、CD、WEに割り当てるポートI/Oの指定です。それらに割り当てたポートI/Oのラベル名を記述します。
 * WE、あるいはCDが基板に無い場合、そのCD、WEへのポートI/Oの割り当ての定義の行を無効にする必要があります。

 256行からの定義は、 WEやCDの使用不使用にはまったく関係はありません。
 256行からの定義は、SPI モジュールの各ピンに対応するポートI/OのTRISレジスタのビット位置の指定です。
 TRISレジスタというのはポートI/Oの各ピンの入出力の方向を決めるレジスタです。FATシステムでは、PIC24FのSPI モジュール(デフォルトではSPI1のほうを使用する設定になっています)を使用してSDカードとやりとりをしますので、SPI モジュールの各ピンの位置にあたるポートI/Oはもちろん使いませんし、SPI モジュールが有効になっていれば、そもそもそのピンのポートI/Oは機能しないので使えません。
 では、なぜSPI モジュールの各ピンに対応するポートI/OのTRISレジスタの対応ビットの指定が必要になるかといいますと、『周辺内蔵モジュールと汎用I/Oの入出力の方向』で述べたように、PIC24Fは周辺モジュールを有効にして使う場合、そのモジュールの各ピンの入出力の方向と、その各ピンのポートI/Oの入出力の方向をTRISレジスタを使って一致させなければならないという原則があるからです。
 FATシステムは、イニシアライズのなかで、そのSPIモジュールの各ピンの入出力の方向と、その各ピンのポートI/Oの入出力の方向を一緒にするという処理をおこないます。しかし、その処理をおこなうには、SPI モジュールの各ピンに対応するポートI/OのTRISレジスタのビット位置の情報が必要になります。その情報をあたえるのが、上の256行からの#define 行なのです。

 これとは別に、PIC24Fの28ピンパッケージと44ピンパッケージにおけるSPI モジュールの各信号ピンの「ピン割り付け機能」の設定は、FATシステムのファイルでではなく、ユーザープログラムのほうでおこなう必要があります。
 それはmainルーチンの最初のほうで、例えば次のようにおこないます。

        // SCK にRP14ピンを割り付ける
       RPOR7bits.RP14R = 8;
       // SDI にRP13ピンを割り付ける
       RPINR20bits.SDI1R = 13;
       // SDO にRP15ピンを割り付ける
       RPOR7bits.RP15R = 7;

 この「ピン割り付け機能」の設定をした場合、PIC24Fの28ピンパッケージでは、256行からの#define の行は次のようになります。

        #define SPICLOCK        TRISBbits.TRISB14
        #define SPIIN                TRISBbits.TRISB13
        #define SPIOUT             TRISBbits.TRISB15


 WE、あるいはCDがない場合の改変はバージョン1.2.0では2個のファイル

 バージョン1.2.0で、WE、あるいはCDがない基板の場合に改変が必要になるのはSD_SPI.cHardwareProfile.h2つのファイルになります。

 ■HardwareProfile.h の変更箇所

 上記の次の行を「//」を行頭に追加してコメント化して無効にします。

 ・WEがない場合

 233行
        #define SD_WE              PORTFbits.RF1
 235行
        #define SD_WE_TRIS       TRISFbits.TRISF1

 ・CDがない場合

 228行
        #define SD_CD              PORTFbits.RF0
 230行
        #define SD_CD_TRIS       TRISFbits.TRISF0

 ・WEもCDもない場合

 228行
        #define SD_CD              PORTFbits.RF0
 230行
        #define SD_CD_TRIS       TRISFbits.TRISF0
 233行
        #define SD_WE              PORTFbits.RF1
 235行
        #define SD_WE_TRIS       TRISFbits.TRISF1


 ■SD_SPI.c の変更箇所

 まず、

void MDD_SDSPI_InitIO (void)
{

     // Turn off the card
    SD_CD_TRIS = INPUT;          //Card Detect - input
    SD_CS = 1;                        //Initialize Chip Select line
    SD_CS_TRIS = OUTPUT;     //Card Select - output
    SD_WE_TRIS = INPUT;        //Write Protect - input
}

 という関数の次の箇所を「//」を行頭に追加してコメント化して無効にします。

 ・WEがない場合
 260行
    SD_WE_TRIS = INPUT;           //Write Protect - input

 ・CDがない場合
 257行
    SD_CD_TRIS = INPUT;           //Card Detect - input

 ・WEもCDもない場合
 257行
    SD_CD_TRIS = INPUT;           //Card Detect - input
 260行
    SD_WE_TRIS = INPUT;           //Write Protect - input

 次にWEがない場合、771行から始まる次の関数の

BYTE MDD_SDSPI_WriteProtectState(void)
{
    return(SD_WE);
}

    return(SD_WE);
 というコードを、
    return(0);
 に変更します。

 次にCDがない場合、174行から始まる次の関数の

BYTE MDD_SDSPI_MediaDetect (void)
{
    return(!SD_CD);
}
//end MediaDetect

    return(!SD_CD);
 を
    return(1);
 に変更します。


 WEとCD関連における変更箇所は以上です。
 変更は、各ファイルの「SD_WE」と「SD_CD」という定義などを、存在しない場合には無効にしているだけです。
 FATシステムのバージョンアップがおこなわれても、やることは同じです。
 各ファイルで「SD_WE」と「SD_CD」を検索し、同じような処理をすればいいと思います。ただし、仕様などが変更され、ワードなども変わる場合があるかもしれません。そのあたりは注意が必要です。
 ちなみに、上記のプログラム中
 BYTE MDD_SDSPI_WriteProtectState(void)
 と
 BYTE MDD_SDSPI_MediaDetect (void)
 は、関数としては用意されていますが、FATシステムとして使用されていません。
 この2つの関数(WE端子とCD端子の状態の値を返す)は、ユーザーに使用が任されています。つまり、アプリケーションでSDカードのWEとCDの状態をチェックするかどうかは、ユーザーの自由裁量条項になっています。

 一方、
 void MDD_SDSPI_InitIO(void)
 については、SDカードをマウントするint FSInit(void) という大事な関数の中で使われています。


 システムクロック周波数の指定

 ところで、MicrochipのFATシステムではボードのマイクロプロセッサのシステムクロック周波数を指定する仕様になっています。
 HardwareProfile.h の50行めの次のところです。

// Sample clock speed for a 16-bit processor(void)
#elif defined (__C30__)(void)

    #define GetSystemClock()        32000000

 この「32000000」の箇所をマイクロプロセッサのシステムクロック周波数の値にする必要があります。
 PIC24Fの場合、「100000」(100kHz)から下はエラーとなり、FATシステムは使えません。


 FAT32のサポート

 FAT32のサポートの有効化はFSconfig.h の次の行でおこないます

98行
#define SUPPORT_FAT32

 FAT16、あるいはFAT12しか使わないのであれば、行頭に「//」を追加しコメント化してFAT32のサポートを無効にします。
 デフォルトでは有効になっています。

参考:

     ●FAT32のサポートが有効のとき


     ●FAT32のサポートを無効にしたとき




 同時に開くことができるファイルの最大数

 同時に開くことができるファイルの最大数はFSconfig.h の次の行で指定します。

47行
#define FS_MAX_FILES_OPEN         3

参考:

     ●ファイル最大数が「3」のとき


     ●ファイル最大数が「6」のとき




 FATシステムのファイルをデモプログラム以外で使用する際の注意点

 次のインクルードファイルのパス名の「MDD File System¥」の部分は、デモプログラム以外で実際に使用する際には適宜削除するか、使用ディレクトリ構成などに合わせてください。そうしないとコンパイルエラーになります。

【FSIO.h】
#include "MDD File System¥FSDefs.h"

#ifdef USE_SD_INTERFACE_WITH_SPI
    #include    "MDD File System¥SD-SPI.h"


【FSIO.c】
#include "MDD File System¥FSIO.h"
#include "MDD File System¥FSDefs.h"


【SD-SPI.h】
#include "MDD File System¥FSDefs.h"

【SD-SPI.c】
#include "MDD File System¥FSIO.h"
#include "MDD File System¥FSDefs.h"
#include "MDD File System¥SD-SPI.h"

 また、HardwareProfile.h の610行にある
#include
 は、FATシステムとは無関係です。デモプログラムでしか使用しないものなので削除してから使って下さい。


 WEもCDもない基板でのテスト


画像

 上記の「WEもCDもない場合」の全ての処理をほどこしたFATシステムファイルで、FAT32サポートも有効にして基板で1GBのmicroSDメモリのテストをおこないました。

 次の画面は前に紹介したfind_f.c で、基板のmicroSDメモリのルートディレクトリだけを検索、Windows のハイパーターミナルで表示させたものです。引数の最後の値の「0」を「1」にすると、サブディレクトリも全て検索、表示をしますが、ディレクトリとファイルの数が多いのでルートディレクトリだけにしています。(クリックで拡大表示します)

画像

 次の画面は、そのmicroSDメモリを基板から抜き、PCのSDカードリーダーでリムーバルディスクとして認識させて、Windows XP のファイルマネージャのエクスプローラで内容を表示させたものです。(クリックで拡大表示します)

画像







| | トラックバック (0)

2008年11月 8日 (土)

ボードのSDカードのファイルやディレクトリを表示させる

 紹介するDir関数(<find_f.c>の中にサブ関数も含め収録)は、Microchip社のFATシステムが組み込まれたPIC24F基板のSDカードのファイルやディレクトリを検索し、ヒットしたファイルやディレクトリをPCのハイパーターミナルなどで表示させる関数です。

■ダウンロード
find_f.lzh (3KB)

 表示には、C30コンパイラのライブラリのprintf関数を使っています。
 C30コンパイラはprintf関数の出力先をデフォルトでUART1に設定しており、PIC24FのUART1をアクティブにしRS232CでPCと接続すれば、即ハイパーターミナルなどで表示がおこなえます。これはデバッグでもけっこう重宝する機能です。

 趣味のマイコンボードの表示機器は2行か4行程度のLCDである場合が多いと思うので、SDカードのファイルやディレクトリの表示などは多くの場合情報量が多すぎ、あまり意味がないものと思います。だから、このプログラムの用途は、SDカードのボードテストなどにおける確認用です。

 ただ、検索でヒットしたファイルやディレクトリの名前の表示は、次のそれぞれのサブ関数でおこなっています。

void find_File( SearchRec *rec, const char *dir)
void find_Dir( SearchRec *rec, const char *dir)


 絶対パス名も引数「const char *dir」で渡しているので、このサブ関数の内容を変えることで、ヒットしたファイルやディレクトリを名前の表示ではなく、削除など他の処理にも使えるようになっています(その場合は、単なる検索ディレクトリの名前の表示に使われている「search_Dir(dir, c++);」の行は、消して下さい)。

 ちなみに、「SearchRec *rec」はFATシステムのライブラリのFindFirst関数及びFindNext関数が、ヒットしたファイル、またはディレクトリの情報を格納する構造体「SearchRec」へのポインタです。その内容は次のようになっています。

typedef struct
{
  // User accessed values
  char filename[FILE_NAME_SIZE + 2];  // File name
  unsigned char attributes;  // The file's attributes
  unsigned long filesize;  // Size of the file
  unsigned long timestamp;  // File's create time
  // For internal use only
  unsigned int entry;  // The file entry
  char searchname[FILE_NAME_SIZE + 2];  // Search string
  unsigned char searchattr;  // The search attributes
  unsigned int cwdclus;  // The cwd for this search
  unsigned char initialized;  // Check for if FindFirst was called
} SearchRec;

(MicrochipのFATシステムの<FSIO.h>より)

 Dir関数自体の使い方については、find_f.c のDir関数の説明のところを読んで下さい。

 この find_f.c の中の関数は、find_f.c と find_f.h をMPLABのプロジェクトに追加し、find_f.h をインクルードすれば使えます。

-------------------------------------

 次にDir関数の検索のいくつかの例を参考までにあげておきます
 「結果」という文字に貼られているリンクは、ハイパーターミナルでの表示画像へのリンクです
 FSInit()はSDカードのマウント処理をするFATシステムのライブラリ関数です。失敗で「0」を返します。簡易的にwhile文を使っていますが、通常はリトライ回数を決めて、失敗が続けばエラーリターンするようにします。Microchipのデモプログラムではリトライは10回になっていました。
 FSInit()ではCDやWEのチェックはおこなっていません。FSInit()に限らず、MicrochipのFATシステムではCDやWEのチェックはユーザーに全て任されており、システム側では関知しません。したがって、CD端子やWE端子がないSDコネクタでも、FATシステムの各ファイル関数は問題なく使用ができます。


PCで認識させた時のSDカードのディレクトリ構造
画像
 (クリックすると拡大します)

 *半角の「¥」記号はブログでは表示されないので、全角で表記しています。
   ちなみに「¥¥」はルートディレクトリです。

■A

   while (!FSInit());
   strcpy(fn,"FILE?.TXT");  // 検索をする対象
   strcpy(dir,"¥¥");        // 検索する場所(ディレクトリ)
   attr = ATTR_READ_ONLY | ATTR_HIDDEN
          | ATTR_SYSTEM | ATTR_VOLUME
          | ATTR_DIRECTORY | ATTR_ARCHIVE ; //検索をするファイルやディレクトリの属性の指定
   Dir((const char *)dir,(const char *)fn, attr, 1);

  結果


■B

   while (!FSInit());
   strcpy(fn,"IBM*.*");
   strcpy(dir,"¥¥");
   attr = ATTR_READ_ONLY | ATTR_HIDDEN
          | ATTR_SYSTEM | ATTR_VOLUME
          | ATTR_DIRECTORY | ATTR_ARCHIVE ;
   Dir((const char *)dir,(const char *)fn, attr, 1);

  結果


■C

   while (!FSInit());
   strcpy(fn,"*.C");
   strcpy(dir,"¥¥");
   attr = ATTR_READ_ONLY | ATTR_HIDDEN
          | ATTR_SYSTEM | ATTR_VOLUME
          | ATTR_DIRECTORY | ATTR_ARCHIVE ;
   Dir((const char *)dir,(const char *)fn, attr, 1);

  結果


■D

   while (!FSInit());
   strcpy(fn,"TWO");
   strcpy(dir,"¥¥");
   attr = ATTR_READ_ONLY | ATTR_HIDDEN
          | ATTR_SYSTEM | ATTR_VOLUME
          | ATTR_DIRECTORY | ATTR_ARCHIVE ;
   Dir((const char *)dir,(const char *)fn, attr, 1);

  結果


■E

   while (!FSInit());
   strcpy(fn,"*.*");
   strcpy(dir,"¥¥");
   attr = ATTR_READ_ONLY | ATTR_HIDDEN
          | ATTR_SYSTEM | ATTR_VOLUME
          | ATTR_DIRECTORY | ATTR_ARCHIVE ;
   Dir((const char *)dir,(const char *)fn, attr, 0);

  結果


■F

   while (!FSInit());
   strcpy(fn,"*.*");
   strcpy(dir,"¥¥");
   attr = ATTR_READ_ONLY | ATTR_HIDDEN
          | ATTR_SYSTEM | ATTR_VOLUME
          | ATTR_DIRECTORY | ATTR_ARCHIVE ;
   Dir((const char *)dir,(const char *)fn, attr, 1);

  結果


■G

   while (!FSInit());
   strcpy(fn,"*.*");
   strcpy(dir,"¥¥ONE¥¥TWO¥¥THREE¥¥FOUR");
   attr = ATTR_READ_ONLY | ATTR_HIDDEN
          | ATTR_SYSTEM | ATTR_VOLUME
          | ATTR_DIRECTORY | ATTR_ARCHIVE ;
   Dir((const char *)dir,(const char *)fn, attr, 1);

  結果







| | トラックバック (0)

2008年11月 7日 (金)

SDカードコネクタのピン配列

 CDとWE

 CD端子(カード検出端子)とWE端子(ライトイネーブル検出端子)はSDカード本体の電子回路には接続されていません。SDカードコネクタの筐体の金属部分と接点スイッチで「スイッチ回路」を構成しているだけです。
 このCD端子とWE端子には、GNDに接地するか、あるいはVDDに抵抗を介して接続するもう一方の端子が存在し、CD端子の場合、SDカードがコネクタに挿入されると、そのもう一方の端子とCD端子との回路が「オープン」になるか「クローズ」になるかによって、信号の状態変化が生じるようになっています。それが検出スイッチとしての役割をはたします。
 WE端子の場合もCD端子と同様で、SDカード側のライトプロテクトのスライドスイッチの位置によって、WE端子ともう一方の端子との回路が「オープン」になるか「クローズ」になるかし、ライトプロテクトの有無の検出をします。

 Microchip社のFATシステムのCDとWEの論理はアクティブ・ロー

 Microchip社のFATシステムのCDとWEはアクティブ・ローの論理でプログラムが作られています。
 つまり、SDカードがコネクタに挿入されている状態では、CD端子の信号レベルはローになっていなければなりません。
 また、SDカードのライトプロテクトがOFFの場合、コネクタのWE端子の信号レベルはローになっていなければなりません。

 コネクタのCD端子のスイッチ回路がSDカードの挿入によって「クローズ」の状態になるコネクタの場合は、スイッチ回路のもう一方の端子はGNDに接続します。またPICとの信号線はプルアップ抵抗をつけてVddに接続します。
 SDカードの挿入によって「オープン」の状態になるコネクタの場合は、上記のSDカードの挿入によって「クローズ」の状態になるものと同じ処理をして、SDカードコネクタとPICとの間にインバータを入れます。ソフトウェア側を変更するという選択肢もあります。

【ソフトを変更する場合】

 「 SD-SPI.c 」ファイルの130行目の
return( !SD_CD); を、
return( SD_CD); とします。

 そして「 SD-SPI.h 」ファイルの422行目の
#define MediaIsPresent()        ( !SD_CD)
 を、
#define MediaIsPresent()        ( SD_CD) とします。


 これらはWE端子の場合も同じです。
 ちなみに、スイッチ回路のもう一方の端子はCD、WEの両者が併用をする共通端子となっています。


 Microchip社のFATシステムで使われるSDカード本体の端子

 PIC    SDカード本体
 I/O ──(1)DAT3 / CS
 SDO ──(2)CMD / DI
 GND ──(3)Vss1
 3.3V ──(4)Vdd
 SCK ──(5)CLK
 GND ──(6)Vss2
 SDI ──(7)DAT0 / DO

 *()内の数字はSDカード本体のピン番号)



 コネクタの製品別ピン配列

■ヒロセSDカードコネクタ[DM1B-DSF-PEJ] (秋月電子)
http://akizukidenshi.com/catalog/g/gC-01865/

 まずヒロセ電機製のSDカードコネクタ【DM1B-DSF-PEJ】のピン配列です。
 このSDカードコネクタはリバースタイプで、スタンダードタイプとはピンの配列が逆になっています。
 製品番号の「DM1B」の「B」がリバースタイプの識別記号で、ここが「A」となっているのがスタンダードタイプのコネクタです。ヒロセ電機製のコネクタはこの識別表記で統一されているようです。
 次の写真はコネクタの底面側(半田付けする際に基板側になるほう)です。

 9 DAT2
 1 DAT3 / CS
 2 CMD  / DI
 3 Vss1
 4 Vdd
 5 CLK
 6 Vss2
 7 DAT0 / DO
 8 DAT1

 「SDコネクタ」なので、CD端子とWE端子を備えています。

 CD端子とWE端子は、8番ピンに続いて写真右側方向にCD、WEという順に並んでいます。ピンの間隔が少し狭くなっています。
 CD端子とWE端子のスイッチ回路の共通端子は印のところです。

 このヒロセSDカードコネクタ[DM1B-DSF-PEJ]のCDとWEの回路は次のとおりです。


 (データシートより)

 ちなみに、スタンダードタイプの[DM1A-DSF-PEJ]は、コネクタ上のCDとWEの端子の位置がまったく違います。


■SDカード・スロット  (秋月電子)
http://akizukidenshi.com/catalog/g/gC-00753/

 このSDコネクタはスタンダードタイプです。
 次の写真はコネクタの底面側(半田付けする際に基板側になるほう)です。

 8 DAT1
 7 DAT0 / DO
 6 Vss2
 5 CLK
 4 Vdd
 3 Vss1
 2 CMD  / DI
 1 DAT3 / CS
 9 DAT2

 SDコネクタなので、CD端子とWE端子を備えています。

 CD端子とWE端子は、8番ピンに続いて写真左側方向にCD、WEという順に並んでいます。こちらもピンの間隔が少し狭くなっています。
 CD端子とWE端子のスイッチ回路の共通端子は端子の形としては用意されていず、筐体の金属製シャシーがその共通端子のかわりになっています(こういう場合、基板取り付け時には普通この金属シャシーをGNDに接地します)。

 CDとWEは電気回路としては上記のヒロセSDカードコネクタ[DM1B-DSF-PEJ]と同じで、CDはカード挿入時に「クローズ」、WEはライトプロテクトOFF時に「クローズ」となります。


■ヒロセminiSDカードコネクタ[DM2A-SFW-PEJ-S] (秋月電子)
http://akizukidenshi.com/catalog/g/gC-02326/

 このminiSDコネクタはスタンダードタイプです。
 10番ピンと11番ピンは使用されません。
 次の写真はコネクタの底面側(半田付けする際に基板側になるほう)です。

 8 DAT1
 7 DAT0 / DO
 6 Vss2
 5 CLK
 4 Vdd
11 NC
10 NC
 3 Vss1
 2 CMD  / DI
 1 DAT3 / CS
 9 DAT2

 miniSDコネクタなのでWE端子はありません。
 CD端子は8番ピンの横にあります。

 CD端子とスイッチ回路を組むもう一方の接続端子は印のところです。

 このヒロセminiSDカードコネクタ[DM2A-SFW-PEJ-S]のCDの回路は次のとおりです。
 カード挿入時に「オープン」になる仕様です。

 (データシートより)


■最後にmicroSDに付属するプラスチック製のminiSDアダプターのピン配列です。

 8 DAT1
 7 DAT0 / DO
 6 Vss2
 5 CLK
 4 Vdd
11 NC
10 NC
 3 Vss1
 2 CMD  / DI
 1 DAT3 / CS
 9 DAT2

 これはmicroSDをminiSDコネクタで使うための単なるアダプタ品なので当然miniSDコネクタにはあるCD端子などもありません。



















| | トラックバック (0)

2008年11月 6日 (木)

SPI モジュールへのピンの割り付け

 PIC24Fシリーズの28ピンと44ピンのものには(DIP版は28ピンのみです)「ピン割り付け機能」というのがあります。
 限られたピン数に、内蔵モジュールを自由に割り当てられるようにとの配慮からのようです。
 割り付けが可能な内蔵モジュールは、アナログ入力、I2C、RTCC出力(アラームパルス出力、または秒パルス出力)、状態変化割り込み入力以外のデジタルのモジュールです。また割り当てることができるピンは<RPn>(nは数字)です。

 Microchip社のFATシステムはSDとのアクセスをSPI による通信でおこないます。

 PIC24FのSPI のモジュールは2チャンネルありますが、2チャンネルともピン割り付け機能の対象です。

 このピン割り付けの対象になっているモジュールは、ピン割り付けの設定をおこなわないうちはピン位置が不定です。

 SDとのアクセスは次の4本の信号線でおこなわれますが、CS(チップセレクト)だけはSPI モジュールではなく、ポートI/Oのなかの任意の一つを割り当てて使用します。(SDカードの検出をおこなうCDと、ライトプロテクトスイッチのON-OFFの検出をおこなうWEもポートI/Oのなかの任意の一つをそれぞれ割り当てます)

 I/O ── CS / DATA3 (1)
 SDO ── CMD / DI   (2)
 SCK ── CLK      (5)
 SDI ── DO / DATA0 (7)

 
*()内の数字はSDカード本体のピン番号)

 したがって、SDにつなぐSPI モジュールの各信号のピン割り付けと、CS、WE、CDへのポートI/Oの割り当て(ポートI/Oは「ピン割り付け機能」の対象にはなっていずピンの位置は固定されています)をプログラムの中で設定をする必要があります。

 SPI モジュールの各信号ピンの割り付け設定については、FATシステムではなく、ユーザープログラムの中で、例えばつぎのように設定します。

// SCKにRP14ピンを割り付ける
RPOR7bits.RP14R = 8;
// SDIにRP13ピンを割り付ける
RPINR20bits.SDI1R = 13;
// SCOにRP15ピンを割り付ける
RPOR7bits.RP15R = 7;

 それとは別に、そのSPI モジュールの各ピンに対応するポートI/OのTRISレジスタのビット位置の指定、及びCS、WE、CDへのポートI/O の割り当て設定は「 SD-SPI.h 」ファイルの次の項目でおこないます(該当する行を赤色で表示)。

/****************************************/
/*  Pin and register definitions   */
/****************************************/

#define SD_CS        PORTBbits.RB1
#define SD_CS_TRIS    TRISBbits.TRISB1
#define SD_CD        PORTFbits.RF0
#define SD_CD_TRIS    TRISFbits.TRISF0
#define SD_WE        PORTFbits.RF1
#define SD_WE_TRIS    TRISFbits.TRISF1

// Registers for the SPI module you want to use
#define SPICON1       SPI1CON1
#define SPISTAT       SPI1STAT
#define SPIBUF        SPI1BUF
#define SPISTAT_RBF   SPI1STATbits.SPIRBF
#define SPICON1bits   SPI1CON1bits
#define SPISTATbits   SPI1STATbits

// Tris pins for SCK/SDI/SDO lines
#define SPICLOCK      TRISFbits.TRISF6
#define SPIIN        TRISFbits.TRISF7
#define SPIOUT       TRISFbits.TRISF8

 これらのうち、

#define SD_CD        PORTFbits.RF0
#define SD_CD_TRIS    TRISFbits.TRISF0
#define SD_WE        PORTFbits.RF1
#define SD_WE_TRIS    TRISFbits.TRISF1

 については『WEやCD端子がない場合の改変のしかた』で書いたようにCDやWEを使わない場合はコメント行化して無効化するので、そのときは設定をする必要はありません。

 「ピン割り付け機能」の設定の仕方については後閑哲也氏のサイト「PIC24FのI/Oピン割り付け」か、データシート、あるいは次の後閑哲也氏の書籍などを参考にしてください。

 ・『 C言語ではじめる「PIC24F活用ガイドブック」』(技術評論社 後閑哲也著)

 この書籍はPIC24Fシリーズを使う場合には是非購入しておきたいものです。僕も最初は本代をケチろうとネットで調べるつもりでこの書籍の購入を見合わせたのですが、この本を読まないとわからないこともあり、現時点では必須の参考資料といえそうです。

 ちなみに、PIC以外のマイクロコントローラなどでSDをFATシステムで使いたい人は、次のサイトが参考になります。またこのサイトはSDそのものを理解するのにも大いに役立つことが書いてあるので、是非一度読んでみてください。

 ・ELM - MMCの使いかた






| | トラックバック (0)

FSIO.c のincludeファイル、ヒープ領域、ファイルのタイムスタンプのことなど

 FSIO.cの42行から始まる次のincludeファイルの名称で、「MDD File System」が加わっているものは「MDD File System」の部分を削除しておきましょう。

#include "MDD File SystemFSIO.h"
#include INCLUDEFILE
#include "GenericTypeDefs.h"
#include "string.h"
#include "stdlib.h"
#include "ctype.h"
#include "MDD File SystemFSDefs.h"

 でないとインクルードファイルが見つからないとしてエラーがずらっと並ぶことになります。

#include "FSIO.h"
#include INCLUDEFILE
#include "GenericTypeDefs.h"
#include "string.h"
#include "stdlib.h"
#include "ctype.h"
#include "FSDefs.h"

 FATシステムをプログラムで使用するときは、コンパイルの前にMPLABの Project -> Build Option -> Projectで表れるダイアログで、「MPLAB LINK30」というタブをクリックしてHeap sizeにヒープ領域のバイト数を設定する必要があります。

 開くファイル一つにつき40バイトが必要になるようです。


 

 また同時に開くことができるファイルの数の上限は、FSconfig.h の

#define FS_MAX_FILES_OPEN       3

 で設定できます。

 ヒープ領域はFATシステムを使わないプログラムでも、printf 関数などを使うと必要になります。

 printf 関数の出力先はデフォルトでUART 1 になっていて、RS232CでPCと接続すれば、ハイパーターミナルなどで表示させることができます。


 RTCCの日付け時間データを自動的にファイルのタイムスタンプに使うための前処理

 ちなみに、ファイルのタイムスタンプに使う日付け時間のデータをファイルシステムのなかでリアルタイムクロック(RTCC)から自動的に取得して記録するようにするためには、FSconfig.h の次の定義をアクティブにしておくことが必要です。

#define USEREALTIMECLOCK

 あとの次の二つはコメント化させて無効化しておきます。

//#define USERDEFINEDCLOCK
//#define INCREMENTTIMESTAMP

 USERDEFINEDCLOCKはプログラマがプログラムで何らかの方法で日付け時間データを取得し(もちろんRTCCから取得してもいい)タイムスタンプの日付け時間データをセットする関数のSetClockVars()を使って手動で値をセットする場合にアクティブにします。







| | トラックバック (0)

2008年11月 5日 (水)

WEやCD端子がない場合の改変のしかた

 Microchip社のFATシステムのプログラムファイルのダウンロードは次のMicrochip社のページからおこないます。

File I/O Functions Using Microchip's Memory Disk Drive File System Library

 
(注:以下の記述はバージョン 1.0.1の場合です。しかし、バージョンが変わっても、修正箇所はあまり変わらないと思われますので、そのあたりは臨機応変で対処して下さい)

 ページの下のほうのAN1045 Source CodeというのがFATシステムのプログラムファイルです。(現在はMicrochip MDD File System 1.2.0 Installer.exeという実行ファイル)
 ダウンロードしそのファイルをクリックすると、CドライブにMicrochip Solutionsというディレクトリが作られ、そこにFATシステムのプログラムファイルやデータシートなどが展開され置かれます。

 SDまたはminiSD、microSDの実際のプログラミングで必要なのは以下のファイルです。


¥Microchip Solutions¥Microchip¥Include¥MDD File System

  FSDefs.h
  FSIO.h
  SD-SPI.h

¥Microchip Solutions¥Microchip¥Include

  GenericTypeDefs.h

¥Microchip Solutions¥MDD File System-PIC24-SD-StatMem-RTCC

  FSconfig.h

¥Microchip Solutions¥Microchip¥MDD File System

  FSIO.c
  SD-SPI.c


 ANSI C準拠の各ファイル関数のリファレンスなどものっているデータシートは次のディレクトリです。

¥Microchip Solutions¥Microchip¥MDD File System¥Documentation

 01045a.pdf



 WE端子のないコネクタの場合の改変

 まず、WE端子が存在しないminiSD及びmicroSDのコネクタの場合です。
 次のように改変します。

 ■「 SD-SPI.c 」ファイル

 196行の
        SD_WE_TRIS = INPUT;
 を、

//        SD_WE_TRIS = INPUT;

 のように、//を行頭に加えてコメント行化して無効化します。

    (1) ──改変の行を
緑色で表示
   void InitIO (void)
    {
        // Turn off the card
        MMC_OFF;
        SD_CD_TRIS = INPUT;            //Card Detect - input
        SD_CS = 1;                     //Initialize Chip Select line
        SD_CS_TRIS = OUTPUT;            //Card Select - output
//        SD_WE_TRIS = INPUT;            //Write Protect - input
    }



 669行の
        return(SD_WE);
 をコメント行化して無効化し、次の一行を追加します。

        return(0);

    (2)
    BYTE WriteProtectState(void)
    {
    //        return(SD_WE);
        return( 0 );

    }



 ■「 SD-SPI.h 」ファイル

 次の55行と56行をコメント行化して無効化します

#define SD_WE        PORTFbits.RF1
#define SD_WE_TRIS        TRISFbits.TRISF1

    (3)
    #define SD_CS        PORTBbits.RB1
    #define SD_CS_TRIS        TRISBbits.TRISB1
    #define SD_CD        PORTFbits.RF0
    #define SD_CD_TRIS        TRISFbits.TRISF0
    //#define SD_WE         PORTFbits.RF1
    //#define SD_WE_TRIS        TRISFbits.TRISF1



 423行の
#define MediaIsWriteProtected()        (SD_WE)
 の値のほうを次のように書きかえます。

#define MediaIsWriteProtected()        (0)

    (4)
    #define MediaIsPresent()        (!SD_CD)
    #define MediaIsWriteProtected()        (0)


 以上です。


 CD端子もWE端子もない場合、あるいは使わない場合の改変

 ■「 SD-SPI.c 」ファイル

 130行の
        return(!SD_CD);
 をコメント行化して無効化し、次の一行を追加します。

        return(1);

    (1)
    BYTE MediaDetect()
    {
    //        return(!SD_CD);
        return(1);

    }//end MediaDetect



 193行と196行の次の行をコメント行化して無効化します。
    SD_CD_TRIS = INPUT;
    ・
    SD_WE_TRIS = INPUT;

    (2)
    void InitIO (void)
    {
        // Turn off the card
        MMC_OFF;
    //        SD_CD_TRIS = INPUT;      //Card Detect - input
        SD_CS = 1;               //Initialize Chip Select line
        SD_CS_TRIS = OUTPUT;     //Card Select - output
    //          SD_WE_TRIS = INPUT;      //Write Protect - input
    }



 669行の
        return(SD_WE);
 をコメント行化して無効化し、次の一行を追加します。

        return(0);

    (3)
    BYTE WriteProtectState(void)
    {
    //        return(SD_WE);
        return( 0 );

    }




 ■「 SD-SPI.h 」ファイル

 53行から56行まで次の行を全てコメント行化して無効化します

#define SD_CD        PORTFbits.RF0
#define SD_CD_TRIS        TRISFbits.TRISF0
#define SD_WE        PORTFbits.RF1
#define SD_WE_TRIS        TRISFbits.TRISF1

    (4)
    #define SD_CS        PORTBbits.RB1
    #define SD_CS_TRIS        TRISBbits.TRISB1
    //#define SD_CD        PORTFbits.RF0
    //#define SD_CD_TRIS        TRISFbits.TRISF0
    //#define SD_WE        PORTFbits.RF1
    //#define SD_WE_TRIS        TRISFbits.TRISF1



 422行の
#define MediaIsPresent()        (!SD_CD)
 の値のほうを次のように書きかえます。

#define MediaIsPresent()        (1)

 また423行の
#define MediaIsWriteProtected()        (SD_WE)
 の値のほうを次のように書きかえます。

#define MediaIsWriteProtected()        (0)

    (5)
    #define MediaIsPresent()        (1)
    #define MediaIsWriteProtected()        (0)


 以上です。







| | トラックバック (0)

Microchip社の「FATファイルシステム」が想定するコネクタ

 基板のminiSDのアダプターのヘタな半田づけの所は、「強靭な乾燥皮膜ができる」と説明書にあるスプレー型の絶縁コーティング剤を塗布し、ちょっと補強をしてあります。

 そういえば、その昔、トヨタのセリカがオートクルーズの不具合で暴走をするという欠陥のリコールがありました。オートクルーズの制御基板の半田づけに一箇所ヒビが入るという製作途上での不良がその原因でした。基板の半田づけは自動機でおこなわれていて、同じ症状の基板が沢山作られて出荷されてしまったのです。

 閑話休題。
 ところで、Microchip社の「FATファイルシステム」はハードウェアとして「SDカード」コネクタ(この「SDカード」とは、microSD、miniSD、SDと区別されているうちのSDのこと)を想定してソフトが書かれています。
  SDのコネクタと、microSD及びminiSDのコネクタの違いは(Microchip社の「FATファイルシステム」において違いが問題となるものですが)、SDカードコネクタにはあるライトプロテクト(WE端子)の機構がmicroSD、miniSDのコネクタにはないことです。
 コネクタのもう一つの機構の、カードが挿入されているかどうかを判別する(CD端子)ほうはmicroSD、miniSDとも備わっています。とはいえ、そのCD端子の作られかたは、コネクタの製造メーカーによって、また同じメーカーでも種別の違いで方式がまちまちです。データシートを参照して図を見てもいまいちわかりにくいです。それで、前に紹介したコネクタの場合を、各信号端子の名称とともに、そのWEとCDの端子を一つ一つ写真で後に説明します。

 ともあれ、microSD、miniSDのコネクタで作る場合は、ソフトウェアのほうを改変するか、ハードウェアのほうを工夫する必要があります。

 ソフトを改変するといっても数ヵ所ちょっと変えるだけで、すぐ済んでしまいます。
 ハードのほうで対処する場合は、カードコネクタとは別にスイッチを一つ基板に作って、そこに本来ならSDカードコネクタのWE端子につながる信号線をつなげば済みます。

 ちゃんとしたコネクタではなく、microSDに付属するminiSDアダプターなどの場合は、CD端子のほうもありません。しかし、この場合も対処はあまりかわりません。けれど、ハードウェアのほうで工夫するということはせず、それより、WEとCDの二つの信号線を省略できるということをかえってメリットとしてとらえ、ソフトウェアのほうで対処しています。PIC24FのDIPタイプは端子数が少ないのでメリットは大きいです。

 次回はWE端子がないmicroSD、miniSDの場合、またはCD端子もないものの場合の、Microchip社の「FATファイルシステム」のC言語のプログラムの改変個所と改変のしかたを説明します。









| | トラックバック (0)

より以前の記事一覧