一、硬件接线
SD NAND通常兼容SD协议,可通过SDIO接口或SPI接口连接。以下为两种模式的硬件连接方法:
1. SDIO接口模式(推荐)
优点:高速传输,支持4位数据总线。
引脚分配(以STM32F407为例):
CLK(时钟):PC12 (SDIO_CK)
CMD(命令):PD2 (SDIO_CMD)
DAT0-DAT3(数据线):PC8-PC11 (SDIO_D0-D3)
VCC:3.3V电源
GND:共地
注意:
确保电源稳定,建议添加100nF滤波电容。
DAT线需外部上拉4.7kΩ电阻(部分STM32内部已集成,若通信不稳定需外接)。
2. SPI接口模式
优点:接线简单,适合低速场景。
引脚分配(以SPI1为例):
SCK:PA5 (SPI1_SCK)
MISO:PA6 (SPI1_MISO)
MOSI:PA7 (SPI1_MOSI)
CS:自定义GPIO(如PE3)
VCC/GND:同上。
注意:SPI时钟频率建议初始化为<400kHz,初始化后可提高。
二、软件配置(基于STM32CubeMX+HAL库)
1. SDIO模式配置
时钟配置:
启用SDIO外设,时钟源选择PLL48CLK,分频至≤400kHz初始化,后续可提升至24MHz。
GPIO设置:
配置SDIO相关引脚为复用功能,高速模式。
DMA配置(可选):
为SDIO添加DMA通道,提升传输效率。
2. SPI模式配置
启用SPI外设,模式为全双工,主机模式。
配置GPIO:SCK、MISO、MOSI为复用推挽输出,CS为普通GPIO输出。
三、代码实现
1. SDIO模式初始化
#include "stm32f4xx_hal.h"
SD_HandleTypeDef hsd;
void SDIO_Init() {
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 = SDIO_INIT_CLK_DIV; // 如0x76(400kHz)
if (HAL_SD_Init(&hsd) != HAL_OK) {
Error_Handler();
}
// 切换到4位总线模式
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK) {
Error_Handler();
}
}
2. SPI模式读写示例
// SPI发送接收单字节
uint8_t SPI_TransmitReceive(uint8_t data) {
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = data;
while (!(SPI1->SR & SPI_SR_RXNE));
return SPI1->DR;
}
// SD卡CS控制
void SD_CS_Enable() { HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); }
void SD_CS_Disable() { HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); }
3. 集成FATFS文件系统
添加FATFS中间件:
在CubeMX中启用FATFS,选择SD Card模式。
实现diskio.c接口:
填充disk_initialize(), disk_read(), disk_write()等函数,调用HAL_SD接口。
// diskio.c示例(SDIO模式)
DSTATUS disk_initialize(BYTE pdrv) {
if (HAL_SD_Init(&hsd) == HAL_OK) {
return RES_OK;
}
return RES_ERROR;
}
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) {
if (HAL_SD_ReadBlocks(&hsd, buff, sector, count, SD_TIMEOUT) == HAL_OK) {
return RES_OK;
}
return RES_ERROR;
}
四、注意事项
电源稳定:SD NAND工作时峰值电流可达100mA,确保3.3V电源质量。
信号完整性:
短线连接(<10cm),避免干扰。
走线等长,尤其是SDIO模式下的DAT线。
文件系统安全:
写操作后调用f_sync()强制写入物理设备。
避免突然断电,可能导致FAT表损坏。
错误处理:
检查HAL_SD函数返回值,超时时间设置为≥500ms。
使用HAL_SD_GetCardState()检测卡状态。
时钟配置:
SDIO时钟频率需符合卡规格(多数支持0-25MHz)。
五、调试技巧
问题:卡无法识别
检查CMD和DAT0是否连接正确。
用逻辑分析仪捕捉SDIO波形,观察初始化流程。
尝试降低时钟频率。
问题:写入数据错误
检查电源电压是否跌落。
确认文件系统已正确挂载(f_mount())。
使用HAL_SD_Erase()擦除卡再测试。
通过以上步骤,可稳定驱动SD NAND并实现文件存储功能。