基于FreeRTOS与MQTT的物联网技术应用系列——步进电机控制(三)SD卡驱动、FatFS等的移植和ini配置文件读取的实现

STM32+FreeRTOS基于SD卡与FatFS的配置文件管理实践 在嵌入式系统开发中,参数配置管理是影响设备灵活性与维护效率的关键环节。传统将参数写死在固件中的方式,在批量部署和现场调试时往往效率低下。通过引入文件系统,将配置参数外置到SD卡中,并采用轻量级的ini格式进行存储,既能实现参数免编译修改,又提升了系统的可维护性。文章从文件系统在单片机中的基础应用切入,详细阐述FatFS的移植要点、SD卡驱动对接以及ini解析器设计原理,并结合FreeRTOS任务调度特性,分析多任务环境下文件访问的互斥与时间戳处理方案。该技术路径在STM32平台上成功驱动步进电机控制,展示了 阅读详情

本文实现了基于STM32F107VC的金牛开发板的基于SPI模式的SD卡驱动和FatFS的移植,以及利用minini库对ini配置信息文件进行读取。

因为后面连接网络需要相关配置参数,而且可能随时发生变化,这些参数不可能固定在程序中,所以,我们现在把它放在sd卡中,以便随时更改。

IDE环境为: MDK v5.23
硬件环境:基于STM32F107VC的金牛开发板

一、添加SD卡驱动代码、移植FatFS

为了节省时间,就不造轮子了,直接使用网上共享的spi和sd驱动代码、FatFS源代码。
这部分源代码摘自:
STM32_SD_FATFS_LCD_TOUCH
备用地址:STM32_SD_FATFS_LCD_TOUCH

把这个源代码下来,解压。
把STM32_SD_FATFS_LCD_TOUCH.rar\User\SD_CARD\src 目录下的spi.c、sdcard.c文件和
STM32_SD_FATFS_LCD_TOUCH.rar\User\SD_CARD\inc 目录下的spi.h、sdcard.h文件都复制到我们工程的BSP目录下,并把spi.c、sdcard.c加入工程的BSP组。

在spi.h中加入:

#include "stm32f10x_spi.h"

然后下载FatFS官方源码:
http://elm-chan.org/fsw/ff/arc/ff13.zip

解压后重命名整个文件夹为FatFS,并把它复制到我们工程的third_party目录下。

在IDE上添加一个组,名字为:third_party/FatFS,添加third_party/FatFS/source目录下的diskio.c、ff.c这两个文件。
其中ff.c是具体fat文件系统的实现,diskio.c是文件系统硬件驱动接口实现。

接下来,把STM32_SD_FATFS_LCD_TOUCH.rar\User\fatfs 目录下的diskio.h和diskio.c文件复制到third_party/FatFS/Source下面来,覆盖原同名文件。

这样就直接使用来源于网上的SD卡驱动接口实现了。

然后,把third_party/FatFS/source这个路径添加到IDE的包含路径中。
编译一下可以通过。

移植完了。写个demo测试一下。

首先参考网上的例程,写一个fatfs测试代码,主体放在common.h和common.c中:

common.h

#ifndef _COMMON_H_
#define _COMMON_H_  1

#include "stm32f10x.h"

#define FI 1
#define DI 2

/* Values magic to the Board keys */
#define  NOKEY  0
#define  KEY1   1
#define  KEY2   2
#define  KEY3   3
#define  KEY4   4

#define RCC_KEY1                                    RCC_APB2Periph_GPIOD
#define GPIO_KEY1_PORT                              GPIOD    
#define GPIO_KEY1                                   GPIO_Pin_3

#define RCC_KEY2                                    RCC_APB2Periph_GPIOA
#define GPIO_KEY2_PORT                              GPIOA  
#define GPIO_KEY2                                   GPIO_Pin_8

#define RCC_KEY3                                    RCC_APB2Periph_GPIOC
#define GPIO_KEY3_PORT                              GPIOC    
#define GPIO_KEY3                                   GPIO_Pin_13 

#define RCC_KEY4                                    RCC_APB2Periph_GPIOA
#define GPIO_KEY4_PORT                              GPIOA    
#define GPIO_KEY4                                   GPIO_Pin_0 

#define GPIO_KEY_ANTI_TAMP                          GPIO_KEY3
#define GPIO_KEY_WEAK_UP                            GPIO_KEY4


uint8_t GetKey(void);
void Sys_Soft_Reset(void);
void get_file_name(uint8_t *file_name,uint8_t length,uint8_t type);
uint8_t check_file_name(uint8_t *file_name,uint8_t length);

void format_disk(void);
void creat_file(void);
void delete_file(void);
void list_file(void);
void get_disk_info(void);
void creat_dir(void);
void edit_file(void);
void read_file(void);


int InitMQTTServerInfo(void);

#endif

common.c

#include "spi.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include "ff.h"
#include "integer.h"
#include "diskio.h"
#include <string.h>
#include "FreeRTOS.h"
#include "serial.h"

//#define _DEBUG
#include "dprintf.h"

/* Handle to the com port used by both tasks. */
static xComPortHandle xPort = NULL;

