STM32通过SDIO读取SD卡,FATFS文件管理系统

STM32cubemx配置FATFS,读取SD卡:

1 准备工具:

	STM32CubeMx,keil,正点原子STM32F103,SD卡。

2打开cubemx配置工程:

2.1 配置时钟

选择高速外部时钟HSE,石英晶体。

配置时钟树。
配置时钟树

2.2 SDIO

选择4线传输。
选择4线传输
2.2.1 参数配置:
在 Parameter Settings 进行具体参数配置。

1、Clock transition on which the bit capture is made: Rising transition(上升沿)。主时钟 SDIOCLK 产生 CLK 引脚时钟有效沿选择,可选上升沿或下降沿,它设定 SDIO 时钟控制寄存器(SDIO_CLKCR)的 NEGEDGE 位的值,一般选择设置为上升沿。

2、SDIO Clock divider bypass: Disable。时钟分频旁路使用,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 BYPASS 位。如果使能旁路,SDIOCLK 直接驱动 CLK 线输出时钟;如果禁用,使用 SDIO_CLKCR 寄存器的 CLKDIV 位值分频 SDIOCLK,然后输出到 CLK 线。一般选择禁用时钟分频旁路。这里选择失能。后面选择分频得到时钟频率。

**3、SDIO Clock output enable when the bus is idle: Disable the power save for the clock。**节能模式选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 PWRSAV 位的值。如果使能节能模式,CLK 线只有在总线激活时才有时钟输出;如果禁用节能模式,始终使能 CLK 线输出时钟。这里功耗要求不大,所以失能它。

**4、SDIO hardware flow control: The hardware control flow is disabled。**硬件流控制选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 HWFC_EN 位的值。硬件流控制功能可以避免 FIFO 发送上溢和下溢错误。

5、SDIOCLK clock divide factor: 6。时钟分频系数,它设定 SDIO_CLKCR 寄存器的 CLKDIV 位的值,设置 SDIOCLK 与 CLK 线输出时钟分频系数:CLK 线时钟频率=SDIOCLK/([CLKDIV+2])。

SD卡在初始化时频率要求低于400KHz,初始化过后可以改为高频率,最高一般位25MHz。所以我们在上面选择分频时,要注意频率不能超过25MHz,SDIOCLK为72MHz.

2.3 配置DMA

在这里插入图片描述

选择循环模式(Circular),方向内存到外设(Memory)。
Priority:
当发生多个 DMA 通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,可以在 DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以上的 DMA 通道请求设置的优先级一样,则他们优先级取决于通 道编号,编号越低优先权越高,比如通道 0 高于通道 1。在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级。
1、Mode:
Normal 表示单次传输,传输一次后终止传输。
Circular 表示循环传输,传输完成后又重新开始继续传输,不断循环永不停止。(选择这个)
2、Increment Address:
Peripheral 表示外设地址自增。
Memory 表示内存地址自增。(选择这个)
3Data Width:
Byte 一个字节。
Half Word 半个字,等于两字节。
Word 一个字,等于四字节。(选择这个)

2.4配置中断

在这里插入图片描述

3FATFS

3.1参数配置

Function Parameters保持默认
1、Locale and Namespace Parameters:
CODE_PAGE(Code page on target): Simplified Chinese GBK(DBCS,OEM,Windows) 支持简体中文编码
USE_LFN(Use Long Filename): Enabled with dynamic working buffer on the STACK 支持长文件名,并指定使用栈 空间为缓冲区。
其他保持不变。

缓存工作区为什么放在栈?其实fatfs提供了三个选项:BSS,STACK , HEAP,根据个人情况选一个。在BSS上启用带有静态工作缓冲区的LFN,不能动态分配。如果选择了HEAP(堆)且自己有属于自己的malloc就去重写ff_memalloc  ff_memfree函数。如果是库的malloc就不需要。一般都选择使用STACK(栈),能动态分配。当使用堆栈作为工作缓冲区时,请注意堆栈溢出。

