一、SD卡模塊介紹
1.1 什么是SD卡
SD存儲卡是一種基於半導體快閃記憶器的新一代記憶設備,由於它體積小、數據傳輸速度快、可熱插拔等優良的特性,被廣泛地於便攜式裝置上使用,例如數碼相機、平板電腦和多媒體播放器等。控制器對 SD 卡進行讀寫通信操作一般有兩種通信接口可選,一種是 SPI 接口,另外一種是 SDIO 接口。
1.2 SD卡的物理結構
一張SD卡包括有存儲單元、存儲單元接口、電源檢測、卡及接口控制器和接口驅動器5 個部分。
存儲單元是存儲數據部件,存儲單元通過存儲單元接口與卡控制單元進行數據傳輸;
電源檢測單元保證SD卡工作在合適的電壓下,如出現掉電或上狀態時,它會使控制單元和存儲單元接口復位;
卡及接口控制單元控制SD卡的運行狀態,它包括有8個寄存器;
接口驅動器控制 SD 卡引腳的輸入輸出。
二、項目代碼
已掛載在Github上
項目鏈接:https://github.com/LinZJ0423/STM32
燒錄程序成功后:
主要函數代碼分析:
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI1_Init(); MX_FATFS_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1); //enable uart printf(" mian \r\n"); Get_SDCard_Capacity(); //得到使用內存並選擇格式化 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { WritetoSD(WriteBuffer,sizeof(WriteBuffer)); HAL_Delay(500); WriteBuffer[0] = WriteBuffer[0] +0; WriteBuffer[1] = WriteBuffer[1] +1; write_cnt ++; while(write_cnt > 10) { printf(" while \r\n"); HAL_Delay(500); } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } void WritetoSD(BYTE write_buff[],uint8_t bufSize) { FATFS fs; FIL file; uint8_t res=0; UINT Bw; res = SD_init(); //SD卡初始化 if(res == 1) { printf("SD卡初始化失敗! \r\n"); } else { printf("SD卡初始化成功! \r\n"); } res=f_mount(&fs,"0:",1); //掛載 // if(test_sd == 0) //用於測試格式化 if(res == FR_NO_FILESYSTEM) //沒有文件系統,格式化 { // test_sd =1; //用於測試格式化 printf("沒有文件系統! \r\n"); res = f_mkfs("", 0, 0); //格式化sd卡 if(res == FR_OK) { printf("格式化成功! \r\n"); res = f_mount(NULL,"0:",1); //格式化后先取消掛載 res = f_mount(&fs,"0:",1); //重新掛載 if(res == FR_OK) { printf("SD卡已經成功掛載,可以進進行文件寫入測試!\r\n"); } } else { printf("格式化失敗! \r\n"); } } else if(res == FR_OK) { printf("掛載成功! \r\n"); } else { printf("掛載失敗! \r\n"); } res = f_open(&file,SD_FileName,FA_OPEN_ALWAYS |FA_WRITE); if((res & FR_DENIED) == FR_DENIED) { printf("卡存儲已滿,寫入失敗!\r\n"); } f_lseek(&file, f_size(&file));//確保寫詞寫入不會覆蓋之前的數據 if(res == FR_OK) { printf("打開成功/創建文件成功! \r\n"); res = f_write(&file,write_buff,bufSize,&Bw); //寫數據到SD卡 if(res == FR_OK) { printf("文件寫入成功! \r\n"); } else { printf("文件寫入失敗! \r\n"); } } else { printf("打開文件失敗!\r\n"); } f_close(&file); //關閉文件 f_mount(NULL,"0:",1); //取消掛載 }
程序首先進行相關初始化,完成后輸出mian,之后進行SD卡格式化,成功后進入循環,進入SD卡讀寫函數,先后進行SD卡的初始化,掛載,創文件,寫入,寫入超過10次,輸出while
三、相關引腳的配置
CS -> PB0 SCK -> PA5 MISO -> PA6 MOSI -> PA7
四、實驗結果
SD卡中生成一個新的hello.txt文件
內容如下
更改寫入內容
寫入結果如下:
五、心得體會
在初始化過程中確保SD格式化成FAT文件模式,確保單片機的供電和SD卡模塊的供電最好是5V,不然可能帶不動SD卡驅動導致實驗失敗。杜邦線連接要盡可能的短,因為實驗過程中,采用過長的杜邦線經常導致出不來結果。初始化的過程中需要耐心等待。本次實驗遇到了很多的問題,通過查閱相關博客,請教同學和老師問題得以解決,在解決的過程中提高了我們的動手能力以及學會了在SD卡讀寫東西,這是一個十分有意思的過程,在學習的過程中讓我受益匪淺。