/* The Rx task will block on the Rx queue for a long period. */
#define comRX_BLOCK_TIME            ( ( TickType_t ) 0xffff )



void edit_file(void)
{
    FATFS fs;
    FIL file;
    FRESULT res; 
    DIR dirs;
    FILINFO finfo;
    signed char key = 0;
    char path[20];

    uint32_t index = 0x00;
    uint32_t reindex = 0x00;
    uint8_t file_buff[512] = {0};

    uint32_t files_num = 0;
    uint8_t length;
    res = f_mount(&fs,"",0);
    if (res != FR_OK)
    {
        printf("\r\n¹ÒÔØÎļþϵͳʧ°Ü,´íÎó´úÂë: %u",res);
        return;
    }
    res = f_opendir(&dirs,"/");
    printf("\r\n------------ÎļþÁбí------------");
    if (res == FR_OK) 
    {
        while ((f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0]) 
        {
            if (finfo.fattrib & AM_DIR)//Èç¹ûÊÇÎļþ¼Ð 
            { 
                continue;
            } 
            else 
            {   
                files_num++;
                //ÏÔʾÎļþÃû,ÏÔʾÎļþʵ¼Ê´óС ,Îļþʵ¼Ê´óС²ÉÓÃËÄÉáÎåÈë·¨
                printf("\r\n/%12s%7ld KB ",  &finfo.fname[0],(finfo.fsize+512)/1024);
            }
        }
        if( files_num == 0 )//ÎÞÎļþ
        {
            printf("\r\nÎÞÎļþ!");    
        }
    }
    else
    {
        printf("\r\n´ò¿ª¸ùĿ¼ʧ°Ü!");
        printf("\r\n´íÎó´úÂë: %u",res);
    }
    printf("\r\nÊäÈëÒª±à¼­ÎļþÈ«Ãû,ÒԻسµ½áÊø...");
    get_file_name((uint8_t *)path,length,FI);
    res = f_open(&file,path,FA_READ | FA_WRITE);
    if (res == FR_OK)
    {   
        printf("\r\n´ò¿ªÎļþ %s ³É¹¦",path);
        printf("\r\nÏÖÔÚÊÇÎļþ±à¼­×´Ì¬,ÇëÊäÈëҪдÈëµÄÊý¾Ý!");       
        printf("\r\n°´ESC»òÕßCtrl+C½áÊø±à¼­!\r\n");

        while(1)
        {       
            if(xSerialGetChar( xPort, &key, comRX_BLOCK_TIME )== pdFALSE)  
            {
                continue;
            }

            if ((key == 0x1B) && (index == 0x00))//key ESC
            {
                printf("\r\nÊý¾Ý»¹Ã»ÓÐÊäÈë,ÏÖÔÚ´¦Óڱ༭ģʽ...");                               
                continue;
            }
            else if ((key == 0x1B)) //key ESC
            {
                printf("\r\n±£´æÊý¾Ý...");
                res = f_write(&file,file_buff,index,&reindex);
                if ((res == FR_OK) && (reindex == index))
                {
                    printf("\r\n±£´æÊý¾Ý³É¹¦!");
                    f_close(&file);
                    index = 0x00;
                    reindex = 0x00;                                 
                }
                else
                {
                    printf("\r\n±£´æÊý¾Ýʧ°Ü!");
                    printf("\r\n´íÎó´úÂë: %u",res);                                 
                }
                break;
            }
            else if (key == 0x03) //key Ctrl+C
            {
                printf("\r\n½áÊøÎļþ±à¼­!");
                printf("\r\n±£´æÊý¾Ý...");
                res = f_write(&file,file_buff,index,&reindex);
                if ((res == FR_OK) && (reindex == index))
                {
                    printf("\r\n±£´æÊý¾Ý³É¹¦!");
                    f_close(&file);
                    index = 0x00;
                    reindex = 0x00;                                 
                }
                else
                {
                    printf("\r\n±£´æÊý¾Ýʧ°Ü!");
                    printf("\r\n´íÎó´úÂë: %u",res);                                 
                }
                break;
            }
            else if ((key < 0x21) || (key > 0x80))
            {
                continue;
            }
            else
            {
                file_buff[index++] = key;
                printf(
基于STM32-RTX-FATFS-U盘操作实现.ini文件读写操作 使用STM32生成可以读写INI文件的工程,工程基于RTX嵌入式系统和Fatfs文件操作系统。 立即下载

相关推荐

STM32F107_Freertos_LED_V1.0 实现FreeRTOS的移植

基于STM32F107VCT6的FreeRTOS的移植与实现。工程为MDK Keil V5的,功能为建立三个小任务,实现LED按不同的时间闪烁,运行正常。可以作为移植后的模板程序使用。

金牛开发板原理图STM32F107VCT6

金牛开发板原理图STM32F107VCT6(网络资料,非原创,仅供电子爱好者参考借鉴)

freertos7.00 + stm32f107 + 12864 (nt7534)+320240 +sed1335

freertos7.00 + stm32f107 + 驱动12864 (nt7534) + 320240 (sed1335) 液晶屏完整工程(song370FreeRTOS)

金牛开发板自编 SPI AT45DB161D

金牛开发板 STM32F107 keil uv3 v3.9 固件库 v3.3.0

直线型一阶倒立摆1---从理论到实践的桥梁

本文深入探讨了直线型一阶倒立摆在控制理论中的核心地位,从非线性控制、鲁棒性到实时反馈等关键问题。通过实际案例和硬件搭建指南,帮助读者理解从理论到实践的过渡,特别适合控制工程初学者和研究人员。文章还提供了算法选型建议和硬件避坑手册,是掌握倒立摆控制的实用指南。

weixin_29047545的博客 314

c转c++——蓝桥杯

在这里,`int &i` 表示 `i` 是一个整型的引用变量,而不是一个拷贝,这意味着在循环中对 `i` 的修改会影响到数组 `arr` 中对应位置的值。arr则是需要遍历的数组。一、为啥要转C++:之前只学过C语言,然后为了蓝桥杯苦哈哈敲了C好久,偶然听了别人的意见去看了一下C++后发现简直太香了——C++不像C要把底层逻辑自己敲出来,而是可以直接调用STL函数库(比如排序,C语言可能要敲个几十行代码C++直接用调用sort函数就可以了),而且C++完全兼容C语言,里面的语法全部可以用C替换。

smwymzqbyl的博客 2034

第1期技术: DQN算法原理及实现过程

利用神经网络近似值函数的方法表示为: V^(s,w)≈Vπ(s)q^(s,a,w)≈qπ(s,a) \hat{V}(s, w) \approx V_{\pi}(s) \\ \hat{q}(s, a, w) \approx q_{\pi}(s, a) V^(s,w)≈Vπ​(s)q^​(s,a,w)≈qπ​(s,a) 那么具体的工作过程是怎样实现的? 以及如何从端到端的过程,本文将讲解Deep Q Network(DQN, 而这正是由DeepMind于2013年和2015年分别提出的两篇论文《Playi

深度强化学习实验室:一个“开源开放、共享共进”的强化学习学术组织。 4951

告别抓包:一个Xposed模块教你监控抖音App的本地数据变化

本文详细介绍了如何利用Xposed框架开发模块,实现抖音App本地数据监控的技术方案。通过Hook关键方法,开发者可以实时获取用户信息、推荐算法参数等核心数据,无需Root设备即可高效调试。文章包含完整的环境配置、代码实现和优化技巧,为移动应用开发与测试提供创新解决方案。

weixin_27015733的博客 380

FreeRTOS任务调度实战:如何让STM32同时处理温湿度采集、OLED显示和云端通信

本文通过一个基于STM32的物联网终端项目,详细讲解了如何利用FreeRTOS实现多任务调度,同时处理温湿度采集、OLED显示和云端通信。文章深入探讨了任务规划、堆栈分配、信号量与消息队列等核心机制,并重点优化了ESP8266通信任务的非阻塞设计与稳定性,为构建响应迅速、运行可靠的嵌入式系统提供了实战指南。

weixin_29188043的博客 328

MTK平台TP驱动设备树与GPIO配置实战解析

本文详细解析了MTK平台TP驱动开发中的设备树与GPIO配置实战。通过DCT工具配置GPIO引脚,结合设备树节点定义触摸参数,并分享驱动移植、编译调试技巧及常见问题解决方案,帮助开发者快速掌握MTK触摸驱动开发核心。

ice55的博客 224

基于 YOLOv26 的陶瓷产品缺陷检测系统:智能视觉质检方案

本文提出了一种基于YOLOv26深度学习模型的陶瓷产品智能缺陷检测系统。该系统针对陶瓷生产中的裂纹、气泡、釉面缺陷等8类常见质量问题,采用YOLOv26目标检测算法实现高精度自动化检测。系统架构包含数据采集、预处理、YOLOv26检测和后处理四个模块,具有多类别分类、实时推理和强鲁棒性等技术优势。文章详细介绍了数据预处理与增强方法,并提供了Python代码实现示例。该方案可显著提升陶瓷产品质量检测效率,替代传统人工检测方式,为陶瓷制造业提供智能化质检解决方案。

一键难忘的博客 780

Android AVB 分析(十三)dm-verity 设备是如何映射的?

在上一篇《Android AVB 分析(十二)嵌入式设备安全中的 dm-verity 简介》介绍 dm-verity 原理的时候,作者提供了一个 dm-verity 演示的例子。本篇我们基于 AOSP 源码 `android-13.0.0_r41` 实际编译生成的 Google Pixel 7 (“panther”) 设备的 system 分区镜像进行 dm-verity 设备验证实战。

洛奇看世界 2431

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

上一篇: 基于FreeRTOS与MQTT的物联网技术应用系列——步进电机控制(二)FreeRTOS v9.0.0 的移植
下一篇: 基于FreeRTOS与MQTT的物联网技术应用系列——步进电机控制(四)FreeRTOS系统下LwIP-1.4.1的移植
假面侠
博客等级 码龄20年 129粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值