一、rtthread使用SD卡
1、配置RT-ThreadSetting
開啓SDIO,配置保存。
2、開啓board.h及stm32f1xx_hal_conf.h的宏定義
3、使用STM32cube配置引腳及通訊參數
生成配置文件,複製stm32f1xx_hal_msp.c中void HAL_SD_MspInit(SD_HandleTypeDef* hsd)到board.c的最後,HAL庫初始化時會調用,同時別忘記更改board.c上面的函數改爲外部時鐘。
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hsd->Instance==SDIO)
{
/* USER CODE BEGIN SDIO_MspInit 0 */
/* USER CODE END SDIO_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SDIO_CLK_ENABLE();
/**SDIO GPIO Configuration
PC8 ------> SDIO_D0
PC9 ------> SDIO_D1
PC10 ------> SDIO_D2
PC11 ------> SDIO_D3
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN SDIO_MspInit 1 */
/* USER CODE END SDIO_MspInit 1 */
}
}
4、掛載文件elm-fat系統
虛擬文件系統資料鏈接
前2個步驟開啓文件系統的時候就已經被調用了,第3步如果是使用SDIO,會在程序中自動初始化註冊爲塊設備,則也不需要編寫,如果是使用SPI則需要編寫註冊塊設備語句。
在SD卡上使用文件系統鏈接
接下來進行第4、5步的程序編寫,先格式化,然後再掛載塊設備到DFS目錄上,之後就可以開始驗證工作了。
void mnt_init(void)
{
rt_thread_mdelay(100);//這段延時必須加上,系統上電過程中存在延時,否則會出現先掛載後註冊塊設備sd0的情況
mkfs("elm","sd0");//掛在前需格式化
if(dfs_mount("sd0","/","elm",0,0)==0) //掛載文件系統,參數:塊設備名稱、掛載目錄、文件系統類型、讀寫標誌、私有數據0
{
rt_kprintf("dfs mount success\r\n");
}
else
{
rt_kprintf("dfs mount failed\r\n");
}
}
二、驗證
掛載文件系統前未加延時的情況:
現象如圖,註冊塊設備失敗了,但是讀SD卡的內存成功了,這樣子的話是不能實現增刪改查文件的。根據這個打印信息,明顯是先掛載了文件系統沒有找到sd0設備(Device(sd0) was not found),然後才初始化註冊的塊設備讀出了內存,但是程序中明明就是在系統初始化完成後在main()函數中才執行的掛載,那問題出在哪裏呢?
仿真找了一下,文件系統先掛載了,然後sd0塊設備後註冊,導致查詢不到塊設備sd0,這並不是我故意後註冊塊設備,我仿真查詢到SD卡系統初始化的時候,上電過程中在mmcsd_power_up()這個函數中存在延時,導致塊設備初始化線程掛起(SDIO驅動SD卡是系統自動註冊塊設備的),在自己寫的初始化中掛載文件系統的語句就先運行了,導致運行不正常,解決方式是在SD卡格式化前加一小段延時。
void mnt_init(void)
{
rt_thread_mdelay(100);//這段延時必須加上,系統上電過程中存在延時,否則會出現先掛載後註冊塊設備sd0的情況
mkfs("elm","sd0");//掛在前需格式化
if(dfs_mount("sd0","/","elm",0,0)==0) //掛載文件系統,參數:塊設備名稱、掛載目錄、文件系統類型、讀寫標誌、私有數據0
{
rt_kprintf("dfs mount success\r\n");
}
else
{
rt_kprintf("dfs mount failed\r\n");
}
}
掛載文件系統前加了延時後的情況:
使用SDIO驅動SD卡掛載文件系統成功。