NXP S32K1052CVL5B 通过 FlexSPI 接口连接 SDNAND,典型引脚分配如下:
| S32K1052 引脚 | 功能 | SDNAND 引脚 |
|---|---|---|
| PTD0 | FlexSPI_A_SCLK | CLK |
| PTD1 | FlexSPI_A_SS0 | CSN |
| PTD2 | FlexSPI_A_DATA0 | IO0 |
| PTD3 | FlexSPI_A_DATA1 | IO1 |
| PTD4 | FlexSPI_A_DATA2 | IO2 |
| PTD5 | FlexSPI_A_DATA3 | IO3 |
| PTD6 | - | WP# |
| PTD7 | - | HOLD# |
10kΩ VCC ────┬─────┬───── 3.3V │ │ │ 上拉 │ │ S32K ───┤ │ SDNAND 引脚 │ └─────────┐ │ │ └─────┬─────────┘ │ 0.1μF │ GND
// 初始化系统时钟void SystemInit(void) {
// 配置系统时钟为80MHz
CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);}// 主函数初始化int main(void) {
// 硬件初始化
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
// 初始化FlexSPI
FLEXSPI_Init(EXAMPLE_FLEXSPI);
FLEXSPI_Reset(EXAMPLE_FLEXSPI);
// 初始化SDNAND
if (SDNAND_Init() != kStatus_Success) {
PRINTF("SDNAND初始化失败
");
for(;;);
}
// 应用程序主循环
for(;;) {
// 应用逻辑
}}// FlexSPI配置结构static flexspi_device_config_t deviceConfig = {
.flexspiRootClk = 80000000,
.csHoldTime = 3u,
.csSetupTime = 3u,
.columnAddressWidth = 0u,
.deviceModeCfgEnable = false,
.deviceModeType = 0,
.deviceModeArg = 0,
.configCmdEnable = false,
.configModeType = 0,
.waitTimeCfgCommands = 0,
.configCmdArg = 0,
.configCmdLen = 0,
.readSampleClkSrc = kFLEXSPI_ReadSampleClk_LoopbackFromDqsPad,
.sampleClockDelayShift = 0,
.sflashPadType = kFLEXSPI_SFlash_4Pads,
.serialClkFreq = kFLEXSPI_Clock_50MHz,
.sflashA1Size = 0x2000000, // 32MB};// SDNAND初始化函数status_t SDNAND_Init(void) {
status_t status;
// 配置FlexSPI端口
status = FLEXSPI_SetFlashConfig(EXAMPLE_FLEXSPI, &deviceConfig, NULL);
if (status != kStatus_Success) {
return status;
}
// 执行SDNAND初始化序列
status = SDNAND_Reset();
if (status != kStatus_Success) {
return status;
}
// 读取设备ID验证连接
uint8_t deviceId[5];
status = SDNAND_ReadID(deviceId);
if (status != kStatus_Success) {
return status;
}
PRINTF("SDNAND设备ID: %02X %02X %02X %02X %02X
",
deviceId[0], deviceId[1], deviceId[2], deviceId[3], deviceId[4]);
return kStatus_Success;}// SDNAND擦除块函数status_t SDNAND_EraseBlock(uint32_t blockAddress) {
flexspi_transfer_t flashXfer;
uint32_t commandSequence[3];
// 构建擦除命令序列
commandSequence[0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x60,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
commandSequence[1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xD8,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
commandSequence[2] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x10,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
// 配置传输参数
flashXfer.deviceAddress = blockAddress;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 3;
flashXfer.seqIndex = 0;
flashXfer.data = NULL;
flashXfer.dataSize = 0;
// 执行擦除命令
return FLEXSPI_TransferBlocking(EXAMPLE_FLEXSPI, &flashXfer);}// SDNAND页编程函数status_t SDNAND_WritePage(uint32_t pageAddress, const uint8_t *data, uint32_t size) {
flexspi_transfer_t flashXfer;
uint32_t commandSequence[2];
// 构建页编程命令序列
commandSequence[0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x80,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
commandSequence[1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x10,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
// 配置传输参数
flashXfer.deviceAddress = pageAddress;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 2;
flashXfer.seqIndex = 0;
flashXfer.data = (uint8_t *)data;
flashXfer.dataSize = size;
// 执行页编程命令
return FLEXSPI_TransferBlocking(EXAMPLE_FLEXSPI, &flashXfer);}// SDNAND页读取函数status_t SDNAND_ReadPage(uint32_t pageAddress, uint8_t *data, uint32_t size) {
flexspi_transfer_t flashXfer;
uint32_t commandSequence[2];
// 构建页读取命令序列
commandSequence[0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
commandSequence[1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x30,
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00);
// 配置传输参数
flashXfer.deviceAddress = pageAddress;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 2;
flashXfer.seqIndex = 0;
flashXfer.data = data;
flashXfer.dataSize = size;
// 执行页读取命令
return FLEXSPI_TransferBlocking(EXAMPLE_FLEXSPI, &flashXfer);}// 配置FatFs文件系统FATFS fs; // 文件系统对象FIL file; // 文件对象FRESULT res; // 文件操作结果UINT bytesWritten; // 写入字节数UINT bytesRead; // 读取字节数// 挂载文件系统void MountFileSystem(void) {
// 挂载SDNAND设备
res = f_mount(&fs, "", 1);
if (res != FR_OK) {
PRINTF("挂载文件系统失败, 错误码: %d
", res);
// 格式化文件系统
res = f_mkfs("", FM_ANY, 0, NULL, 0);
if (res == FR_OK) {
PRINTF("文件系统格式化成功
");
res = f_mount(&fs, "", 1);
if (res == FR_OK) {
PRINTF("文件系统重新挂载成功
");
}
}
} else {
PRINTF("文件系统挂载成功
");
}}// 文件操作示例void FileOperationsExample(void) {
// 创建并写入文件
res = f_open(&file, "test.txt", FA_CREATE_ALWAYS | FA_WRITE);
if (res == FR_OK) {
const char *message = "Hello, SDNAND!";
res = f_write(&file, message, strlen(message), &bytesWritten);
if (res == FR_OK) {
PRINTF("写入成功, 写入字节数: %d
", bytesWritten);
}
f_close(&file);
}
// 读取文件
res = f_open(&file, "test.txt", FA_READ);
if (res == FR_OK) {
char buffer[100];
res = f_read(&file, buffer, sizeof(buffer), &bytesRead);
if (res == FR_OK) {
buffer[bytesRead] = '