配置 STM32F407 的 SDIO 时钟和 GPIO 以实现与 SD NAND 通信的步骤如下:
根据 STM32F407 的数据手册,SDIO 默认引脚分配如下:
SDIO 信号 | STM32F407 引脚 | 复用功能 |
---|---|---|
CLK | PC8 | AF12 |
CMD | PD2 | AF12 |
DATA0 | PC9 | AF12 |
DATA1 | PC10 | AF12 |
DATA2 | PC11 | AF12 |
DATA3 | PC12 | AF12 |
SDIO 的时钟源和频率需要精确配置:
__HAL_RCC_SDIO_CLK_ENABLE(); // 使能SDIO时钟__HAL_RCC_GPIOC_CLK_ENABLE(); // 使能GPIOC时钟(CLK、DATA0-3)__HAL_RCC_GPIOD_CLK_ENABLE(); // 使能GPIOD时钟(CMD)
配置 SDIO 时钟分频:
// 初始化时的低频率(400kHz)hsd.Instance->CLKCR |= (0x70 << 0); // 分频系数=112,SDIO_CLK=42MHz/(2×112)≈187kHz// 初始化完成后切换到高速(如24MHz)hsd.Instance->CLKCR |= (0x04 << 0); // 分频系数=4,SDIO_CLK=42MHz/(2×4)=5.25MHz
使用 HAL 库配置 GPIO 为复用功能、高速模式,并启用上拉:
GPIO_InitTypeDef GPIO_InitStruct = {0};// 配置CLK、DATA0-3 (PC8-PC12)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_PULLUP; // 上拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 高速GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; // 复用为SDIO功能HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);// 配置CMD (PD2)GPIO_InitStruct.Pin = GPIO_PIN_2;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
使用SD_HandleTypeDef
结构体配置 SDIO 核心参数:
SD_HandleTypeDef hsd;hsd.Instance = SDIO;hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; // 上升沿采样hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; // 不使用旁路hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; // 禁用时钟省电hsd.Init.BusWide = SDIO_BUS_WIDE_1B; // 初始化为1位宽hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; // 禁用硬件流控hsd.Init.ClockDiv = 0x70; // 初始化分频(约400kHz)if (HAL_SD_Init(&hsd) != HAL_OK) { Error_Handler();}
以下是使用 HAL 库初始化 SDIO 的完整函数:
HAL_StatusTypeDef SDIO_SDNAND_Init(void) { // 使能时钟 __HAL_RCC_SDIO_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); // 配置GPIO GPIO_InitTypeDef GPIO_InitStruct = {0}; // ...(GPIO配置代码,同上)... // 配置SDIO参数 hsd.Instance = SDIO; hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; hsd.Init.BusWide = SDIO_BUS_WIDE_1B; hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; hsd.Init.ClockDiv = 0x70; // 初始化分频(约400kHz) // 初始化SDIO if (HAL_SD_Init(&hsd) != HAL_OK) { return HAL_ERROR; } // 发送初始化命令序列 // ...(发送CMD0、CMD8、ACMD41等命令)... return HAL_OK;}
通过以上步骤,STM32F407 的 SDIO 接口即可与 SD NAND 建立通信。实际应用中,还需根据具体的 SD NAND 型号调整初始化参数和命令序列。
下一篇:SDNAND其他通信方法