如何使用stm32cubemx中文教程生成一个DFU工程

1288人阅读
STM32(31)
本文将根据我的一些理解,针对elm FatFs文件系统做一个初步总结。
2 elm FatFs文件系统介绍
顾名思义FatFs文件系统就是针对FAT文件系统来的,主要是应用于MCU中,STM32官方提供的文件系统就是这个,STM32CubeMx工具也集成了这个文件系统,同时一些国产MCU操作系统中也集成了这个文件系统,比如RTT(rt-thread),它是第三方提供的开源代码,是一个日本人开发的,开源官网为:
FatFs文件系统之所以这么流行,主要是因为它简单易用,移植非常方便。
图1 FatFs Module
如上图,中间绿色部分为FatFs文件系统模块。APP通过FatFs模块来实现对存储模块的读写访问。FatFs模块不但可以管理单个存储设备,同时也可以管理多个,如下图所示:
图2 FatFs可以管理一到多个存储设备
如上图,蓝色部分为FatFs模块,绿色部分为读写外部存储设备的驱动接口。蓝色部分与绿色部分是分开的,也就是说,FatFs是与底层分开的,它是完全抽象出来的独立于HAL层之上的中间件模块。上层APP正是通过这个中间件模块来实现对底层存储模块的访问,而访问的手段或接口集合我们称之为驱动。一个驱动往往与一个具体的存储设备对应,FatFs与驱动是分开的,那么,我们需要将存储设备对应的操作驱动注册或链接到文件系统中,这样,文件系统才知道它底层有这个一个存储设备,并且可以通过这个驱动来操作它,当然,也可以注册多个设备的驱动,如上图右边的图b,这样,文件系统就知道它底层有多个存储设备,并在注册的过程中,为每个驱动分配一个唯一的卷号,以便后面使用卷号来操作存储设备中的文件。
3 FatFs文件系统移植
图3 FatFs源码文件组织
如上图,蓝色部分为FatFs文件系统,ff.h负责对APP提供使用接口,ffconf.h为FatFs文件系统的配置参数,integer.h为FatFs文件系统内部通用数据类型定义,便于跨平台移植,diskio.h负责连接FatFs与存储设备驱动。因此,基于不同的存储设备,实现FatFs与底层驱动的对接是关键。
要实现FatFs与底层驱动的对接,我们首先得为底层存储设备实现一套驱动接口,FatFs为这个底层存储设备驱动专门定义了一个数据结构:
typedef struct
DSTATUS (*disk_initialize) (BYTE);
DSTATUS (*disk_status)
DRESULT (*disk_read)
(BYTE, BYTE*, DWORD, UINT);
#if _USE_WRITE == 1
DRESULT (*disk_write)
(BYTE, const BYTE*, DWORD, UINT);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT (*disk_ioctl)
(BYTE, BYTE, void*);
#endif /* _USE_IOCTL == 1 */
}Diskio_drvTypeD
即初始化,获取状态,读,写,控制着5个操作接口,一套这样的接口(也就是一个驱动)对应着一个存储设备。移植时,用户需要自己根据实际情况来实现这个驱动,当然,如果使用CubeMx来实现对U盘或SD卡读取的功能,CubeMx可以自动生成这个驱动。比如CubeMx为SD卡自动生成sd_diskio.c文件,为U盘则自动生成usbh_diskio.c这个U盘的驱动源码文件,如下:
图4 驱动文件
并在各自驱动文件中定义驱动实例:
const Diskio_drvTypeDef
USBH_Driver =
USBH_initialize,
USBH_status,
USBH_read,
_USE_WRITE == 1
USBH_write,
#endif /* _USE_WRITE == 1 */
_USE_IOCTL == 1
USBH_ioctl,
#endif /* _USE_IOCTL == 1 */
const Diskio_drvTypeDef
SD_Driver =
SD_initialize,
SD_status,
_USE_WRITE == 1
#endif /* _USE_WRITE == 1 */
_USE_IOCTL == 1
#endif /* _USE_IOCTL == 1 */
有了存储设备的驱动实例,接下来我们需要将其注册进FatFs模块中,以便由其管理这两个存储设备。
retSD = FATFS_LinkDriver(&SD_Driver, SD_Path);
retUSBH = FATFS_LinkDriver(&USBH_Driver, USBH_Path);
如上代码就是将SD卡驱动与U盘驱动注册进FatFs模块,注册后,FatFs会为驱动分配一个唯一的盘符路径并返回保存在传入的路径中,如SD_Path,USBH_Path,其内容为”0:/”, “1:/”。这个就是盘符了。
这样就将驱动注册进FatFs模块,接下来检查驱动与HAL之间的BSP,比如SD卡往往是通过一个GPIO口的状态来判断是否当前SD卡是否存在:
bsp_driver_sd.c:
uint8_t BSP_SD_IsDetected(void)
__IO uint8_t status = SD_PRESENT;
if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_Port, SD_DETECT_Pin) != GPIO_PIN_RESET)
status =SD_NOT_PRESENT;
这个是CubeMx无法帮忙自动实现的,需要手动实现。
另外,U盘的供电往往也是通过一个GPIO管脚的输出来控制,这个也需要手动来实现,比如:
usbh_conf.c:
USBH_StatusTypeDef
USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t state)
if (phost-&id == HOST_FS)
if (state == 0)
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay(200);
return USBH_OK;
这样基本移植OK了,下面我们来介绍使用U盘或者SD卡内文件系统需要注意的事项。
4 使用文件系统
在正式访问文件系统之前,我们需要挂载文件系统,U盘内部存在一个FAT32文件系统,SD卡内部也存在一个文件系统,我们需要在U盘或者SD卡插入后来挂载它,并且在其拔出后卸载它。因此,我们需要一个比较可靠的SD卡和U盘拔插检测机制。
U盘和SD卡的拔插检测一般通过在主线程内的一个for循环内来检测,通过判断某一个状态标识,一旦发现插入,则挂载其文件系统到指定路径,挂载时,需要指定一个FATFS变量,这个变量最好使用静态全局变量。卸载是,使用NULL替代FATFS变量,表示卸载,如下U盘挂载与卸载示例:
if (pre_state != Appli_state)
switch(Appli_state)
case APPLICATION_DISCONNECT:
if(f_mount(NULL, USBH_Path, 0) != FR_OK)
USBH_UsrLog("ERROR : Cannot exit FatFs! \n");
case APPLICATION_READY:
if(f_mount(&usbFs, USBH_Path, 0) != FR_OK)
pre_state = Appli_
如上,若第一个参数为NULL,f_mount函数会将第二个参数表示的路径上挂载的文件系统卸载掉。
下面是SD卡的挂载与卸载示例:
curSdCardStatus =BSP_SD_IsDetected();
if(curSdCardStatus !=preSdCardStatus)
switch(curSdCardStatus)
case SD_PRESENT:
BSP_SD_Init();
MountFat32FileSystem();
case SD_NOT_PRESENT:
UnmountFilesystem();
preSdCardStatus =curSdCardS
static int
MountFat32FileSystem(void)
ret =f_mount(&SDFatFs, "0:/", 0);
if(ret!= FR_OK)
if(ret ==FR_DISK_ERR)
Error_Handler();
static int UnmountFilesystem(void)
ret =f_mount(NULL, "0:/", 0);
这里需要注意地是,f_mount函数的第三个参数为1时,表示立即挂载,为0时,表示暂时不挂载,等正真等到后边f_open时才会执行挂载。这里建议在U盘或SD卡插入时先不要立即挂载文件系统,因为在频繁插拔时,立即挂载文件系统容易导致系统出错,为了简化,一般不需要立即挂载,等后边对文件系统访问时,再来挂载也不迟。
最后就是正常使用了,f_open,f_read,f_write等等对文件进行操作,最好能使用绝对路径,如:
fr = f_open(&fil, "1:/mytest.txt", FA_READ | FA_WRITE | FA_CREATE_ALWAYS)
这个表示打开U盘内mytext.txt文件,若不存在,则创建这个文件。盘符”1:/”在这里对应着U盘,”0:/”对应着SD卡,这个在前面提到的注册或者叫链接驱动时,FatFs为驱动分配的唯一盘符,这个是按注册先后顺序自动分配的。
FatFs简单实用,对于MCU来说非常适用。
SD卡若适用DMA,注意DMA中断与SD卡全局中断的优先级,SD卡全局中断优先级一定要高于DMA的中断优先级。
示例源码:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:930698次
积分:9907
积分:9907
排名:第1382名
原创:127篇
转载:14篇
评论:396条
阅读:39387
文章:36篇
阅读:236023
文章:26篇
阅读:114368
(6)(3)(3)(2)(2)(1)(2)(1)(2)(2)(5)(5)(1)(5)(4)(17)(2)(1)(15)(5)(9)(11)(2)(8)(10)(3)(12)(10)(1)转:STM32CubeMX生成代码试用体会 - 单片机论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
转:STM32CubeMX生成代码试用体会
14:15:40  
听了研讨会 CubeMX感觉有点意思,回来试用了下。我用的是STM32F072B-DISCOVERY. Cube最新版本是4.3.1.增加了最新的L0,F042等新器件,和一些Nucleo板和Discovery板。可直接导入。
& && &&&程序实现功能:将接收到的数据发送出去。测试结果如图
& && &&&首先,打开STM32CubeMX,打开串口1。
高级工程师
22:48:10  
确实是方便很多,我用的F4。
09:45:01  
有用就好,,,,,,,,,,,
10:14:10  
然后Project --&Generate Code , 有两个页面选项
10:14:24  
可以生成如上3种工程,我一般用keil .
10:14:46  
以上页面中红框1表示每个外设单独生成一个.c和.h文件,这样层次更明确。红框2中表示把其余不用的pin脚都设置为模拟输入以降低功耗,也选上。
生成工程后会自动生成4个文件夹,如图。其中Drivers就是硬件抽象层,类似于以前的库,都以“hal”结尾。inc和src分别是生成的头文件和包含文件。Projects是工程快捷方式。
10:15:00  
以下是使用以前的库需要做的工作,判断是否接收完毕,发送接收到的数据,等待发送完毕。
10:15:19  
这是用新的CubeMX生成的工程需要添加的函数,串口接收直接使用HAL_UART_Receive( ) , 发送直接用HAL_UART_Transmit( ) .也不需要再加判断接收/发送状态。都包在了函数里面。修改响应的参数即可。但首次使用难免会不熟,我也是看了HAL里面的UART例程函数才知道可以调用这两个函数的,再看看原型,基本就懂了。
总体来说,硬件抽象层的这些函数,宏定义比起以前的库文件还是有很多的不同。但总体里说感觉还是会减少一些工作量。后面有工程时会具体再试一下。
10:16:22  
分享完成,,,,,,,,,,,
自动驾驶技术大战硝烟弥漫,一直以来都是汽车行业竞赛的新热点。
大牌的汽车品牌纷纷参战,也吸引了众多科技公司加入战场。
我们来看看近期分别有那些最新动态:
Uber将与德国车企戴姆勒(Daimler)联手打造无人驾驶汽车。
丰田与铃木将共同研发无人驾驶等技术
在举国欢庆的长假里,科技圈发生了那些重磅事件?
1、MV公布自动驾驶年终报告,谷歌Waymo依旧保持领先;2、CMU AI系统Libratus击败世界顶级德州扑克玩家;3、波士顿动力推轮式机器人Handle曝光,用轮子取代双足;
更多内容,点击详情来了解吧
中国电子业在80年代后得到迅速发展,近20年的持续、快速增长,让很多中国年轻人选择电子工程师作为自己的职业。
很多年轻的工程师中,不少人对35岁之后的职业发展方向感到忧虑。
Powered by用STM32CubeMX快速生成一个U盘模拟程序_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
用STM32CubeMX快速生成一个U盘模拟程序
上传于||文档简介
&&STM32 CubeMX 快速生成一个U盘,使用内部flash
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩6页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 stm32cubemx 的文章

 

随机推荐