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] = '