OneNET麒麟座應用開發之九:與SD卡通訊並儲存資料

來源:互聯網
上載者:User

標籤:name   即時   get   image   電源   set   這一   man   漢字編碼   

由於需要記錄的資料量比較大,而且有些時候,有的使用者不方便即時上傳資料,所以要求使用SD卡儲存資料然後人工收取上傳。為此我們選擇了一種通用的SD卡讀寫器。

1、讀卡機簡介

該讀卡機整合 SD 記憶卡規範和 FAT 檔案格式規範,只要通過本模組規定的通訊協議就可以把資料存放區在 SD 記憶卡中的檔案中。該讀卡機串連方便採用串口通訊方式,如:

該讀卡機摸塊通訊協議比較簡單,本模組的通訊協議分為命令發送和命令的應答兩部分,其中命令格式由4個部分組成:命令識別碼(0x55 0xAA),命令號,位元組數(參數的個數,佔2個位元組,先發送低位位元組,再發送高位位元組),參數(根據命令的不同而不同),校正和(除命令識別碼和校正和本身,所有發送資料之和的低 8 位元據)。命令格式

 

應答分為兩部分:命令的執行情況(編碼將附錄 1),資料。資料根據命令的不同而不同。

2、硬體串連

因為採用的是串口通訊,所以硬體的串連比較簡單。麒麟座上的USART1(PA9:USART1_TX,PA10:USART1_RX)連接埠已經引到了J2端子排的J2_6和J2_5,所以我們就是用這一介面,至於5V電源和接地以及控制及狀態訊號懸著相應的引腳即可。

 

3、軟體設計

接下來我們根據協議編寫讀寫SD卡的軟體,主要實現狀態檢測、建立檔案、開啟檔案、寫檔案、關閉檔案、儲存檔案以及擷取檔案資訊等。

1)擷取系統的狀態命令

擷取系統的狀態命令是用來擷取模組當前的狀態。命令編碼是:0x01,命令格式如下:

 

//檢測系統SD卡的狀態uint8_t GetSDCardStatus(void){  uint8_t CommandText[6]={0x55,0xAA,0x01,0x00,0x00,0x01};  uint8_t StatusByte=0xaa;  StatusByte = SendCommand(CommandText,6);  Delayms(50);  return StatusByte;}

2)建立檔案命令

建立檔案命令提供給主機建立檔案的功能。參數為 N 位元組 8.3 檔案格式的檔案名稱(字串格式,即檔案名稱以 0 結尾),即 8 位元組的基本檔案名稱(模組不支援漢字編碼,字母不區分大小寫),3 位元組副檔名。命令編碼是:0x02,命令格式如下:

 

//建立檔案,返回操作狀態uint8_t CreateFile(uint8_t fileName[8]){  uint8_t CommandText[19]={0x55,0xAA,0x02,0x0D,0x00,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x2E,0x74,0x78,0x74,0x00,0x41};  uint8_t StatusByte;  StatusByte=0xaa;  uint16_t i;  for(i=0;i<8;i++)  {    CommandText[i+5]=fileName[i];  }  uint8_t checksum=0x00;  for(i=2;i<18;i++)  {    checksum+=CommandText[i];  }  CommandText[18]=checksum;  StatusByte = SendCommand(CommandText,19);  return StatusByte;}

(3)開啟檔案命令

該命令為主機提供開啟檔案的功能。參數為 N 位元組 8.3 檔案格式的檔案名稱(字串格式,即檔案名稱以0 結尾),即 8 位元組的基本檔案名稱(模組不支援漢字編碼,字母不區分大小寫),3 位元組副檔名。命令編碼是:0x06命令格式如下,其中個數占 2 位元組,低位元組先發送:

 

//開啟檔案uint8_t OpenFile(uint8_t fileName[8]){  uint8_t CommandText[19]={0x55,0xAA,0x06,0x0D,0x00,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x2E,0x74,0x78,0x74,0x00,0x45};//開啟檔案命令 0x06  uint8_t StatusByte=0xaa;  uint16_t i;  for(i=0;i<8;i++)  {    CommandText[i+5]=fileName[i];  }  uint8_t checksum=0x00;  for(i=2;i<18;i++)  {    checksum+=CommandText[i];  }  CommandText[18]=checksum;  StatusByte = SendCommand(CommandText,19);  return StatusByte;}

4)擷取檔案資訊命令

本命令為主機提供了讀取當前開啟檔案的檔案指標值和檔案大小的功能。命令編碼是:0x09,其命令格式如下:

 

