第3章 MDK软件与工程模板创建 本章要点 STM32固件库概述 STM32固件库下载 STM32固件库目录结构 Keil MDK软件操作方法 Keil MDK工程模板的创建 Keil MDK软件模拟仿真调试 “工欲善其事,必先利其器”,无论是基于寄存器方式还是基于库函数方式开发STM32应用程序,首先必须选择一个熟悉、完善的开发平台,建立方便、合理的程序工程模板。对于51单片机开发者来说,KeilC是再熟悉不过的。而Keil公司针对32位ARM嵌入式系统推出的Keil MDK开发平台功能强大,基本操作又和KeilC保持兼容,是32位嵌入式单片机开发的首选。建立工程模板的核心内容包含两个方面: 一是必须包含的文件; 二是这些文件对应的路径。 工程模板创建 3.1STM32固件库认知 建立工程模板需要从指定路径找到必要文件,要想很好地完成这一任务,我们需要首先认识STM32固件库。 3.1.1STM32固件库概述 意法半导体公司提供的STM32F10x标准外设库是基于STM32F1系列微控制器的固件库进行STM32F103开发的一把利器。可以像在标准C语言编程中调用printf()一样,在STM32F10x的开发中调用标准外设库的库函数,进行应用开发。相比传统的直接读写寄存器方式,STM32F10x标准外设库不仅明显降低了开发门槛和难度,缩短了开发周期,进而降低开发成本,而且提高了程序的可读性和可维护性,给STM32F103开发带来了极大的便利。毫无疑问,STM32F10x标准外设库是用户学习和开发STM32F103微控制器的第一选择。 STM32固件库是根据CMSIS标准(Cortex Microcontroller Software Interface Standard,ARM Cortex微控制器软件接口标准)而设计的。CMSIS标准由ARM和芯片生产商共同提出,让不同的芯片公司生产的Cortex M3微控制器能在软件上基本兼容。 STM32F10x的固件库是一个或一个以上的完整的软件包(称为固件包),包括所有的标准外设的设备驱动程序,其本质是一个固件函数包(库),它由程序、数据结构和各种宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API(APPlication Programming Interface,应用编程接口)。通过使用固件函数库,无须深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。每个外设驱动都由一组函数组成,这组函数覆盖了该外设的所有功能。每个器件的开发都由一个通用API驱动,API对该驱动程序的结构、函数和参数名称都进行了标准化。 3.1.2STM32固件库下载 意法半导体公司2007年10月发布了V1.0版本的固件库,2008年6月发布了V2.0版的固件库。V3.0以后的版本相对之前的版本改动较大,本书使用目前最为通用的V3.5版本,该版本固件库支持所有的STM32F10x系列。具体下载方法如下: 第一步: 输入www.st.com网址,打开意法半导体官方网站,在首页搜索栏输入stm32f10x,其操作界面如图31所示。 图31搜索资料操作界面 在图31中,单击右侧搜索图标开始搜索,结果如图32所示,其中STM32F10x standard peripheral library记录即为STM32F1的标准外设库。 图32搜索结果页面 打开链接即可进入固件库下载页面,操作结果如图33所示,同时也可以看到,该固件库版本为3.5.0,该版本最为成熟和通用。 图33固件库下载页面 单击图33右边的Get Software按钮,登录并确认著作权之后,即可将该固件库下载到的本机。 需要说明的是: 意法半导体官网资料需要登录才可以下载,如果没有账号还需要注册,当然读者也可以直接在清华大学出版社网站下载本书的教学素材,里面包含STM32内核固件库。 3.1.3STM32固件库目录结构 下载STM32F10x标准外设库并解压后,其目录结构如图34所示,由图可知固件库包含四个文件夹和两个文件。 图34STM32固件库目录结构 两个文件中,stm32f10x_stdperiph_lib_um.chm为已经编译的帮助系统,也就是该固件库的使用手册和应用举例,该文件很重要; 而另一个文件Release_Notes.html是固件库版本更新说明,可以将其忽略。 四个文件夹中,_htmresc文件夹是意法半导体公司的LOGO图标等文件,也可以将其忽略,重要的三个文件夹是Libraries、Project和Utilities,下面对其进行分别介绍。 1. Libraries文件夹 Libraries文件夹用于存放STM32F10x开发要用到的各种库函数和启动文件,其下包括CMSIS和STM32F10x_StdPeriph_Driver两个子文件夹,如图35所示。 图35Libraries文件夹 1) CMSIS子文件夹 CMSIS子文件夹是STM32F10x的内核库文件夹,其核心是CM3子文件夹,其余可以忽略。在CM3子文件夹下有CoreSupport和DeviceSupport两个文件夹,如图36所示。 图36Libraries\CMSIS\CM3目录 (1) CoreSupport文件夹。该文件夹为 CortexM3核内外设函数文件夹,CortexM3内核通用源文件core_cm3.c和CortexM3内核通用头文件core_cm3.h即在此目录下,如图37所示。 图37CMSIS\CM3\CoreSupport目录 上述文件位于CMSIS核心层的核内外设访问层,由ARM公司提供,包含用于访问内核寄存器的名称、地址定义等内容。 (2) DeviceSupport文件夹。该文件夹为 设备外设支持函数文件夹,STM32F0x头文件stm32f10x.h和系统初始化文件system_stm32f10x.c即位于此目录下的ST\STM32F10x文件夹中,如图38所示。 图38DeviceSupport\ST\STM32F10x目录 除了头文件和初始化文件,STM32F10x系列微控制器的启动代码文件,也位于此目录下的ST\STM32F10x\startup\arm文件夹中,如图39所示。例如,本书配套开发板使用的STM32F103ZET6微控制器属于STM32F103的大容量产品,因此,它对应的启动代码文件为startup_stm32f10x_hd.s。 图39STM32F10x启动代码文件目录 上述文件位于CMSIS核心层的设备外设访问层,由意法半导体公司提供,包含片上核外设寄存器名称、地址定义、中断向量定义等。 2) STM32F10x_StdPeriph_Driver文件夹 STM32F10x_StdPeriph_Driver子文件夹为STM32Fl0x标准外设驱动库函数目录,包括了所有STM32F10x微控制器的外设驱动,如GPIO、TIMER、SysTick、ADC、DMA、USART、SPI和I2C等。STM32F10x的每个外设驱动对应一个源代码文件stm32f10x_ppp.c和一个头文件stm32f10x_ppp.h。相应地,STM32F10x_StdPeriph_Driver文件夹下也有两个子目录: src和inc,如图310所示。特别地,除了以上STM32F10x片上外设的驱动以外,CortexM3内核中NVIC的驱动(misc.c和misc.h)也在该文件夹中。 图310Libraries\STM32F10x_StdPeriph_Driver目录 (1) src子目录: src是source的缩写,该子目录下存放意法半导体公司为STM32F10x每个外设而编写的库函数源代码文件,如图311所示。 图311STM32F10x_StdPeriph_Driver\src目录 (2) inc子目录: inc是include的缩写。该子目录下存放STM32F10x每个外设库函数的头文件,如图312所示。 图312STM32F10x_StdPeriph_Driver\inc目录 2. Project文件夹 Project文件夹对应STM32F10x标准外设库体系架构中的用户层,用来存放意法半导体公司官方提供的STM32F10x工程模板和外设驱动示例,包括STM32F10x_StdPeriph_Template和STM32F10x_StdPeriph_Examples两个子文件夹,目录结构如图313所示。 图313STM32F10x_StdPeriph_Lib_V3.5.0\Project文件夹目录 1) STM32F10x_StdPeriph_Template子文件夹 STM32F10x_StdPeriph_Template子文件夹,是意法半导体公司提供的STM32F10x工程模板目录,包括了5个开发工具相关子目录和5个用户应用相关文件,目录结构如图314所示。 图314Project\STM32F10x_StdPeriph_Template文件夹目录 (1) 开发工具相关子目录: 根据使用的开发工具的不同,分为MDKARM、EWARM、HiTOP、RIDE和TrueSTUDIO这5个子目录,每个子目录分别存放对应开发工具下STM32F10x的工程文件。 (2) 用户应用相关文件: 包括main.c、stm32f10x_it.c、stm32f10x_it.h、stm32f10x_conf.h和system_stm32f10x.c这5个文件。无论使用5种开发工具中的哪一个构建STM32F10x工程,用户的具体应用都只与这5个文件有关。这样,在同一型号的微控制器上开发不同应用时,无须修改相关开发工具目录下的工程文件,只需要用新编写的应用程序文件替换这5个文件即可。 2) STM32F10x_StdPeriph_Examples子文件夹 STM32F10x_StdPeriph_Examples子文件夹,是意法半导体公司提供的STM32F10x外设驱动示例目录。该目录包含许多以STM32F10x外设命名的子目录,囊括了STM32F10x所有外设,其目录结构如图315所示。 图315Project\STM32F10x_StdPeriph_Examples目录 每个外设子目录下又包含多个具体驱动示例目录,而每个示例目录下又包含5个用户应用相关文件。意法半导体公司官方的外设驱动示例,不仅是了解和验证STM32外设功能的重要途径,而且给STM32F10x相关外设开发提供了有益的参考。 3. Utilities文件夹 Utilities文件夹用于存放意法半导体公司官方评估板的BSP(Board Support Package,板级支持包)和额外的第三方固件。初始情况下,该文件夹下仅包含意法半导体公司各款官方评估板的板级驱动程序(即STM32_EVAL子文件夹),目录结构如图316所示。 图316Utilities文件夹目录 用户在实际开发时,可以根据应用需求,在Utilities文件夹下增删内容,如删除仅支持意法半导体公司官方评估板的板驱动包,添加由意法半导体公司及其第三方合作伙伴提供的固件协议,包括各种嵌入式操作系统、文件系统、图形接口等,当然也可以不使用其参考模板,自行独立创建工程模板,本书采用的是后者。 3.2工程模板创建 本节介绍Keil MDKARM软件的使用,并创建一个自己的MDK工程模板,该工程模板是后续学习的基础。 3.2.1Keil MDKARM软件简介 Keil MDKARM是适用于基于CortexM、CortexR4、ARM7和ARM9处理器的设备的完整软件开发环境。Keil MDKARM是专为微控制器应用程序开发而设计的,它易于学习和使用,同时具有强大的功能,适用于多数要求苛刻的嵌入式应用程序开发。Keil MDKARM是目前最流行的嵌入式开发工具,集成了业内最领先的技术,包括μVision4集成开发环境与ARM编译器,具有自动配置启动代码、集成Flash烧写模块、强大的Simulation设备模拟、性能分析等功能。 目前Keil MDKARM的最新版本是4.74。4.0以上版本的Keil MDKARM的IDE界面有了很大的改变,并且支持CortexM内核的处理器。Keil MDKARM 4.74界面简洁、美观,实用性更强,对于使用过Keil的读者来说,更容易上手。Keil MDKARM软件主要特点如下: (1) 完美支持CortexM、CortexR4、ARM7和ARM9系列器件。 (2) 行业领先的ARM C/C++编译工具链。 (3) 确定的Keil RTX,小封装实时操作系统(带源码)。 (4) μVision4 IDE集成开发环境,调试器和仿真环境。 (5) TCP/IP网络套件提供多种的协议和各种应用。 (6) 提供带标准驱动类的USB设备和USB主机栈。 (7) 为带图形用户接口的嵌入式系统提供了完善的GUI库支持。 (8) ULINKpro可实时分析运行中的应用程序,且能记录CortexM指令的每一次执行。 (9) 关于程序运行的完整代码覆盖率信息。 (10) 执行分析工具和性能分析器可使程序得到最优化。 (11) 大量的项目例程有助于快速熟悉Keil MDKARM强大的内置特征。 (12) 符合CMSIS (Cortex微控制器软件接口标准)。 本书选择Keil MDKARM 4.74版本的开发工具作为学习STM32的软件。当然,读者也可以到Keil公司网站下载或查看最新的Keil MDKARM软件版本。 3.2.2工程模板的创建 工程模板是我们后续所有项目的基础,正确、合理的工程模板不仅使用起来得心应手,而且有利于结构化程序设计。工程模板除了必须包含的框架体系结构,也有一部分个性化的因素,所以每个人创建的工程模板可能是不同的。 1. 创建工程模板素材 创建工程模板素材主要是内核固件库3.5版,另外还有两个重要的预定义命令,也以文本文档的形式给出来,相关素材均可以在清华大学出版社网站下载。 为了便于叙述,将原固件库的文件夹名STM32F10x_StdPeriph_Lib_V3.5.0更改为简短一些的F10x_Lib_V3.5,以便在书中给出具体的文件路径。 2. 工程模板创建步骤 第一步: 创建或复制文件夹。 (1) 在桌面创建“工程模板”文件夹。 (2) 复制固件库中的Libraries文件夹到工程模板文件夹。 (3) 创建Output文件夹,用于存放输出文件。 (4) 创建Startup文件夹,用于存放启动文件,并复制startup_stm32f10x_hd.s文件到该文件夹中,此文件为大容量芯片的启动文件,文件路径为: F10x_Lib_V3.5\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm。操作结果如图317所示。 图317Startup文件夹 (5) 创建User文件夹,并复制main.c、stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h文件到该文件夹中。上述文件路径为: F10x_Lib_V3.5\Project\STM32F10x_StdPeriph_Template,其操作结果如图318所示。 图318User文件夹 (6) 创建APP文件夹,用于存放用户编写的外设驱动程序。 经过上述步骤创建的工程模板文件夹如图319所示。 图319工程模板文件夹 第二步: 建工程模板文件,建立文档分组。 (1) 在开始/程序或桌面快捷方式中启动Keil μVision4软件,其界面如图320所示。 图320Keil μVision4软件界面 (2) 依次单击菜单栏Project→new μvision Project命令,弹出如图321所示的窗口,表示新建一个工程文件,并需要选择保存路径。此时将保存路径选择为我们在桌面的创建的工程模板文件夹,文件名为“工程模板”。 图321保存新建工程文件 (3) 单击如图321所示的“保存”按钮,弹出选择芯片的对话框,由于开发板使用的是STM32F103ZET6芯片,故选择CPU为STM32F103ZE。 图322CPU芯片选择 (4) 单击图322中的OK按钮,弹出询问对话框,由于后面还需要专门添加此文件,故选择“否”,其操作界面如图323所示。 图323复制启动文件选项 (5) 建立分组并添加文件。 依次单击Project→Manage→components Environment或直接单击工具栏图标打开Manage Project Items对话框,其操作界面如图324所示。 图324添加工程分组对话框 在此对话框中的Groups项中,先删除原来的Source Group 1,然后依添加User、Cmsis、Startup、ST Driver和APP分组,并为每个分组添加相应的源文件。 (1) User: main.c,stm32f10x_it.c。 (2) Cmsis: core_cm3.c,system_stm32f10x.c。 (3) Startup: startup_stm32f10x_hd.s。 (4) ST Driver: stm32f10x_gpio.c、stm32f10x_rcc.c。 (5) APP: 此分组下面还没有文件,由用户编写。 建立分组和添加文件操作完成之后,Keil软件界面如图325所示,在左边的工程浏览窗口,可以看到刚刚创建的分组和相应的文件信息。 图325建立分组和添加文件完成 第三步: 设置输出文件夹,添加预编译变量,包含头文件路径。 (1) 依次单击菜单Project→Options for target命令或直接单击工具栏图标,可以打开如图326所示的对话框。 图326Options for Target 'Target 1'对话框 (2) 在Output选项卡中勾选Create HEX File,并选择输出文件夹为工程模板目录下的output文件夹,其操作界面如图327所示。 图327Output选项卡设置 (3) 在Listing选项卡中单击Select Folder for Listings,并选择输出文件夹为工程模板目录下的output文件夹,操作界面如图328所示。 图328Listing输出文件目录 (4) 在C/C++选项卡中,在Define区域添加两个重要的预编译命令: USE_STDPERIPH_DRIVER。STM32F10X_HD,这两个预编译命令存放在素材文件夹中的“两个重要的预编译指令.txt”文件中,操作界面如图329所示。 图329添加两个重要预编译命令 (5) 在如图329所示的C/C++选项卡中,单击Include Path后面的按钮,打开包含文件夹路径设置对话框。将工程中可能需要用到的头文件所在路径全部包含进来,操作结果如图330所示。 图330包含路径添加结果 (6) 在Debug选项卡中选中Use Simulator单选按钮,其操作界面如图331所示。至此工程文件Options for Target选项已全部配置完成,单击OK按钮退出。 图331Debug选项卡设置 第四步: 创建public.h文件,重写main.c文件,编译调试。 (1) 在Keil μVision4工程文件界面中,依次单击File→New新建一个空白文件,并将其以文件名public.h保存到工程模板的User文件夹下,在public.h文件中输入以下代码。 #ifndef _public_H #define _public_H #include "stm32f10x.h" #endif (2) 将原main.c中的程序删除,写一个main的空函数,并包含公共头文件public.h。 #include "public.h" int main() { } (3) 对整个工程进行编译,结果如图332所示,如果下面的编译输出显示为:“".\工程模板.axf"  0 Error(s), 0 Warning(s).”则表示工程模板创建成功,如有错误则需要返回上面布骤,找出原因并进行更正,直至没有编译错误出现为止。 至此整个工程模板就创建完成了,工程模板对整个嵌入式系统的学习是至关重要的,后面项目学习都是在该模板的基础上进行扩展的,所以大家应该熟练掌握模板的创建方法。 图332编译输出界面 模拟仿真调试 3.3软件模拟仿真 Keil MDKARM同样提供了强大的软件模拟仿真功能,对于暂不具备硬件平台的学习者也可以通过模拟仿真学习嵌入式开发。下面以一个具体实例讲解软件模拟仿真方法。 第一步: 创建项目工程,并编译生成目标文件。 在上一节创建的工程模板中main.c文件中输入图333中方框中的源程序,该程序用于在PC0端口输出方波信号,该程序只是用于讲解Keil MDK软件仿真操作,其代码较为简单,读者将在后续章节逐步学习,其操作过程如图333所示。 图333创建工程项目并编译 第二步: 将调试方式设置为软件模拟仿真方式。 在Keil MDKARM的工程管理窗口中,选中刚才编译连接成功的Target1工程并右击,在右键菜单中选择Option for Target 'Target 1'命令,打开Option for Target 'Target 1'对话框。在该对话框中,选择Debug选项卡,选中左侧的Use Simulator单选按钮,同时设置左侧CPU DLL为SARMCM3.DLL和Parameter为空,并设置左侧Dialog DLL为DARMSTM.DLL和Parameter为pSTM32F103ZE,然后单击OK按钮确定,其操作界面及顺序如图334所示。 图334软件模拟调试方式设置 第三步: 进入软件模拟调试模式。 选择菜单Debug→start/stop Debug session命令或者单击工具栏中的Debug按钮,进入软件模拟调试模式,其操作界面如图335所示。 图335进入/退出模拟调试方式 第四步: 打开相关窗口添加监测变量或信号。 选择菜单View→Analysis Windows→Logic Analyzer命令或者直接单击工具栏中的Logic Analyzer按钮,打开逻辑分析仪窗口,如图336和图337所示。 图336打开逻辑分析仪 图337逻辑分析仪窗口 图338添加观测信号 单击逻辑分析仪窗口的Setup按钮,打开Setup Logic Analyzer对话框,单击右上角的New按钮,在空白框中输入PORTC.0新增一个观测信号,并在Display Type下拉列表框中选择Bit,单击Close按钮退出,如图338所示。这样,就在Logic Analyzer窗口中添加了一个观测信号PORTC.0。在程序软件仿真运行过程中,可通过观察该信号的波形图得到STM32F103微控制器的引脚PC0上输入或输出的变化情况。 第五步: 软件模拟运行程序,观察仿真结果。 选择菜单Debug→Run命令或者单击工具栏中的Run按钮,开始仿真。让程序运行一段时间后,再选择菜单Debug→Stop命令或者单击工具栏中的Stop按钮,暂停仿真,其操作界面如图339所示。 图339开始/停止运行 然后,在Logic Analyzer窗口中可以看到程序仿真运行期间PC0的信号图,如图340所示。由图可以看出,PC0端口输出信号为一方波,占空比为50%,符合项目预期效果。如果看不清信号波形图,单击Zoom中的All按钮可以显示全部波形,还可以通过In按钮放大波形,Out按钮缩小波形。 图340逻辑分析仪输出波形 第六步: 退出模拟仿真调试模式。 选择菜单Debug→Start/Stop Debug Session命令或者单击工具栏中的Debug按钮,即可退出模拟仿真调试模式。 上述例题只是Keil MDKARM模拟仿真最简单的应用,其观测信号范围十分广泛,包括I/O端口、逻辑数值、寄存器、存储器等,还可以设定外设的工作状态,包括GPIO、ADC、DMA、TIMER等,还经常被用于时序分析,调试输出等典型应用,功能十分强大。用好模拟仿真调试,可以提前发现错误,是硬件运行调试的有益补充。 本章小结 本章的主要任务是创建是一个正确的、合理的、适合自己的工程模板,这项工作也是本课程后续学习的基础。本章首先对固件库进行认知,包括固件库概述、下载和目录结构等。随后开始工程模板的创建,包括Keil MDKARM软件简介和工程模板创建具体步骤详解。本章最后还介绍了基于Keil MDKARM软件的模拟仿真调试,该部分内容为选学内容,是硬件运行调试的有益的补充。 思考与扩展 1. 什么是STM32固件库? 2. 目前通用的STM32F10x固件库版本是多少? 3. STM32固件库下载网址是什么?并从该网站下载最新的固件库。 4. 请指出固件库中文件core_cm3.c文件的路径。 5. 请指出固件库中文件stm32f10x.h文件的路径。 6. Keil MDKARM软件的下载网址是什么?并从该网站下载最新的软件包。 7. Keil MDKARM软件建立的工程文件的扩展名是什么? 8. 参照书中工程模板创建方法,建立自己的工程模板。