手把手教你创建SD_FS文件系统
开发环境:CubeMX5.6.1(packages--F4--1.25.0)、Keil5(5.30.0.0--Keil.STM32F4xx_DFP.2.9.0)
硬件开发板平台:野火STM32F429IG-V2
第1步:打开Cube MX软件
第2步:新建工程
第3步:选择自己使用的芯片并开始工程配置
第4步:开启仿真接口
第5步:选择外部高速时钟HSE
第6步:配置USART串行通讯(为方便后续调试和使用打印函数printf();)
7、
#include "stdio.h"
/***************** 发送字符串 **********************/
void Usart_SendString(uint8_t *str)
{
unsigned int k=0;
do
{
HAL_UART_Transmit(&huart1,(uint8_t *)(str + k) ,1,1000);
k++;
} while(*(str + k)!='\0');
}
///重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口DEBUG_USART */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
return (ch);
}
///重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
int ch;
HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);
return (ch);
}
#include "stdio.h"
//char SDPath[4]; /* SD逻辑驱动器路径 */
FATFS fs; /* FatFs文件系统对象 */
FIL fnew; /* 文件对象 */
FRESULT res_sd; /* 文件操作结果 */
UINT fnum; /* 文件成功读写数量 */
BYTE ReadBuffer[1024]={0}; /* 读缓冲区 */
BYTE WriteBuffer[] = /* 写缓冲区*/
"欢迎使用野火STM32 F429开发板 今天是个好日子,新建文件系统测试文件\r\n";
/* USER CODE BEGIN 2 */
//链接驱动器,创建盘符
FATFS_LinkDriver(&SD_Driver, SDPath);
//在外部SD卡挂载文件系统,文件系统挂载时会对SD卡初始化
res_sd = f_mount(&fs,"0:",1);
/*----------------------- 格式化测试 ---------------------------*/
/* 如果没有文件系统就格式化创建创建文件系统 */
if(res_sd == FR_NO_FILESYSTEM)
{
printf("》SD卡还没有文件系统,即将进行格式化...\r\n");
/* 格式化 */
// res_sd=f_mkfs("0:",0,0);
if(res_sd == FR_OK)
{
printf("》SD卡已成功格式化文件系统。\r\n");
/* 格式化后,先取消挂载 */
res_sd = f_mount(NULL,"0:",1);
/* 重新挂载 */
res_sd = f_mount(&fs,"0:",1);
}
else
{
printf("《《格式化失败。》》\r\n");
while(1);
}
}
else if(res_sd!=FR_OK)
{
printf("!!SD卡挂载文件系统失败。(%d)\r\n",res_sd);
printf("!!可能原因:SD卡初始化不成功。\r\n");
while(1);
}
else
{
printf("》文件系统挂载成功,可以进行读写测试\r\n");
}
/*----------------------- 文件系统测试:写测试 -----------------------------*/
/* 打开文件,如果文件不存在则创建它 */
printf("\r\n****** 即将进行文件写入测试... ******\r\n");
res_sd = f_open(&fnew, "0:FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );
if ( res_sd == FR_OK )
{
printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\r\n");
/* 将指定存储区内容写入到文件内 */
res_sd=f_write(&fnew,WriteBuffer,sizeof(WriteBuffer),&fnum);
if(res_sd==FR_OK)
{
printf("》文件写入成功,写入字节数据:%d\n",fnum);
printf("》向文件写入的数据为:\r\n%s\r\n",WriteBuffer);
}
else
{
printf("!!文件写入失败:(%d)\n",res_sd);
}
/* 不再读写,关闭文件 */
f_close(&fnew);
}
else
{
printf("!!打开/创建文件失败。\r\n");
}
/*------------------- 文件系统测试:读测试 ------------------------------------*/
printf("****** 即将进行文件读取测试... ******\r\n");
res_sd = f_open(&fnew, "0:FatFs读写测试文件.txt", FA_OPEN_EXISTING | FA_READ);
if(res_sd == FR_OK)
{
// LED_GREEN;
printf("》打开文件成功。\r\n");
res_sd = f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum);
if(res_sd==FR_OK)
{
printf("》文件读取成功,读到字节数据:%d\r\n",fnum);
printf("》读取得的文件数据为:\r\n%s \r\n", ReadBuffer);
}
else
{
printf("!!文件读取失败:(%d)\n",res_sd);
}
}
else
{
printf("!!打开文件失败。\r\n");
}
/* 不再读写,关闭文件 */
f_close(&fnew);
/* 不再使用文件系统,取消挂载文件系统 */
f_mount(NULL,"0:",1);
/* 操作完成,停机 */
/* USER CODE END 2 */
//
//在FatFs模块上注册、注销一个工作区(文件系统对象)
FRESULT f_mount (
FATFS* fs, /* 【工作区(文件系统对象)指针】Pointer to the file system object (NULL:unmount)*/
const TCHAR* path, /* 【注册/注销工作区的逻辑驱动器号】Logical drive number to be mounted/unmounted */
BYTE opt /*【注册或注销选项】 Mode option 0:Do not mount (delayed mount), 1:Mount immediately */
)
//创建/打开一个文件对象
FRESULT f_open (
FIL* fp, /* 【将被创建的文件对象结构的指针】Pointer to the blank file object */
const TCHAR* path, /* 【文件名指针,指定将创建或打开的文件名】Pointer to the file name */
BYTE mode /*访问类型和打开方法,由一下标准的一个组合指定的 Access mode and file open mode flags */
)
/*
#define FA_READ 0x01/*指定读访问对象。可以从文件中读取数据。 与FA_WRITE 结 合可以进行读写访问*/
#define FA_WRITE 0x02/*指定写访问对象。可以向文件中写入数据。与FA_READ 结合 可以进行读写访问*/
#define FA_OPEN_EXISTING 0x00/*打开文件。如果文件不存在,则打开失败。(默认) */
#define FA_CREATE_NEW 0x04/*创建一个新文件。如果文件已存在,则它将被截断并覆盖*/
#define FA_CREATE_ALWAYS 0x08/*无法创建为新文件*/
#define FA_OPEN_ALWAYS 0x10/*如果文件存在,则打开;否则,创建一个新文件*/
#define FA_OPEN_APPEND 0x30/*创建一个新文件。如果文件已存在,则创建失败*/
*/
//关闭一个打开的文件
FRESULT f_close (
FIL* fp /* 【fp 指向将被关闭的已打开的文件对象结构的指针】Pointer to the file object to be closed */
)
//从一个打开的文件中读取数据
FRESULT f_read (
FIL* fp, /* 【指向将被读取的已打开的文件对象结构的指针】Pointer to the file object */
void* buff, /* 【指向存储读取数据的缓冲区的指针】Pointer to data buffer */
UINT btr, /* 【要读取的字节数】Number of bytes to read */
UINT* br /* 【指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数】Pointer to number of bytes read */
)
//写入数据到一个已打开的文件
FRESULT f_write (
FIL* fp, /* 【指向将被写入的已打开的文件对象结构的指针】Pointer to the file object */
const void* buff, /*【指向存储写入数据的缓冲区的指针】 Pointer to the data to be written */
UINT btw, /* 【要写入的字节数】Number of bytes to write */
UINT* bw /* 【指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数】Pointer to number of bytes written */
)