//擷取檔案資訊命令void GetFileStatus(uint8_t rxData[]){  uint8_t CommandText[6]={0x55,0xAA,0x09,0x00,0x00,0x09};//擷取檔案資訊命令0x09  uint16_t i;  for(i=0;i<6;i++)  {    //等待傳送結束    while(USART_GetFlagStatus(UART4, USART_FLAG_TXE) == RESET)    {    }    // 寫一個位元組到對應的串口傳送資料寄存器    USART_SendData(UART4, CommandText[i]);  }   Delayms(20);   for(i=0;i<9;i++)  {    // 等待位元組被對應的串口完全接收    //while(USART_GetFlagStatus(UART4, USART_FLAG_RXNE) == RESET)    //{    //}    // 擷取接收到的位元組    rxData[i] = USART_ReceiveData(UART4);  }}

5)寫檔案命令

該命令為主機提供向已開啟檔案中寫入資料的功能。每寫一個資料檔案指標自動加1,當資料寫完,檔案指標指向最後一個資料地址加1的位置。命令編碼是:0x05,命令格式如下,其中個數佔2位元組,低位元組先發送,起始地址佔4位元組,低位元組先發送:

 

//寫檔案,返回寫操作的狀態uint8_t WriteToFile(uint8_t * address,uint8_t data[],uint16_t datalength){  uint16_t count=datalength+10+19;  uint8_t CommandText[70];  uint8_t StatusByte=0xaa;  uint16_t i;  CommandText[0]=0x55;  CommandText[1]=0xAA;  CommandText[2]=0x05;  CommandText[3]=datalength+4+19;  CommandText[4]=0x00;  CommandText[5]=0xFF;  CommandText[6]=0xFF;  CommandText[7]=0xFF;  CommandText[8]=0xFF;   for(i=0;i<datalength;i++)  {    CommandText[i+9]=data[i];  }   CommandText[datalength+9]=(saveDate[0]/10)+0x30;  CommandText[datalength+10]=(saveDate[0]%10)+0x30;  CommandText[datalength+11]=0x2D;  CommandText[datalength+12]=(saveDate[1]/10)+0x30;  CommandText[datalength+13]=(saveDate[1]%10)+0x30;  CommandText[datalength+14]=0x2D;  CommandText[datalength+15]=(saveDate[2]/10)+0x30;  CommandText[datalength+16]=(saveDate[2]%10)+0x30;  CommandText[datalength+17]=0x20;  CommandText[datalength+18]=(saveDate[3]/10)+0x30;  CommandText[datalength+19]=(saveDate[3]%10)+0x30;  CommandText[datalength+20]=0x3A;  CommandText[datalength+21]=(saveDate[4]/10)+0x30;  CommandText[datalength+22]=(saveDate[4]%10)+0x30;  CommandText[datalength+23]=0x3A;  CommandText[datalength+24]=(saveDate[5]/10)+0x30;  CommandText[datalength+25]=(saveDate[5]%10)+0x30;  CommandText[datalength+26]=0x0D;  CommandText[datalength+27]=0x0A;   uint8_t checksum=0x00;  for(i=2;i<count-1;i++)  {    checksum+=CommandText[i];  }  CommandText[count-1]=checksum;  StatusByte = SendCommand(CommandText,count);  return StatusByte;}

6)儲存檔案命令

該命令為主機提供儲存當前開啟檔案的功能,為了防止頻繁寫 SD 記憶卡,每次送入模組的資料先是儲存在模組的 512 位元組的扇區緩衝中,所以為了防止資料丟失,完成所有資料的傳輸後,要發送儲存檔案命令來儲存檔案。命令編碼是:0x04,命令格式如下:

 

//儲存檔案,返回操作執行狀態uint8_t SaveFile(void){  uint8_t CommandText[6]={0x55,0xAA,0x04,0x00,0x00,0x04};//儲存檔案命令 0x04  uint8_t StatusByte=0xaa;  StatusByte = SendCommand(CommandText,6);  return StatusByte;}

7)關閉檔案命令

該命令為主機提供關閉當前開啟的檔案的功能。在建立檔案、建立檔案夾、開啟檔案之前要求關閉當前開啟的檔案,才可以執行這些命令,否則返回失敗。命令編碼是:0x08,命令格式如下:

 

//關閉檔案,返回操作執行狀態uint8_t CloseFile(void){  uint8_t CommandText[19]={0x55,0xAA,0x08,0x00,0x00,0x08};//關閉檔案命令 0x08  uint8_t StatusByte=0xaa;  StatusByte = SendCommand(CommandText,6);  return StatusByte;}

編寫完程式,我們測試以我們想要的格式寫一些資料下去檔案被儲存為文字檔,以時間為檔案名稱,資料格式與預期一致。至此SD卡讀寫完成。

OneNET麒麟座應用開發之九:與SD卡通訊並儲存資料

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.