2、Physical Drive Parameters:
VOLUMES(Logical drivers): 2 指定物理设备数量,这里设置为 1,预留 SD 卡
MAX_SS(Maximum Sector Size): 512 指定扇区大小的最大值。SD 卡扇区大小一般都为 512 字节,SPI Flash 芯片扇区大小一般设置为 4096 字节,所以需要把 _MAX_SS 改为 512
MIN_SS(Minimum Sector Size): 512 指定扇区大小的最小值
其他保持不变。

3.2配置SD卡检测引脚

如果不配置,生成工程时会报错,就算硬件没有设计,也要随便配置一个引脚位检测引脚。后面生成工程后,要在代码里把它屏蔽掉。

现将该引脚在芯片上配置位输入模式

4 生成工程

1、增大栈空间
在这里插入图片描述
2、
在这里插入图片描述
这里要勾选 .c/h。
在这里插入图片描述

5打开工程,屏蔽引脚检测代码

在这里插入图片描述
然后我们就可以在main.c里添加测试代码了:
先不着急我们先来了解一下FATFS,SDIO的一些接口函数。

FatFs API
1.1 f_mount

功能 在FatFs模块上注册、注销一个工作区(文件系统对象)
函数定义 FRESULT f_mount(FATFS* fs, const TCHAR* path, BYTE opt)
参数 fs:工作区(文件系统对象)指针
path:注册/注销工作区的逻辑驱动器号
opt:注册或注销选项
返回 操作结果。 FR_OK 成功,其他失败。

1 .2f_open
功能 创建/打开一个文件对象
函数定义 FRESULT f_open(FIL* fp, const TCHAR* path, BYTE mode)
参数 fp:将被创建的文件对象结构的指针
path:文件名指针,指定将创建或打开的文件名
mode:访问类型和打开方法,由一下标准的一个组合指定的
返回 操作结果 FR_OK 成功,其他失败。
模式 描述
FA_READ 指定读访问对象。可以从文件中读取数据。 与FA_WRITE 结 合可以进行读写访问。
FA_WRITE 指定写访问对象。可以向文件中写入数据。与FA_READ 结合 可以进行读写访问。
FA_OPEN_EXISTING 打开文件。如果文件不存在,则打开失败。(默认)
FA_OPEN_ALWAYS 如果文件存在,则打开;否则,创建一个新文件。
FA_CREATE_NEW 创建一个新文件。如果文件已存在,则创建失败。
FA_CREATE_ALWAYS 创建一个新文件。如果文件已存在,则它将被截断并覆盖。

1.3 f_close
功能 关闭一个打开的文件
函数定义 FRESULT f_close(FIL* fp)
参数 fp:指向将被关闭的已打开的文件对象结构的指针
返回 操作结果 FR_OK 成功,其他失败。

1.4 f_read
功能 从一个打开的文件中读取数据
函数定义 FRESULT f_read(FIL* fp, void* buff, UINT btr, UINT* br)
参数 fp:指向将被读取的已打开的文件对象结构的指针
buff:指向存储读取数据的缓冲区的指针
btr:要读取的字节数
br:指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数
返回 操作结果 FR_OK 成功,其他失败。

1.5 f_write
功能 写入数据到一个已打开的文件
函数定义 FRESULT f_write(FIL* fp, void* buff, UINT btw, UINT* bw)
参数 fp:指向将被写入的已打开的文件对象结构的指针
buff:指向存储写入数据的缓冲区的指针
btw:要写入的字节数
bw:指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数
返回 操作结果 FR_OK 成功,其他失败。

1.6 f_gets
功能:从文件中读取字符串
函数定义 TCHAR* f_gets(TCHAR* str, int size, FIL* fp)
参数 fp:指向将被写入的已打开的文件对象结构的指针
str:指向存储读字符串缓冲区的指针
size:读缓冲区的字节数

1.7 f_tell()
功能:获取文件的当前指针位置相对文件首地址的偏移。
函数定义:TCHAR* f_tell(FIL* fp)
参数 fp:指向将被写入的已打开的文件对象结构的指针

