收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
| FA_CREATE_ALWAYS | 创建一个新文件。如果文件已存在,则它将被截断并覆盖。 |
1.3.3 f_close
功能 | 关闭一个打开的文件 |
---|---|
函数定义 | FRESULT f_close(FIL* fp) |
参数 | fp:指向将被关闭的已打开的文件对象结构的指针 |
返回 | 操作结果 |
1.3.4 f_read
功能 | 从一个打开的文件中读取数据 |
---|---|
函数定义 | FRESULT f_read(FIL* fp, void* buff, UINT btr, UINT* br) |
参数 | fp:指向将被读取的已打开的文件对象结构的指针buff:指向存储读取数据的缓冲区的指针btr:要读取的字节数br:指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数 |
返回 | 操作结果 |
1.3.5 f_write
功能 | 写入数据到一个已打开的文件 |
---|---|
函数定义 | FRESULT f_write(FIL* fp, void* buff, UINT btw, UINT* bw) |
参数 | fp:指向将被写入的已打开的文件对象结构的指针buff:指向存储写入数据的缓冲区的指针btw:要写入的字节数bw:指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数 |
返回 | 操作结果 |
另外FatFs还有很多API操作函数,在这里不再作详细的介绍,详细信息请查看FatFs文件系统官网。
二、新建工程
1. 打开 STM32CubeMX 软件,点击“新建工程”
2. 选择 MCU 和封装
3. 配置时钟
RCC 设置,选择 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)
选择 Clock Configuration,配置系统时钟 SYSCLK 为 72MHz
修改 HCLK 的值为 72 后,输入回车,软件会自动修改所有配置
4. 配置调试模式
非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器
SYS 设置,选择 Debug 为 Serial Wire
三、SDIO
STM32 控制器可以控制使用单线或 4 线传输,本开发板设计使用 4 线传输。
3.1 参数配置
在 Connetivity
中选择 SDIO
设置,并选择 SD 4 bits Wide bus
四线SD模式
此时 SDIO 对应的管脚也被选中。
在 Parameter Settings
进行具体参数配置。
Clock transition on which the bit capture is made: Rising transition
。主时钟 SDIOCLK 产生 CLK 引脚时钟有效沿选择,可选上升沿或下降沿,它设定 SDIO 时钟控制寄存器(SDIO_CLKCR)的 NEGEDGE 位的值,一般选择设置为上升沿
。
SDIO Clock divider bypass: Disable
。时钟分频旁路使用,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 BYPASS 位。如果使能旁路,SDIOCLK 直接驱动 CLK 线输出时钟;如果禁用,使用 SDIO_CLKCR 寄存器的 CLKDIV 位值分频 SDIOCLK,然后输出到 CLK 线。一般选择禁用时钟分频旁路
。
SDIO Clock output enable when the bus is idle: Disable the power save for the clock
。节能模式选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 PWRSAV 位的值。如果使能节能模式,CLK 线只有在总线激活时才有时钟输出;如果禁用节能模式,始终使能 CLK 线输出时钟。
SDIO hardware flow control: The hardware control flow is disabled
。硬件流控制选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 HWFC_EN 位的值。硬件流控制功能可以避免 FIFO 发送上溢和下溢错误。
SDIOCLK clock divide factor: 6
。时钟分频系数,它设定 SDIO_CLKCR 寄存器的 CLKDIV 位的值,设置 SDIOCLK 与 CLK 线输出时钟分频系数:CLK 线时钟频率=SDIOCLK/([CLKDIV+2])。
SDIO_CK 引脚的时钟信号在卡识别模式时要求不超过 400KHz,而在识别后的数据传输模式时则希望有更高的速度(最大不超过 25MHz),所以会针对这两种模式配置 SDIOCLK 的时钟。
这里参数描述建议将SDIOCLK clock divede factor 参数使用默认值为0,SDIOCLK为72MHz,可以得到最大频率36MHz,但请注意,有些型号的SD卡可能不支持36MHz这么高的频率,所以还是要以实际情况而定。
3.2 配置DMA
SDIO 外设支持生成 DMA 请求,使用 DMA 传输可以提高数据传输效率,因此在 SDIO 的控制代码中,可以把它设置为 DMA 传输模式或轮询模式,ST 标准库提供 SDIO 示例中针对这两个模式做了区分处理。
应用中一般都使用DMA 传输模式。
点击 DMA Settings
添加 SDIO 对应 DMA2 的通道4。DMA模式选择循环模式,方向选为内存到外设。
- Priority:
当发生多个 DMA 通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,可以在 DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以上的 DMA 通道请求设置的优先级一样,则他们优先级取决于通 道编号,编号越低优先权越高,比如通道 0 高于通道 1。在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级。 - Mode:
Normal
表示单次传输,传输一次后终止传输。
Circular
表示循环传输,传输完成后又重新开始继续传输,不断循环永不停止。 - Increment Address:
Peripheral
表示外设地址自增。
Memory
表示内存地址自增。 - Data Width:
Byte
一个字节。
Half Word
半个字,等于两字节。
Word
一个字,等于四字节。
3.3 配置NVIC
DMA及SDIO中断设置,原则是全局中断优先级高于DMA中断
四、FATFS
4.1 参数配置
在 Middleware
中选择 FATFS
设置,并勾选 SD Card
配置为SD卡
-
Function Parameters
跳过
-
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
支持长文件名,并指定使用栈空间为缓冲区
- CODE_PAGE(Code page on target): Simplified Chinese GBK(DBCS,OEM,Windows)
缓存工作区为什么放在栈?其实fatfs提供了三个选项:BSS,STACK , HEAP,根据个人情况选一个。
在BSS上启用带有静态工作缓冲区的LFN,不能动态分配。
如果选择了HEAP(堆)且自己有属于自己的malloc就去重写ff_memalloc ff_memfree函数。如果是库的malloc就不需要。
一般都选择使用STACK(栈),能动态分配。
当使用堆栈作为工作缓冲区时,请注意堆栈溢出。
- Physical Drive Parameters:
- VOLUMES(Logical drivers): 2
指定物理设备数量,这里设置为 2,包括预留 SD 卡和 SPI Flash 芯片
- MAX_SS(Maximum Sector Size): 512
指定扇区大小的最大值。SD 卡扇区大小一般都为 512 字节,SPI Flash 芯片扇区大小一般设置为 4096 字节,所以需要把 _MAX_SS 改为 512
- MIN_SS(Minimum Sector Size): 512
指定扇区大小的最小值
- VOLUMES(Logical drivers): 2
4.2 配置SD卡检测引脚
SD卡插入检测引脚,如果不配置一个引脚生成文件时会报错,所以这里即使没有硬件连接,也可以任意设置一引脚使用,生成工程后注释代码。
4.3 增大栈空间
将最小栈空间改到 0x1000
注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环。
4.4 生成代码
输入项目名和项目路径
选择应用的 IDE 开发环境 MDK-ARM V5
每个外设生成独立的 ’.c/.h’
文件
不勾:所有初始化代码都生成在 main.c
勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。
点击 GENERATE CODE 生成代码
五、屏蔽SD卡插入检测代码
由于没有检测SD卡插入的硬件引脚,打开 bsp_driver_sd.c
文件,修改 BSP_SD_IsDetected()
函数,始终返回SD_PRESENT:
六、修改main函数
定义相关变量:
FATFS fs; /\* FatFs 文件系统对象 \*/
FIL file; /\* 文件对象 \*/
FRESULT f_res; /\* 文件操作结果 \*/
UINT fnum; /\* 文件成功读写数量 \*/
BYTE ReadBuffer[1024] = {0}; /\* 读缓冲区 \*/
BYTE WriteBuffer[] = /\* 写缓冲区 \*/
"This is STM32 working with FatFs\r\n";
修改main函数:
/\*\*
\* @brief The application entry point.
\* @retval int
\*/
int main(void)
{
/\* USER CODE BEGIN 1 \*/
/\* USER CODE END 1 \*/
/\* MCU Configuration--------------------------------------------------------\*/
/\* Reset of all peripherals, Initializes the Flash interface and the Systick. \*/
HAL\_Init();
/\* USER CODE BEGIN Init \*/
/\* USER CODE END Init \*/
/\* Configure the system clock \*/
SystemClock\_Config();
/\* USER CODE BEGIN SysInit \*/
/\* USER CODE END SysInit \*/
/\* Initialize all configured peripherals \*/
MX\_GPIO\_Init();
MX\_DMA\_Init();
MX\_USART1\_UART\_Init();
MX\_SDIO\_SD\_Init();
MX\_FATFS\_Init();
/\* USER CODE BEGIN 2 \*/
printf("\r\n\*\*\*\*\*\* FatFs Example \*\*\*\*\*\*\r\n\r\n");
//在外部 SD 卡挂载文件系统,文件系统挂载时会对 SD 卡初始化
f_res = f\_mount(&fs, "0:", 1);
/\*----------------------- 格式化测试 ---------------------------\*/
printf("\r\n\*\*\*\*\*\* Register the file system object to the FatFs module \*\*\*\*\*\*\r\n");
/\* 如果没有文件系统就格式化创建创建文件系统 \*/
if(f_res == FR_NO_FILESYSTEM)
{
printf("The SD card does not yet have a file system and is about to be formatted...\r\n");
/\* 格式化 \*/
f_res = f\_mkfs("0:", 0, 0);
if(f_res == FR_OK)
{
printf("The SD card successfully formatted the file system\r\n");
/\* 格式化后,先取消挂载 \*/
f_res = f\_mount(NULL, "0:", 1);
/\* 重新挂载 \*/
f_res = f\_mount(&fs, "0:", 1);
}
else
{
printf("The format failed\r\n");
while(1);
}
}
else if(f_res != FR_OK)
{
printf(" mount error : %d \r\n", f_res);
while(1);
}
else
{
printf(" mount sucess!!! \r\n");
}
/\*----------------------- 文件系统测试:写测试 -----------------------------\*/
/\* 打开文件,如果文件不存在则创建它 \*/
printf("\r\n\*\*\*\*\*\* Create and Open new text file objects with write access \*\*\*\*\*\*\r\n");
f_res = f\_open(&file, "0:FatFs STM32cube.txt", FA_CREATE_ALWAYS | FA_WRITE);
**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/761e961e75ad35688ce460d769ae559e.png)
![img](https://img-blog.csdnimg.cn/img_convert/aa87ac4eb483fd0e0d21a43c1b230ae7.png)
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
[外链图片转存中...(img-Deb5IRPl-1715908253193)]
[外链图片转存中...(img-SsWlR0pD-1715908253194)]
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**