如何使用CubeMx製作一個基於SD卡的文件系統工程

1 前言

本文將介紹使用CubeMx工具從零開始製作一個基於SD卡的文件系統,以便後續使用此功能者參考。

2 準備工作

本文工程得測試將以STM3240G-EVAL這個ST官方的評估板爲測試平臺,所有這塊板子的一些外部組件連接方式有必要先了解一下。

LED電路
按鍵電路
LED1~LED4分別使用管腳PG6,PG8,PI9,PC7,輸出高電平LED燈點亮,用戶按鍵使用PG15管腳,按下時爲低電平。
HSE電路
SD卡電路
如上圖,MCU使用的HSE是25M晶振。SD卡使用STM32F407固定的6個管腳如上圖所示D0(PC8),D1(PC9),D2(PC10),D3(PC11),CLK(PC12), CMD(PD2). SD卡插入檢測腳爲用戶自定義的管腳,在STM3240G這塊ST官方的評估板上是使用PH13管腳。

3 創建CubeMx工程與代碼修改

3.1 創建CubeMx工程

打開CubeMx創建一個基於STM32F407IGHx的工程,使能RCC的HSE,外部晶振模式,SDIO使用4位總線寬度,如下圖所示:
RCC
SDIO
並在pinout右邊將PH13設置爲INPUT模式:
pinout
接來下配置時鐘樹,將主屏配置爲168M:
clock tree
在配置頁面下的配置如下圖所示:
configuration
在中間件添加SD Card類型的FATFS:
middleware
在配置中的文件系統相關參數配置都使用默認參數值。
另外一點非常重要的是,在工程設置內配置棧大小爲0x800,默認的0x400是不夠的,運行時會出錯。如下:
project setting
最後點擊生成代碼。

3.2 SD卡和文件系統初始化部分

在main函數內有如下代碼:

  MX_GPIO_Init();
  MX_SDIO_SD_Init();
  MX_FATFS_Init();

SDIO初始化代碼已經自動生成,不需要修改任何地方,進入到MX_FATFS_Init()函數內,在/* USER CODE BEGIN Init /與/ USER CODE END Init */內添加用戶自定義代碼,如下:

/* USER CODE BEGIN Variables */
FATFS SDFatFs;
/* USER CODE END Variables */ 

void MX_FATFS_Init(void)
{
  /*## FatFS: Link the SD driver ###########################*/
  retSD = FATFS_LinkDriver(&SD_Driver, SD_Path);

  /* USER CODE BEGIN Init */
  /* additional user code for init */
    if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)
    {
      /* FatFs Initialization Error */
      Error_Handler();
    }
    else
    {
//      if(f_mkfs((TCHAR const*)SD_Path, 0, 0) != FR_OK)        //格式化SD存儲卡
//      {
//          /* FatFs Format Error */
//          Error_Handler();
//      }
    }
  /* USER CODE END Init */
}

如上代碼,自己定義全局變量SDFatFs,以供後續代碼需要用到。
上面代碼中在掛載SD卡後的註釋掉的f_mkfs行是格式化SD卡,可以根據情況來是否需要格式化SD卡,這裏選擇不格式化。

3.3 文件系統與SDIO對接部分

文件系統與SDIO對接有些地方需要修改。
打開bsp_driver_sd.c文件,找到BSP_SD_IsDetected函數,由於SD卡插入檢測是通過用戶定義的管腳來實現檢測的(本例是通過PH13來檢測的),因此,這裏需要匹配下,在此函數內的/* USER CODE BEGIN 1 /與/ USER CODE END 1 */之間添加用戶自己的代碼:

uint8_t BSP_SD_IsDetected(void)
{
  __IO uint8_t status = SD_PRESENT;

  /* USER CODE BEGIN 1 */
  /* user code can be inserted here */
  if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_Port, SD_DETECT_Pin) != GPIO_PIN_RESET) //SD卡插入時爲低電平
    {
        status =SD_NOT_PRESENT;
    }
  /* USER CODE END 1 */     

  return status;
}

就這樣,就移植好了,接來下是寫測試代碼。

3.4 測試文件系統

回到main函數,在/* USER CODE BEGIN 2 /與/ USER CODE END 2 */添加自己的文件系統測試代碼,如下:

if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) //創建一個文件
    {
        /* 'STM32.TXT' file Open for write Error */
        Error_Handler();
    }
  else
  {
            res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);//寫入內容
            if((byteswritten == 0) || (res != FR_OK))
            {
                /* 'STM32.TXT' file Write or EOF Error */
                Error_Handler();
            }
            else
            {
                f_close(&MyFile); //關閉文件

                /*##-7- Open the text file object with read access ###############*/
                if(f_open(&MyFile, "STM32.TXT", FA_READ) != FR_OK) //再次打開文件
                {
                    /* 'STM32.TXT' file Open for read Error */
                    Error_Handler();
                }
                else
                {
                    res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread);  //讀出內容

                    if((bytesread == 0) || (res != FR_OK))
                    {
                        /* 'STM32.TXT' file Read or EOF Error */
                        Error_Handler();
                    }
                    else
                    {
                        f_close(&MyFile); //關閉文件

                /*##-10- Compare read data with the expected data ############*/
                if((bytesread != byteswritten))  //比較
                {
                  /* Read data is different from the expected data */
                  Error_Handler();
                }
                else
                {
                  /* Success of the demo: no error occurrence */
                  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
                }
                    }
                }
            }
  }

上述代碼流程爲:創建一個文件,寫入內容,再關閉此文件,然後再次打開這個文件,讀出內容,關閉文件,最後比較讀出的內容是否爲寫入的內容,根據比較結果分別進行處理。

最後編譯整個工程燒錄到STM3240G-EVAL這塊評估板上進行測試,運行結果是OK的。

4 結論

CubeMx還是相當強大的,將一個SD存儲卡的文件系統通過幾步設置就自動生成了工程,只需要掌握幾處關鍵地方進行修改就能讓這麼一個看似很複雜的工程通過幾步簡單的步驟就完成了。CubeMx是一個非常強大的工具,此文最關鍵的參數就棧大小設置爲0x800,沒碰到過的人需要花很長時間纔會發現這個問題,所以再次強調下。

最後附上代碼工程下載鏈接地址:
http://download.csdn.net/detail/flydream0/9649702

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章