LPC55S69的SD卡操作,需要使用FatFs文件系统,官方提供了个例子,是可用的,这里做少量改动,以便于实际使用。
一、导入FatFs_SDCard例子。
把例子中的fatfs文件夹,拷贝到自己的工程中。
二、增加组件和设置源文件搜索路径。
1、增加SD卡的相关组件。
2、设置源文件的搜索路径。
在includes和general都要添加fatfs_include路径。
三、引脚。
四、代码。
1、fatfs_sdcard.h
#ifndef FATFS_SDCARD_H_
#define FATFS_SDCARD_H_
#include <stdio.h>
#include <string.h>
#include "fsl_sd.h"
#include "fsl_debug_console.h"
#include "ff.h"
#include "diskio.h"
#include "fsl_sd_disk.h"
#include "board.h"
#include "pin_mux.h"
#include <stdbool.h>
#include "fsl_iocon.h"
/* buffer size (in byte) for read/write operations */
#define BUFFER_SIZE (100U)
extern FATFS g_fileSystem; /* File system object */
extern FIL g_fileObject; /* File object */
extern SDK_ALIGN(uint8_t g_bufferWrite[SDK_SIZEALIGN(BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
extern SDK_ALIGN(uint8_t g_bufferRead[SDK_SIZEALIGN(BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
extern const sdmmchost_detect_card_t s_sdCardDetect;
extern FRESULT error;
extern UINT bytesWritten;
extern UINT bytesRead;
extern const TCHAR driverNumberBuffer[];
extern TCHAR * fileName;
void fatfs_sdcard_init(void);
void fatfs_sdcard_read(void);
void fatfs_sdcard_write(void);
status_t sdcardWaitCardInsert(void);
#endif /* FATFS_SDCARD_H_ */
2、fatfs_sdcard.c
#include "fatfs_sdcard.h"
FATFS g_fileSystem; /* File system object */
FIL g_fileObject; /* File object */
SDK_ALIGN(uint8_t g_bufferWrite[SDK_SIZEALIGN(BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
SDK_ALIGN(uint8_t g_bufferRead[SDK_SIZEALIGN(BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
const sdmmchost_detect_card_t s_sdCardDetect = {
.cdType = BOARD_SD_DETECT_TYPE,
.cdTimeOut_ms = (~0U),
};
FRESULT error;
UINT bytesWritten;
UINT bytesRead;
const TCHAR driverNumberBuffer[3U] = {SDDISK + '0', ':', '/'};
TCHAR * fileName = "/config.txt";
void fatfs_sdcard_init(void) {
static uint8_t initFlag = 0;
if(initFlag == 0) {
CLOCK_EnableClock(kCLOCK_InputMux);
CLOCK_AttachClk(BOARD_SDIF_CLK_ATTACH);
CLOCK_SetClkDiv(kCLOCK_DivSdioClk, (uint32_t)(SystemCoreClock / FSL_FEATURE_SDIF_MAX_SOURCE_CLOCK + 1U), true);
initFlag = 1;
}
if (sdcardWaitCardInsert() != kStatus_Success) {
PRINTF("\r\nPlease insert a card into board.\r\n");
}
if (f_mount(&g_fileSystem, driverNumberBuffer, 0U)) {
PRINTF("Mount volume failed.\r\n");
}
#if (FF_FS_RPATH >= 2U)
error = f_chdrive((char const *)&driverNumberBuffer[0U]);
if (error) {
PRINTF("Change drive failed.\r\n");
}
#endif
}
void fatfs_sdcard_write(void) {
uint8_t i;
PRINTF("Write.\r\n");
error = f_open(&g_fileObject, (const TCHAR*)fileName, (FA_WRITE | FA_CREATE_ALWAYS));
if (error) {
if (error == FR_EXIST) {
PRINTF("File exists.\r\n");
} else {
PRINTF("Open file failed.\r\n");
}
fatfs_sdcard_init();
error = f_open(&g_fileObject, (const TCHAR*)fileName, (FA_WRITE | FA_CREATE_ALWAYS));
}
for(i=0;i<8;i++) { // Writting Bytes
g_bufferWrite[i] = '0' +i;
}
error = f_write(&g_fileObject, g_bufferWrite, sizeof(g_bufferWrite), &bytesWritten);
if ((error) || (bytesWritten != sizeof(g_bufferWrite))) {
PRINTF("Write file failed. \r\n");
}
if (f_close(&g_fileObject)) {
PRINTF("\r\nClose file failed.\r\n");
}
}
void fatfs_sdcard_read(void) {
uint8_t i;
PRINTF("Read.\r\n");
error = f_open(&g_fileObject, (const TCHAR*)fileName, FA_READ);
if (error) {
if (error == FR_EXIST) {
PRINTF("File exists.\r\n");
} else {
PRINTF("Open file failed.\r\n");
}
fatfs_sdcard_init();
error = f_open(&g_fileObject, (const TCHAR*)fileName, FA_READ);
}
if (f_lseek(&g_fileObject, 0U)) {
PRINTF("Set file pointer position failed. \r\n");
}
memset(g_bufferRead, 0U, sizeof(g_bufferRead));
error = f_read(&g_fileObject, g_bufferRead, sizeof(g_bufferRead), &bytesRead);
if ((error) || (bytesRead != sizeof(g_bufferRead))) {
PRINTF("Read file failed. \r\n");
}
for(i=0;i<8;i++) { // Read Bytes
PRINTF("%c",g_bufferRead[i]);
}
if (f_close(&g_fileObject)) {
PRINTF("\r\nClose file failed.\r\n");
}
}
status_t sdcardWaitCardInsert(void) {
g_sd.host.base = SD_HOST_BASEADDR;
g_sd.host.sourceClock_Hz = SD_HOST_CLK_FREQ;
g_sd.usrParam.cd = &s_sdCardDetect;
if (SD_HostInit(&g_sd) != kStatus_Success) {
PRINTF("\r\nSD host init fail\r\n");
return kStatus_Fail;
}
SD_PowerOffCard(g_sd.host.base, g_sd.usrParam.pwr);
if (SD_WaitCardDetectStatus(SD_HOST_BASEADDR, &s_sdCardDetect, true) == kStatus_Success) {
PRINTF("\r\nCard inserted.\r\n");
SD_PowerOnCard(g_sd.host.base, g_sd.usrParam.pwr);
} else {
PRINTF("\r\nCard detect fail.\r\n");
return kStatus_Fail;
}
return kStatus_Success;
}
3、main.c
#include "fatfs_sdcard.h"
int main(void) {
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitPins();
BOARD_BootClockPLL150M();
BOARD_InitDebugConsole();
PRINTF("FATFS SDCard example.\r\n");
fatfs_sdcard_init();
fatfs_sdcard_write();
fatfs_sdcard_read();
while(1){
}
}
五、说明。
编译、调试、运行后,可以在控制台上看到以下现象。
在SD卡中写入字符0~7,再读出来。
修改g_bufferWrite和g_bufferRead的值,再调用fatfs_sdcard_write()和fatfs_sdcard_read(),即可方便读写SD卡。
六、其它问题。
1、读写SD卡需要将g_bufferWrite和g_bufferRead都要做好4字符对齐,每次读写的字节数均可以被4整除,而且要小于512字节,否则读写速度很慢。
2、测试用的SD卡为32G。