【STM32F7 实战系列】工程的建立及分析

  • 999
  • LV4工程师
  • |      2015-09-30 18:31:41
  • 浏览量 4331
  • 回复:4


【STM32F7 实战系列】工程建立及分析  


        我们继续STM32F746G discovery kit的学习。上一教程介绍了开发环境的建立及使用,体验了下载自带例程到开发板的过程。我们接着学习建立工程及对工程的分析。

        作为技术积累,希望大家多多在论坛发言,共同发展壮大社区。往期教程及参考资料如下,大家想了解相关内容的可以查看。


        相关资源参考:

         STM32F746 Discovery kit官方资料

         STM32F7系列官网资料

        【STM32F7 入门系列】结构体系初探(一)

        【STM32F7 入门系列】结构体系初探(二)

        【STM32F7 实战系列】STM32F746G Disco试用体验

        【STM32F7 实战系列】开发环境的搭建及使用

        



一、 使用RTE建立工程


        打开MDK,点击菜单栏Project>>New μVision Project。输入工程名称后点击保存。然后接下来选择单片机型号并点击保存。此时会弹出运行库管理程序(Manage Run-Time Environment),我们根据需要勾选需要的组件。这个管理程序在以后也可以随时打开进行配置。

        一般的功能组件还依赖其它组件,所以只选中一个是不能正常工作的。比如仅选一个BSP中的LED驱动,很显然那是不可能正常工作的,还需要选启动文件、CMSIS、HAL中的GPIO驱动等等。我们需要解决这些依赖关系。当你选择某一组件时,如果它依赖其它组件,在组件列表中会以橙色警告,并且在Validation Output窗口会提示还需要选那些其它的组件。在Validation Output窗口中手动点击依赖组件将自动跳转到对应列表处,然后我们手动勾选添加。如下图假设我们先只选择BSP中的emWin LCD组件,提示还需要添加其它依赖组件。


【STM32F7 实战系列】工程的建立及分析




        如果不想一个一个手动添加,也可以点击Resolve按钮,将自动解析并添加依赖组件。但有时依赖的库出现多选一的情况,这时需要们手动选择一个。



【STM32F7 实战系列】工程的建立及分析



        对于我们本次教程,先建立一个操作GPIO的工程。添加组件如下:

        CMSIS>>CORE

        Device>>Startup

        Device>>STM32Cube Framework(API)>>Classic

        Device>>STM32Cube HAL>>Common/Cortex/GPIO/PWR/RCC

        如下图所示,Sel.中所有选项均变为绿色,则表示添加无误。点击OK。


【STM32F7 实战系列】工程的建立及分析




        CMSIS>>CORE 是必加的。其包含并提供了内核相关的API,如外设访问接口、NVIC等。

        Device>>Startup同样是必须的。它包含了startup_xxx.s启动文件,定义了复位操作及中断向量表等。该组件还包含了system_xxx.c,该c文件主要与时钟、内存总线等方面相关。

        然后我们在工程中添加C文件。如下图所示,在工程串口中右键Source Group 1,选择“Add new item…”。可以使用模板建立main.c。使用模板时选择“User Code Template”。 也可以选择C文件类型,建立一个空白的main.c文件。


【STM32F7 实战系列】工程的建立及分析




        添加完各个文件之后,我们开始我们的程序。

        首先main.c要包含设备头文件“stm32f7xx.h”。该文件是F7系列头文件,包含了该系列的一些通用的声明或定义,同时需要通过define不同的宏来选择包含具体的设备的头文件:


【STM32F7 实战系列】工程的建立及分析




        上图中116~124行代码:通过判断不同的宏定义即可选择编译包含不同的头文件。STM32F7-DISCO应该包含stm32f746xx.h。所以我们应该把80行的 /* #define STM32F746xx */注释符号去掉。但由于该文件是RTE组件文件,默认是只读属性,不能修改。当然可以修改其只读属性然后修改,但不建议这样做。作为标准组件,以后利用RTE建立其它工程,可能还会包含这个文件,那时可能你已经忘记修改过这个文件了。还有个方法,就是在“Options for Target”的C++选项卡Define这个字段:



【STM32F7 实战系列】工程的建立及分析



        和上边的方法一样,我们还需要定义USE_HAL_DRIVER字段,以支持HAL驱动。该选择编译的代码部分在stm32f7xx.h的179~181行。

        这样我们就完成了利用RTE建立工程。关于使用该方法建立的工程还有一些其他问题可以和大家讨论一下。我使用的Keil版本为5.16a,RTE中的CMSIS版本为4.4.0(其中CMSIS-Core的版本是4.20 )。该版本与ST的STM32Cube_FW_F7_V1.1.0中的CMSIS版本不一样。从4.4.0的头文件我们发现:core_cm7.h包含了core_cmInstr.h等头文件,而后者包含cmsis_armcc.h(只有4.4.0中才有该文件)等文件。蛋疼的是cmsis_armcc.h等文件里边用到的某些字段却是在core_cm7.h中定义,但它却未包含任何头文件。如果包含了core_cm7.h就重复循环包含文件了,并且这些头文件都是只读属性,keil不允许更改。既然如此,为何编译不报错呢?那只能是使能了自动包含头文件功能了。打开Options for Target的C/C++选项卡中,No Auto Includes果然没有被勾选。那我们勾选它,禁止自动包含,编译后果然报错。WTF! 于是我去ARM官网下载资料,没有4.4.0的,只有低版本的。keil自带的文档也无此处的说明。对于Keil MDK里的这个CMSIS4.4.0真是无语。尝试更换组件为CMSIS4.3.0就没有这样的问题。待弄清楚后我再来补贴说明,同时欢迎大家留言讨论。





