トップページ > dsPIC入門 > SDカードモジュールの使い方(3)

SDカードモジュール用のヘッダファイル

SD用ヘッダファイル : SD.h

//******************************************************************************
//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;
}  

ヘッダファイルの使い方




前へ   戻る