トップページ > 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; }