二、手动建立工程:


        我们可以通过手动添加STM32cubeF7提供的文件来建立工程。新建工程时,在选择完芯片型号后,不要去配置RTE,直接关掉就行。然后我们手动添加所需要的文件。


        官方手册的推荐使用STM32CubeF7中的Template来建立工程。

        1、 拷贝Cube中的Template中的各个文件、CMSIS相关的文件、HAL驱动、中间层驱动等文件,放到你的工程目录下,并在Options for Target的C/C++选项卡添加头文件路径。

        2、配置、裁剪组件。一般在名为xxx_conf.h中,通过注释掉某些宏定义来裁剪。

        3、初始化HAL驱动、系统时钟等。

        4、编写你自己的应用程序。


        下面我们来看看具体步骤,拷贝STM32Cube_FW_F7_V1.1.0中以下文件到你的工程目录:

        (因为不能显示反斜杠,所以用冒号“:“来代替。)

        1、HAL相关文件(名字含有“_template”的文件,要把这个字段删掉):

            Drivers:STM32F7xx_HAL_Driver:Src:所有文件

            Drivers:STM32F7xx_HAL_Driver:Inc:所有文件

        2、 CMSIS相关文件:

            Drivers:CMSIS:Include:所有文件(有几个用不到)

            Drivers:CMSIS:Device:ST:STM32F7xx:Include:所有文件(有几个用不到)

            Drivers:CMSIS:Device:ST:STM32F7xx:Source:Templates:arm:startup_stm32f746xx.s

            Drivers:CMSIS:Device:ST:STM32F7xx:Source:Templates:system_stm32f7xx.c

        3、 官方Template文件(也可以手动建立main.c):

            Projects:STM32746G-Discovery:Templates:Inc:stm32f7xx_it.h

            Projects:STM32746G-Discovery:Templates:Src:stm32f7xx_it.c

            Projects:STM32746G-Discovery:Templates:Src:main.c

            Projects:STM32746G-Discovery:Templates:Inc:mian.h

        (Template中的stm32f7xx_hal_msp.c、stm32f7xx_hal_conf.h在第1步的拷贝HAL驱动文件时,已经拷贝过来。所以这里不用拷贝)

        4、 在Options for Target中添加头文件路径


        我们简单看下模板的main函数中做了哪些初始化工作:


【STM32F7 实战系列】工程的建立及分析




        模板使用4个函数来初始化各个功能、模块。

        1、 MPU_Config()

        该函数主要是和函数CPU_CACHE_Enable()(使能Core的L1-cache)配合使用的。在我的教程《 STM32F7系列MCU结构体系初探(一) 》对此有说明。并不是所有的存储区域都能被缓存,内存区域类型属性要符合要求。SRAM内存映射区域在复位后的默认属性即可支持被缓存,这里调用MPU_Config()是修改其属性为Write-Through(SRAM复位后的默认属性为Write-Back),这里的Write-Through和Write-Back是通过Cache写回数据的两种方式:WT即CPU更新Cache数据同时,也同步更新SRAM中的数据。WB即CPU只标记Cache区域,等有新数据或者Cache Flush时才更新SRAM中的数据。关于更多Cache的介绍,请关注我的教程贴系列。当然,若不使用Cache就不用调此函数。

        2、 CPU_CACHE_Enable()

        顾名思义,该函数就是使能L1-cache的。可以一定程度上提高执行效率。当然,不使用也能正常工作。

        3、 HAL_Init()

        对于HAL层驱动的初始化,模板中的该函数做了以下几件事:1、通过宏定义ART_ACCLERATOR_ENABLE来判断是否使能ART,默认是使能的。该宏定义定义在stm32f7xx_hal_conf.h头文件中。2、通过NVIC设置中断组。3、使能SysTick并配置中断优先级。4、调用HAL_MspInit()。使用STMCubeMX工具生成的初始化代码将在这里被调用。或者你自己写点什么相关代码都可以。

        4、 SystemClock_Config()

        该函数主要是初始化系统时钟。主要调用了HAL_RCC_OscConfig()和HAL_RCC_ClockConfig()两个函数。这两个函数是HAL驱动层提供的。


        本次教程介绍了如何建立工程,下次将以GPIO等外设为例介绍STM32 HAL驱动的使用等。




  • 0
  • 收藏
  • 举报
  • 分享
我来回复

登录后可评论,请 登录注册

所有回答 数量:3
asdfmgh 2017-08-13
不错哦。
0   回复
举报
发布
奔跑小蜗牛 2015-10-07
很详细。。。
0   回复
举报
发布
我们都一样 2015-10-01
不错哦 
0   回复
举报
发布
x
收藏成功!点击 我的收藏 查看收藏的全部帖子