« 細々と改善は続く | メイン | SWRグラフをSDカードへセーブ »

2015年9月17日 (木)

PICマイコンからSDカードへのファイル書き込み

<カテゴリー:PICマイコン

LCD表示のアンテナアナライザーの自作の中で、周波数対SWRのグラフを描かせるところまで成功しました。 そこで、このグラフをPCに取り込めないか、試行錯誤しておりました。 そして、やっと、PICマイコンでSDカードにファイルを書き込む事が出来るようになりました。 まだ、数行のテキストデータしかないファイルを書き込んだだけで、グラフデータは未完成ですが、ここまで、出来ると、後は時間の問題となります。

今回は、PICマイコンからFAT32のファイルシステムでフォーマットされたSDカードにテキストファイルを書き込む方法を紹介します。

ハードの構成です。 アンテナアナライザーのハードに秋月で売っているSDカードソケットを接続した、単純な回路となっております。

Pic_sd_schema

 検討するソフトもこのSDカードの部分のみで、LCD表示は実装していません。

秋月から「SDカードスロットDIP化モジュール」という名前のソケットを買ってきて、これを配線図のごとく、マイコンの空きピンに接続します。PIC24FJ128GB106はi/o設定が自由にできますので、このような場合、非常に便利です。

Sd_card0そして、左の画像のごとく実装しました。

この状態でSDカードをドライブするソフトはMicrochipが無償で提供しているfileioというアプリケーションを使います。

このアプリの説明を読んでいると、私のようにC言語のポインターもまともに扱えない者でもなんとかPCで読めるファイルを書き込めるかも知れないと思うようになりました。

しかし、これが間違いの始まりで、検討を開始してからすでに1か月。 やっとのことで、FAT32のファイルシステム上に自作のファイルを書き込む事に成功しました。

Pic_fat32file0 上はエクスプロラーでSDカード内のファイルを表示させたものです。

Sample long file name.txtはデモプログラムが見本として作成したファイルです。

SWR12345.txtは私が作ったファイルです。 いずれも2行、20文字くらいのファイルですが、ファイルの中身は、これから好きに変更できます。

ここまで出来るまでの工程を以下説明します。

MicrochipのサイトからMLAと言われるアプリケーションファイルをダウンロードし、デフォルトの設定のままインストールします。 私がインストールしたファイル名は以下の名前でした。

mla_v2015_08_10_windows_installer.exe

デフォルトでインストールした後、MPLAB Xから以下のプロジェクトを探し

C:\microchip\mla\v2015_08_10\apps\fileio\sd_card_demo_lfn\firmware\MPLABX

fileio_sd_card_demo_lfn を読み込むと、同名のプロジェクトがオープンします。

このプロジェクトができましたら、マイコンの品種設定とi/oの設定を書き換える事により簡単にデモプログラムが動作します。・・・・とはなりませんでした。

Mplabx_sd

上のダイアログはMPLABXにてプロジュクトをオープンした時の画面ですが、上の方にICの品種を指定するランがありますので、実際に使用しているICファミリーを選択します。 

私の場合、実際に使用しているICはPIC24FJ128GB106ですので、ファミリー名はpic24fj256gb110となります。 使用可能なICのファミリー名が左側の「exp16」フォルダーの下に表示されていますので、確認できます。ここにリストされた以外のICで、このデモソフトが動作するかは不明です。

リンクされたファイルには同じ名前で中身の違うものがいくつかあります。main.c やsystem.c が該当しますので、他のホルダーでプロジェクトを構築する場合は、一度デモプロジェクトをオープンし、そのとき表示されるファイルをコピーして他のホルダー移すことで間違いを防ぐ事ができます。 事実、最初、リンクを頼りにファイルをコピーしてきて、独自のホルダーに集めてbuildをかけたところ、エラー続出で困り果てた事がありました。 この為、main.c とsystem.c はそれぞれ、SD_main.c とSD_system.c いう名前にし、のちのち間違わないようにした上で、独自のフォルダーへ移動させ、オリジナルのファイルは元の場所にそのまま残しました。 

まず、lfn(ロングファイル名)を選んだのに、リンクされたヘッダーファイルはlfnなしの普通のfileio.h。 これをハンドでfileio_lfn.hに入れ換えました。 ソースファイルもlfnではなかったような記憶ですが確かでありません。もし、違ってましたらソースファイルもfileio_lfn.c に入れ換えて下さい。

また、system.c の中の一部を以下のように書き換えました。

#pragma config FNOSC = FRCPLL//OSCを32MHzのCR発振に変更

#pragma config FWDTEN=OFF

ただし、このままでは16MHzにしかなりませんでしたので、main()の中で、以下を

