这是本文档旧的修订版!
int main(void) { /* MCU 配置*/ /* 重置所有外围设备,初始化Flash接口和Systick */ HAL_Init(); /* 配置系统时钟 */ SystemClock_Config(); /* 初始化所有已配置的外围设备 */ MX_GPIO_Init(); MX_DMA_Init(); MX_SDMMC1_SD_Init(); MX_USART6_UART_Init(); usart6.initialize(115200); //串口波特设置 usart6.printf("\x0c"); //清屏 usart6.printf("\033[1;32;40m"); //设置终端字体为绿色 usart6.printf("\r\nHello, I am iCore4!\r\n\r\n"); //串口信息输出 //配置SD接口位宽为4bit用于数据传输 if(HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK){ usart6.printf("SD Card Error!\r\n"); while(1){ LED_RED_ON; HAL_Delay(500); LED_RED_OFF; HAL_Delay(500); } }else{ usart6.printf("SD Card OK!\r\n"); } switch(hsd1.SdCard.CardType){ case CARD_SDSC: usart6.printf("SD CardType\t\t: CARD_SDSC\r\n"); break; case CARD_SDHC_SDXC: usart6.printf("SD CardType\t\t: CARD_SDHC_SDXC\r\n"); break; case CARD_SECURED: usart6.printf("SD CardType\t\t: CARD_SECURED\r\n"); break; } switch(hsd1.SdCard.CardVersion){ case CARD_V1_X: usart6.printf("SD CardVersion\t: CARD_V1_X\r\n"); break; case CARD_V2_X: usart6.printf("SD SD CardVersion\t: CARD_V2_X\r\n"); break; } usart6.printf("SD CardCapacity\t\t: %dMB\r\n",(unsigned int)(hsd1.SdCard.BlockNbr * hsd1.SdCard.BlockSize) >> 20); usart6.printf("SD BlockSize\t\t: %dByte\r\n",hsd1.SdCard.BlockSize); usart6.printf("SD RelCardAdd\t\t: %d\r\n",hsd1.SdCard.RelCardAdd); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ LED_GREEN_ON; HAL_Delay(500); LED_GREEN_OFF; HAL_Delay(500); } /* USER CODE END 3 */ }
void MX_SDMMC1_SD_Init(void) { hsd1.Instance = SDMMC1; hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; //上升沿 hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; //使用 bypass 模式,直接用 HCLK 进行分频得到 SDMMC_CK hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; //空闲时不关闭时钟电源 hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B; //1位数据线 hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; //关闭硬件流控 hsd1.Init.ClockDiv = 5; //SD传输时钟频率 if (HAL_SD_Init(&hsd1) != HAL_OK) //初始化SD卡 { _Error_Handler(__FILE__, __LINE__); } HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B); //使能宽总线模式 }
void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle) { GPIO_InitTypeDef GPIO_InitStruct; if(sdHandle->Instance==SDMMC1) { /* SDMMC1时钟使能 */ __HAL_RCC_SDMMC1_CLK_ENABLE(); /**SDMMC1 GPIO配置 PC8 ------> SDMMC1_D0 PC9 ------> SDMMC1_D1 PC10 ------> SDMMC1_D2 PC11 ------> SDMMC1_D3 PC12 ------> SDMMC1_CK PD2 ------> SDMMC1_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.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* SDMMC1 DMA 初始化 */ /* SDMMC1 初始化 */ hdma_sdmmc1.Instance = DMA2_Stream3; hdma_sdmmc1.Init.Channel = DMA_CHANNEL_4; //DMA通道 hdma_sdmmc1.Init.Direction =DMA_PERIPH_TO_MEMORY; //从外围设备传输到内存 hdma_sdmmc1.Init.PeriphInc = DMA_PINC_DISABLE; //不增加外设地址寄存器 hdma_sdmmc1.Init.MemInc = DMA_MINC_ENABLE; //增加内存地址寄存器 hdma_sdmmc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; //外围数据对齐:Word hdma_sdmmc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; //内存数据对齐:Word hdma_sdmmc1.Init.Mode = DMA_PFCTRL; //外围流量控制方式 hdma_sdmmc1.Init.Priority = DMA_PRIORITY_LOW; //优先等级:低 hdma_sdmmc1.Init.FIFOMode = DMA_FIFOMODE_ENABLE; //FIFO模式使能 hdma_sdmmc1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; //FIFO阈值完整配置 hdma_sdmmc1.Init.MemBurst = DMA_MBURST_INC4; hdma_sdmmc1.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_sdmmc1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } __HAL_LINKDMA(sdHandle,hdmarx,hdma_sdmmc1); __HAL_LINKDMA(sdHandle,hdmatx,hdma_sdmmc1); /* SDMMC1中断初始化*/ HAL_NVIC_SetPriority(SDMMC1_IRQn, 1, 0);//中断优先级 HAL_NVIC_EnableIRQ(SDMMC1_IRQn); //使能中断 } }
typedef struct { uint32_t CardType; // 类型 uint32_t CardVersion; // 版本 uint32_t Class; // 卡的类 uint32_t RelCardAdd; // 相对卡地址 uint32_t BlockNbr; //以块为单位指定卡容量 uint32_t BlockSize; //块大小(以字节为单位) uint32_t LogBlockNbr; //以块为单位指定卡逻辑容量 uint32_t LogBlockSize; //指定逻辑块大小(以字节为单位) }HAL_SD_CardInfoTypeDef;