トップページ > dsPIC入門 > SDカードモジュールの使い方(3)
//******************************************************************************
//SDカード用ヘッダファイル for dsPIC30F
//SDカードはUART2
//デフォルトでは、SDカードモジュールの通信速度は9600bpsです。
//******************************************************************************
//******************************************************************************
//関数プロトタイプ宣言
//******************************************************************************
//SDカードモジュールからのACKを待つ関数
int ack_wait(void);
//SDカードモジュールを初期化して、使用できるようにする関数
int SD_ini(void);
//挿入されているSDカードをクイックフォーマットする関数
int quic_format(void);
//新しくファイルを生成する関数
int new_file(char *file_name);
//指定ファイルに1バイト書き込む関数
int write_char(char *file_name,char data);
//指定ファイルに任意バイト数を書き込む関数
int write_string(char *file_name,char *data,int num);
//引数のint型データを16進数文字列に変換する関数
char* SD_int_toString(int data);
//******************************************************************************
//SDカードモジュールからのACKを待つ関数。最大3秒程度のウェイト。
//******************************************************************************
int ack_wait(void)
{
//for文用変数
int i;
//受信タイムアウトのカウント用
unsigned int timeout_cnt;
//受信データ用変数
char temp;
//フェーズ管理用
int phase;
//はじめに変数をリセット
timeout_cnt=0;
phase=0;
//オーバーラン・フラグをクリア
U2STAbits.OERR=0;
//-------------------------------------------------------------------
//1バイト受信
for(i=0;i<40;i++)
{
timeout_cnt=0;
while(!DataRdyUART2())
{
timeout_cnt++;
if(timeout_cnt>65000)
{
break;
}
}
//データ受信
temp=ReadUART2();
//オーバーランをチェック
if(U2STAbits.OERR==1)
{
U2STAbits.OERR=0;
}
//-------------------------------------------------------------------
//ACKかどうかを判定
switch(phase)
{
//最初の'!'を待つ。
case 0:
if(temp==(char)0x21)
{
phase = 1;
}
break;
//1つめの'0'を待つ。
case 1:
if(temp==(char)0x30)
{
phase = 2;
}
else
{
if(temp==(char)0x21)
{
phase = 1;
}
else
{
phase=0;
}
}
break;
//2つめの'0'を待つ。
case 2:
if(temp==(char)0x30)
{
phase = 3;
}
else
{
phase = 0;
}
break;
//最後のCR(0x0d)を待つ。
case 3:
if(temp==(char)0x0d)
{
//ACK正常受信の場合、0を返す。
return 0;
}
else
{
phase = 0;
}
break;
}
//switch文ここまで。
//-------------------------------------------------------------------
}
//for文ここまで。
//-------------------------------------------------------------------
//ACKを受信できなかった場合は-1を返す。
return -1;
}
//******************************************************************************
//ack_wait()ここまで。
//******************************************************************************
//******************************************************************************
//SDカードモジュールを初期化する関数
//******************************************************************************
int SD_ini(void)
{
//試行回数設定
int try_cnt=10000;
//for文用変数
int i;
//-------------------------------------------------------------------
//設定回数だけ繰り返す。
for(i=0;i<try_cnt;i++)
{
//初期化コードを送る。
WriteUART2('I');
while(BusyUART2());
//CRを送る。
WriteUART2(0x0d);
while(BusyUART2());
//ACKを確認。
if(ack_wait()==0)
{
//初期化できた場合は0を返す。
return 0;
}
}
//for文ここまで。
//-------------------------------------------------------------------
//初期化できなかった場合は-1を返す。
return -1;
}
//******************************************************************************
//SD_ini()ここまで
//******************************************************************************
//******************************************************************************
//SDカードをクイックフォーマットする関数
//(30秒くらいかかります・・・)
//******************************************************************************
int quic_format(void)
{
//試行回数設定
int try_cnt=10000;
//for文用変数
int i;
//状態保存
int phase=0;
//-------------------------------------------------------------------
//設定回数だけ繰り返す。
for(i=0;i<try_cnt;i++)
{
//クイックフォーマット開始の命令を出す。
if(phase==0)
{
//命令を送る。
putsUART2("Q CONFIRM FORMAT");
while(BusyUART2());
//CRを送る。
WriteUART2(0x0d);
while(BusyUART2());
//ACKを待つ。
if(ack_wait()==0)
{
phase=1;
}
}
//クイックフォーマットが完了するまで待つ。
if(phase==1)
{
if(ack_wait()==0)
{
//正常にフォーマットできた場合は0を返す。
return 0;
}
}
}
//for文ここまで。
//-------------------------------------------------------------------
//フォーマットできなかった場合は-1を返す。
return -1;
}
//******************************************************************************
//quic_format()ここまで
//******************************************************************************
//******************************************************************************
//新しくファイルを作る関数。
//引数はファイル名(拡張子含む)です。
//******************************************************************************
int new_file(char *file_name)
{
//試行回数
int try_cnt=10000;
//for文用変数
int i;
//状態保存用
int phase=0;
//ファイル生成完了フラグ
int flag=0;
//-------------------------------------------------------------------
//設定回数だけ繰り返す。
for(i=0;i<try_cnt;i++)
{
//-------------------------------------------------------------------
//1つ1つのACKが来るまで、順次くりかえしながら実行。
switch(phase)
{
//新しくファイルを作る。
case 0:
putsUART2("O 1W>");
while(BusyUART2());
putsUART2(file_name);
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
phase++;
}
break;
//0バイト書き込み命令。(実質何もしない)
case 1:
putsUART2("W 1>0");
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
phase++;
}
break;
//ファイルクローズ
case 2:
putsUART2("C 1");
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
//生成完了フラグを立てる。
flag=1;
}
break;
}
//swicth文ここまで。
//-------------------------------------------------------------------
//生成完了の場合
if(flag==1)
{
//正常にファイルを生成できた場合は0を返す。
return 0;
}
}
//for文ここまで。
//-------------------------------------------------------------------
//ファイル生成できなかった場合は-1を返す。
return -1;
}
//******************************************************************************
//new_file()ここまで。
//******************************************************************************
//******************************************************************************
//指定したファイルに任意バイト数のデータを追加する関数
//第一引数はファイル名、
//第二引数は書きこむデータ、
//第三引数はデータのバイト数です。
//******************************************************************************
int write_string(char *file_name,char *data,int num)
{
//試行回数
int try_cnt=10000;
//for文用変数
int i,j;
//状態保存用
int phase=0;
//データ書き込み完了フラグ
int flag=0;
//-------------------------------------------------------------------
//設定回数だけ繰り返す
for(i=0;i<try_cnt;i++)
{
//-------------------------------------------------------------------
//1つ1つのACKが来るまで、順次くりかえしながら実行。
switch(phase)
{
//アド・モードで指定ファイルをオープン。
case 0:
putsUART2("O 1A>");
while(BusyUART2());
putsUART2(file_name);
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
phase++;
}
break;
//任意のバイト数分だけ書き込むことを宣言。
case 1:
putsUART2("W 1>");
while(BusyUART2());
putsUART2(SD_int_toString(num));
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
phase++;
}
break;
//書き込みデータ送信。
case 2:
for(j=0;j<num;j++)
{
WriteUART2(*data);
while(BusyUART2());
data++;
}
if(ack_wait()==0)
{
phase++;
}
break;
//ファイルクローズ。
case 3:
putsUART2("C 1");
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
//書きこみ完了フラグを立てる。
flag=1;
}
break;
}
//swicth文ここまで。
//-------------------------------------------------------------------
//書き込み完了の場合。
if(flag==1)
{
//正常に書き込めた場合は0を返す。
return 0;
}
}
//for文ここまで。
//-------------------------------------------------------------------
//書きこみ失敗の時は-1を返す。
return -1;
}
//******************************************************************************
//write_string()ここまで。
//******************************************************************************
//******************************************************************************
//指定したファイルに1バイトデータを追加する関数
//第一引数はファイル名、
//第二引数は書きこむデータです。
//******************************************************************************
int write_char(char *file_name,char data)
{
//試行回数
int try_cnt=10000;
//for文用変数
int i;
//状態保存用
int phase=0;
//データ書き込み完了フラグ
int flag=0;
//-------------------------------------------------------------------
//設定回数だけ繰り返す
for(i=0;i<try_cnt;i++)
{
//-------------------------------------------------------------------
//1つ1つのACKが来るまで、順次くりかえしながら実行。
switch(phase)
{
//アド・モードで指定ファイルをオープン。
case 0:
putsUART2("O 1A>");
while(BusyUART2());
putsUART2(file_name);
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
phase++;
}
break;
//1バイト書き込むことを宣言。
case 1:
putsUART2("W 1>1");
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
phase++;
}
break;
//書き込みデータ送信。
case 2:
WriteUART2(data);
while(BusyUART2());
if(ack_wait()==0)
{
phase++;
}
break;
//ファイルクローズ。
case 3:
putsUART2("C 1");
while(BusyUART2());
WriteUART2(0x0d);
while(BusyUART2());
if(ack_wait()==0)
{
//書きこみ完了フラグを立てる。
flag=1;
}
break;
}
//swicth文ここまで。
//-------------------------------------------------------------------
//書き込み完了の場合。
if(flag==1)
{
//正常に書き込めた場合は0を返す。
return 0;
}
}
//for文ここまで。
//-------------------------------------------------------------------
//書きこみ失敗の時は-1を返す。
return -1;
}
//******************************************************************************
//write_char()ここまで。
//******************************************************************************
//******************************************************************************
//整数を文字列に変える関数
//******************************************************************************
char* SD_int_toString(int data)
{
//for文用変数
int i;
int j;
int string_index=0;
static char num_string[7];
char temp_string[7];
int temp;
int m_flag=0;
int z_flag=0;
temp = data;
if(data<0)
{
data = -data;
m_flag=1;
}
if(data==0)
{
z_flag=1;
}
while(data>0)
{
temp = data%16;
//数値を文字列にする作業…。
switch(temp)
{
case 0:
temp_string[string_index] = '0';
break;
case 1:
temp_string[string_index] = '1';
break;
case 2:
temp_string[string_index] = '2';
break;
case 3:
temp_string[string_index] = '3';
break;
case 4:
temp_string[string_index] = '4';
break;
case 5:
temp_string[string_index] = '5';
break;
case 6:
temp_string[string_index] = '6';
break;
case 7:
temp_string[string_index] = '7';
break;
case 8:
temp_string[string_index] = '8';
break;
case 9:
temp_string[string_index] = '9';
break;
case 10:
temp_string[string_index] = 'A';
break;
case 11:
temp_string[string_index] = 'B';
break;
case 12:
temp_string[string_index] = 'C';
break;
case 13:
temp_string[string_index] = 'D';
break;
case 14:
temp_string[string_index] = 'E';
break;
case 15:
temp_string[string_index] = 'F';
break;
}
//次の位へいきます。
data/=16;
string_index++;
}
if(z_flag==0 && m_flag==0)
{
j=string_index;
j--;
for(i=0;i<string_index;i++)
{
num_string[i]=temp_string[j-i];
}
for(i=string_index;i<7;i++)
{
num_string[i]=0;
}
}
if(m_flag==1)
{
num_string[0]='-';
j=string_index;
j--;
for(i=0;i<string_index;i++)
{
num_string[i+1]=temp_string[j-i];
}
for(i=string_index+1;i<7;i++)
{
num_string[i]=0;
}
}
if(z_flag==1)
{
num_string[0]='0';
for(i=1;i<7;i++)
{
num_string[i]=0;
}
}
return num_string;
}