追加し32MHzにしました。

OSCCON = 0b0001000110100001; //Fosc FRCPLL 32MHz
 CLKDIV = 0x0000;

また、青色の設定は後日、追加したものです。 このPICマイコンはデフォルトでウォッチドッグタイマーがONになっており、約2分20秒でリセットがかかる原因になっていました。 これが時々暴走する原因と解るまで3週間くらいかかりました。

また、i/oの設定も変更しました。

void USER_SdSpiConfigurePins_1 (void) {     //Initialize the SPI    

RPINR20bits.SDI1R = 25;    //修正

RPOR10bits.RP20R = 7;    //修正

RPOR11bits.RP22R = 8;    //修正

    //enable a pull-up for the card detect, just in case the SD-Card isn't attached    

//  then lets have a pull-up to make sure we don't think it is there.    

//CNPU5bits.CN68PUE = 1;//プルアップはハードで行っていますので、この行は不要です。   

// Deassert the chip select pin    

LATDbits.LATD2 = 1;    //CS端子1に設定

// Configure CS pin as an output    

TRISDbits.TRISD2 = 0;    //CS端子出力に設定

// Configure CD pin as an input    

TRISDbits.TRISD1 = 1;    //CD端子入力に設定

// Configure WP pin as an input   

// TRISDbits.TRISD1 = 1; //この行はコメントアウト

}

・・・・・

・・・・

inline void USER_SdSpiSetCs_1(uint8_t a) {

    LATDbits.LATD2 = a;   //CS端子修正

}

inline bool USER_SdSpiGetCd_1(void) {

    return (!PORTDbits.RD1) ? true : false;//CD端子修正

}

inline bool USER_SdSpiGetWp_1(void) {

    //return (PORTFbits.RF1) ? true : false;//コメントアウトして0を返す

    return 0;

}

ここまで修正してBuildをかけてエラーが出なかったら、成功です。

しかし、PCでFAT32にフォーマットしたSDカードを用意し、マイコンにプログラムを書き込んでもファイルは出来ません。

今度はmain.c の定義の部分を変更します。

typedef enum
{
    DEMO_STATE_MEDIA_DETECTED = 0,
    DEMO_STATE_NO_MEDIA,
    DEMO_STATE_DRIVE_MOUNTED,
    DEMO_STATE_DONE,
    DEMO_STATE_FAILED
} DEMO_STATE;

DEMO_STATE_NO_MEDIA=0という記述が最初の行にありますので、これを上記のごとく2行目に移し、"=0"の文字を削除します。 DEMO_STATE_MEDIA_DETECTEDを一番上にして、"=0"を追記しておきます。これは、Maicrochipのデモ機はCDが0の時ノーメディアなのに対して、秋月のソケットはCDが1のときノーメディアになっている為です。

以上の手直しでデモ用のファイルがSDカード内に出来るようになりました。

次に自作のファイル名でファイル作成にトライです。 ところが、出来たファイル名は文字化けして読めない上、ファイルの中身も空です。 ファイル名は「SWR00001.csv」で始まる連番とする予定ですので、この数値の部分はunsigned int で1から始まる整数です。これをファイルに書き込めるようにASCII変換してファイル名としたのですが、うまく行きません。

色々調べて、判った事は、FAT32のファイル名はASCIIコードではないということでした。ファイル名はutf-16という16bitの文字でエンコードされていました。 XC16の中にあるストリング系の関数は使えませんので、自分でASCII to utf-16の変換ルーチンを作る必要がありました。 

幸い、ASCIIコードの文字だけに限れば、8bitのASCIIコードの上部に0x00のコードを加えて、16bitにするだけなので、変換ルーチンは私でも作れましたが、日本語のファイル名は使えません。

このようにして、「SWR12345」のようなファイル名を付けたテキストファイルを作る事が出来るようになりました。このファイル名の数字の部分を連番のファイル名にし、拡張子をcsvにするとOKとなります。

SDカードは、128Mと8Gの物をテストしましたが、いずれもFAT32でフォーマットしてあれば問題なく使う事ができました。 exFATでフォーマットしたSDカードの場合、エラーがでます。

この小さなデモファイルを作る為に必要なROM容量は約44.9Kバイトです。これから実験しようと考えているなら、ROM容量64Kでは心細く、最低でも128K品が必要でしょう。

ところで、出来たファイルにちゃんとタイムスタンプが付いています。どうやって時間を計っているのでしょうかね。マイコンボードは使わないとき電源OFFなのですが。

このSDカードドライブ機能をアンテナアナライザーに実装する事にします。

SWRグラフをSDカードへセーブ へ続く。

INDEXに戻る