1.8 f_lseek()
功能:移动文件的读写指针
函数定义:FRESULT f_lseek(FIL* fp,DWORD offset)
参数 fp:指向将被写入的已打开的文件对象结构的指针
offset: 偏移文件起始地址的字节数。

1.9 f_eof()
功能:测试一个文件是否达到末尾
函数定义:FRESULT f_eof(FIL* fp)
参数fp:指向将被写入的已打开的文件对象结构的指针
返回值: 0:没有达到末尾
1:达到了末尾。

1.10 f_size()
功能;获取一个文件的大小

1.11 f_putc()
功能:写一个字符

1.12 f_puts()
功能:写一个字符串。

。。。这里就不一一列举了。

6 添加代码

在这里插入图片描述

/* 在main前面添加如下代码*/
/* USER CODE BEGIN PTD */
FATFS fs;                       /* FatFs 文件系统对象 */
FIL file;                       /* 文件对象 */
FRESULT f_res;                  /* 文件操作结果 */
uint16_t fnum;                      /* 文件成功读写数量 */
BYTE ReadBuffer[1024] = {0};    /* 读缓冲区 */
BYTE WriteBuffer[] =            /* 写缓冲区 */
    "hello word\r\n";
uint16_t file_memory=0;
/* USER CODE END PTD */

/*在main里面添加如下代码*/
 /* USER CODE BEGIN 2 */
	printf("\r\n****** FatFs Example ******\r\n\r\n");
	//在外部 SD 卡挂载文件系统,文件系统挂载时会对 SD 卡初始化
  f_res = f_mount(&fs, "0:", 1);
	if(f_res == FR_OK)
	{
		printf("挂载成功\r\n");
		f_res = f_open(&file, "0:120_0811.wav", FA_OPEN_EXISTING | FA_READ);
		if(f_res == FR_OK)
		{
			printf("文件打开成功\r\n");
			file_memory=f_size(&file);
			printf("文件大小:%d\r\n",file_memory);
		}
	}
  /* USER CODE END 2 */

7 总结

以上就是所有的配置过程,关于SD卡的介绍我这里就不做阐述了,大家感兴趣可以去看看其他博主写的。这里我借鉴了http://t.csdn.cn/dnIQU这篇文章,这位博主写的很好。

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
STM32F4基于SDIO总线的读写SD卡需要使用FATFS文件系统。要实现这个功能,首先需要配置STM32F4的SDIO接口以及相应的GPIO引脚。接下来,我们可以按照以下步骤进行读写SD卡: 1. 初始化SDIO接口:初始化SDIO控制器,并设置时钟和数据传输属性。 2. 初始化GPIO引脚:配置SDIO通信需要使用的GPIO引脚,包括CMD线、CLK线、以及数据线(D0-D3)。 3. 初始化SD卡:使用SDIO发送SD卡初始化命令,以便与SD卡进行通信。这个过程包括等待SD卡响应、发送上电命令、以及读取SD卡的OCR(操作条件寄存器)。 4. 检查SD卡状态:通过发送CMD13命令,读取SD卡状态信息。这个过程可以确保SD卡正常工作并准备好读取或写入数据。 5. 挂载文件系统:使用FATFS库中的函数,将SD卡上的文件系统挂载到指定的逻辑驱动器。 6. 打开文件:使用FATFS库中的函数,打开指定的文件。 7. 读取或写入数据:使用FATFS库中的函数,读取或写入数据到SD卡上的文件。 8. 关闭文件:使用FATFS库中的函数,关闭文件。 9. 卸载文件系统:使用FATFS库中的函数,卸载SD卡上的文件系统。 需要注意的是,在进行读写操作时,需要确保SD卡已经插入并且正确连接到SDIO接口上。此外,还需要根据SD卡的规格以及相应的存储格式,进行适当的读写操作。 以上就是基于SDIO总线的读写SD卡的基本步骤。通过使用FATFS库,我们可以很方便地实现对SD卡的读写操作,以便进行数据存储和读取。希望这个回答能够对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值