下面是一个使用 C 语言实现的 GD32 SDIO 初始化函数,这个函数可以作为 SDNAND 初始化的基础。
sdio_init.c
#include "gd32f4xx.h"
#include <stdbool.h>
/**
* @brief 初始化SDIO接口用于连接SDNAND
* @param 无
* @retval bool: 初始化成功返回true,失败返回false
*/
bool sdio_sdnand_initialize(void)
{
/* 使能外设时钟 */
rcu_periph_clock_enable(RCU_SDIO);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);
/* 配置SDIO引脚 - PC8:CLK, PC9:CMD, PC10-12:DAT0-3 */
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE,
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
gpio_af_set(GPIOC, GPIO_AF_12, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
/* 配置SDIO参数 */
sdio_deinit(SDIO);
/* 设置SDIO时钟分频 - 初始化为低频率(400kHz)用于初始化 */
uint32_t sdio_clk_div = (SystemCoreClock / 400000) - 2; // 计算分频系数得到~400kHz
if(sdio_clk_div < 0) sdio_clk_div = 0;
/* 初始化SDIO结构体 */
sdio_parameter_struct sdio_init_struct;
sdio_init_struct.sdio_bus_width = SDIO_BUS_WIDTH_1B; // 初始化为1位宽
sdio_init_struct.sdio_clock_div = sdio_clk_div; // 分频系数
sdio_init_struct.sdio_clock_edge = SDIO_CLOCK_EDGE_RISING; // 上升沿采样
sdio_init_struct.sdio_clock_power_save = SDIO_CLOCK_POWER_SAVE_DISABLE;
sdio_init_struct.sdio_hardware_flow_control = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
/* 应用初始化配置 */
sdio_init(SDIO, &sdio_init_struct);
/* 使能SDIO */
sdio_enable(SDIO);
/* 初始化超时计数器 */
uint32_t timeout = 100000;
/* 等待SDIO就绪 */
while(!sdio_flag_get(SDIO, SDIO_FLAG_READY) && timeout--) {
if(timeout == 0) {
return false; // 初始化超时
}
}
return true; // 初始化成功
}
这个函数完成了以下关键步骤:
使用此函数后,你可以继续发送 SD 卡初始化命令(如 CMD0、CMD8 等)来完成 SDNAND 的初始化过程。注意,这个函数假设使用的是 GD32F4 系列微控制器,如果使用其他系列,可能需要调整引脚配置和时钟使能部分。