STM32CubeMX系列教程17:SDMMC
SDHC卡(SD High Capacity,大容量SD卡):4GB~32GB
SDXC卡(SD eXtended Capacity):64GB~2TB。
在main.c文件前面添加变量,Status保存程序返回状态,Buffer_Tx,Buffer_Rx存储读写数据。
/* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ HAL_SD_ErrorTypedef Status; uint32_t Buffer_Tx[512/4], Buffer_Rx[512/4]; uint32_t i; /* USER CODE END PV */
程序中用的memset函数填充缓存数据,所以要添加字符头文件。
/* USER CODE BEGIN Includes */ #include <string.h> /* USER CODE END Includes */</string.h>
在main函数中添加下面应用程序。程序中首先输出SD卡信息,然后进行读写擦除块等操作。
/* USER CODE BEGIN 2 */ printf(" Warning: this program may erase all the TF card data. \r\n"); printf("\r\n Initialize SD card successfully!\r\n\r\n"); printf(" SD card information! \r\n"); printf(" CardCapacity : %llu \r\n",SDCardInfo1.CardCapacity ); printf(" CardBlockSize : %d \r\n",SDCardInfo1.CardBlockSize); printf(" RCA : %d \r\n",SDCardInfo1.RCA); printf(" CardType : %d \r\n",SDCardInfo1.CardType); /*------------------- Block Write --------------------------*/ memset(Buffer_Tx,0x15,sizeof(Buffer_Tx)); if(HAL_SD_WriteBlocks_DMA(&hsd1, Buffer_Tx, 0, 512, 1) == SD_OK) { Status = HAL_SD_CheckWriteOperation(&hsd1, (uint32_t)100000000); if (Status == SD_OK) { printf("\r\n Write block successfully!\r\n"); for(i=0;i<sizeof(buffer_tx)>>2;i++) { printf("%02x:0x%08x ",i,Buffer_Tx[i]); } printf("\r\n"); } else printf("\r\n Write block fail!\r\n"); } /*------------------- Block Read --------------------------*/ if(HAL_SD_ReadBlocks_DMA(&hsd1, Buffer_Rx, 0, 512, 1) == SD_OK) { Status = HAL_SD_CheckReadOperation(&hsd1, 0xFFFF); if (Status == SD_OK) { printf("\r\n Read block successfully!\r\n"); for(i=0;i<sizeof(buffer_rx)>>2;i++) { printf("%02x:0x%08x ",i,Buffer_Rx[i]); } printf("\r\n"); } else printf("\r\n Read block fail!\r\n"); } /*------------------- Block Erase -------------------------------*/ Status = HAL_SD_Erase(&hsd1, 0, 512); if (Status == SD_OK) printf("\r\n Erase block successfully!\r\n"); else printf("\r\n Erase block fail!\r\n"); /*------------------- Block Read --------------------------*/ if(HAL_SD_ReadBlocks_DMA(&hsd1, Buffer_Rx, 0, 512, 1) == SD_OK) { Status = HAL_SD_CheckReadOperation(&hsd1, 0xFFFF); if (Status == SD_OK) { printf("\r\n Read block successfully!\r\n"); for(i=0;i<sizeof(buffer_rx)>>2;i++) { printf("%02x:0x%08x ",i,Buffer_Rx[i]); } printf("\r\n"); } else printf("\r\n Read block fail!\r\n"); } /* USER CODE END 2 */</sizeof(buffer_rx)></sizeof(buffer_rx)></sizeof(buffer_tx)>
在SDMMC接口初始化函数MX_SDMMC1_SD_Init()中,调用HAL_SD_Init(&hsd1, &SDCardInfo1)函数初始SD卡(有兴趣的少年可以对比上面的状态图看看SD卡的初始化程序),将SD卡的信息保存在SDCardInfo1结构体中。
其中SD_csd,SD_cid分别对应SD卡的CSD,CID寄存器。CardCapacity为SD卡容量大小,CardBlockSize为SD卡块大小,CardType为SD类型。查看HAL_SD_CSDTypedef,HAL_SD_CIDTypedef两个类型可以知道CSD,CID寄存器各位的含义。
/** @defgroup SD_Exported_Types_Group5 SD Card information structure * @{ */ typedef struct { HAL_SD_CSDTypedef SD_csd; /*!< SD card specific data register */ HAL_SD_CIDTypedef SD_cid; /*!< SD card identification number register */ uint64_t CardCapacity; /*!< Card capacity */ uint32_t CardBlockSize; /*!< Card block size */ uint16_t RCA; /*!< SD relative card address */ uint8_t CardType; /*!< SD card type */ }HAL_SD_CardInfoTypedef;
程序中HAL_SD_WriteBlocks_DMA()和HAL_SD_ReadBlocks_DMA()读写块,注意调用这函数后面要调用HAL_SD_CheckWriteOperation()/HAL_SD_CheckReadOperation()判断传输是否完成。同样也可以用HAL_SD_WriteBlocks()/HAL_SD_ReadBlocks()通过轮询的方式读写块。HAL_SD_Erase()为擦除块操作。