购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.2 库文件及其层次关系

2.2.1 CMSIS标准软件架构

基于Cortex-M3内核的芯片虽然所采用的内核是相同的,但核外的片上外设之间存在差异,而这些差异会导致软件在同内核、不同外设的芯片上移植困难。为了解决不同的芯片厂商所生产的Cortex系列微控制器软件的兼容性问题,ARM公司与ST公司、Atmel公司、Keil公司等诸多芯片和软件厂商制定了CMSIS标准(Cortex Microcontroller Software Interface Standard)。

所谓CMSIS标准,是指建立一个硬件抽象层,基于CMSIS标准的软件架构(见图2.2)主要分为用户应用层、CMSIS层(包含操作系统和CMSIS核心层两部分)和硬件寄存器层三层。CMSIS层起着承上启下的作用,一方面它对硬件寄存器层进行统一实现,屏蔽了不同厂商对Cortex-M系列微控制器核内外设寄存器的不同定义;另一方面它为操作系统和用户应用层提供接口,简化了应用程序开发难度。因此,CMSIS层的实现相对复杂,CMSIS核心层主要分为以下3部分。

图2.2 基于CMSIS标准的软件架构

(1)核内外设访问层(Core Peripheral Access Layer,CPAL)。该层主要由ARM公司负责实现,包括对内核寄存器名称、地址的定义,对NVIC(嵌套向量中断控制器)、调试子系统访问接口的定义和对特殊用途寄存器访问接口(如CONTROL,xPSR等)的定义等。

(2)片上外设访问层(Device Peripheral Access Layer,DPAL)。该层由芯片厂商负责实现,与核内外设访问层类似,主要负责对硬件寄存器地址和外设访问接口进行定义。该层可调用核内外设访问层提供的接口函数,同时根据设备特性对异常向量表进行扩展,以处理相应外设的中断请求。

(3)外设访问函数(Access Functions for Peripherals,AFP)。该层由芯片厂商负责实现,主要用于提供访问片上外设的访问函数,这一部分是可选的。

对于一个Cortex-M系列微控制系统而言,CMSIS标准提供了与芯片厂商无关的硬件抽象层,既可以为接口外设、实时操作系统提供简单的处理器软件接口,又可以屏蔽不同硬件之间的差异,这对软件的移植具有极大的帮助。STM32标准函数库是按照这个标准来建立的。

2.2.2 库目录和文件简介

STM32标准函数库可以从ST公司的官网上下载。下面介绍目前最新的3.5.0库文件。将下载的STM32标准函数库解压后,打开STM32F10x_StdPeriph_Lib_V3.5.0文件夹,可以看到STM32标准函数库中的各文件夹,如图2.3所示。

图2.3 STM32标准函数库

h_tmresc文件夹包含ST与CMSIS的图标,这些一般用不到;Libraries文件夹包含驱动库的源代码和启动文件,所要使用的库函数就在这个文件夹中,在使用库函数进行开发时,需要把Libraries目录下的库函数文件添加到相应的工程中,因此这个文件夹十分重要;Project文件夹包含用驱动库写的各种例子和工程模板,内容非常全面,为每个外设写好的例程具有非常重要的参考价值;Utilities文件夹包含基于ST官方评估开发板的各种例程,这些例程在实际的嵌入式系统开发过程中一般用不到;stm32f10x_stdperiph_lib_um.chm是STM32标准函数库使用的英文帮助文档,这是一个已经编译好的HTML文件,主要讲述每个库函数的使用方法,具有非常重要的参考价值。

在库文件中,Libraries文件夹是开发过程中一定会用到的,打开Libraries文件夹,可以看到关于内核与外设的库文件分别存放在CMSIS文件夹和STM32F10x_StdPeriph_Driver文件夹中。下面简要介绍开发过程中用到的主要文件。

1. CMSIS文件夹

CMSIS文件夹中的主要文件及其位置关系如图2.4所示。

图2.4 CMSIS文件夹中的主要文件及其位置关系

(1)内核相关文件。CoreSupport文件夹中有core_cm3.c和core_cm3.h两个文件。core_cm3.c文件是实现操作内核外部寄存器的函数,而core_cm3.h头文件用于实现内核寄存器的映射,与DeviceSupport文件夹中的外设头文件stm32f10x.h相对应,其区别在于core_cm3.h针对的是内核外设,而stm32f10x.h针对的是片上外设。另外,core_cm3.h头文件还包含stdint.h头文件,这是一个ANSIC文件,独立于微控制器之外。它位于RVMDK软件的安装目录下,其主要作用是提供一些类型定义,这些类型定义用于屏蔽在不同芯片平台上出现的诸如int的大小是16位还是32位的差异。stdint.h头文件中的类型定义如下。在开发设计过程中,所使用的数据类型均应以stdint.h头文件中定义的为准。

(2)STM32启动文件。由图2.4可以看出,STM32的启动文件放在arm文件夹中,这个文件夹中有很多启动文件。不同型号的单片机所使用的启动文件也不一样。STM32启动文件说明如表2.1所示。

表2.1 STM32启动文件说明

STM32F103ZET6单片机芯片的内部FLASH存储器容量为512KB,属于基础型中的大容量产品,所以启动文件应该选择startup_stm32f10x_hd.s。

(3)STM32专用文件。stm32f10x.h头文件包含STM32F10×全系列所有外设寄存器的定义(寄存器的基地址和布局等)、位定义、中断向量表和存储空间的地址映射等,是一个非常重要的头文件,在内核中与之相对应的头文件是core_cm3.h。system_stm32f10x.c文件和system_stm32f10x.h头文件是STM32F10×系列微控制器的专用系统文件,其中system_stm32f10x.c文件主要对片上的RCC外设进行操作,用于实现STM32的时钟配置。系统在上电之后,首先会执行由汇编语言编写的启动文件,启动文件中的复位函数所调用的Systeminit函数(用来初始化微控制器)就是在system_stm32f10x.c文件中定义的,调用完之后,STM32F103系列芯片的系统时钟频率会被初始化成72MHz。在实际应用中如果需要对系统时钟进行重新配置,则可以参考这个函数重写,为了维持STM32标准函数库的完整性,建议不要直接在这个文件里修改时钟配置函数。

2. STM32F10x_StdPeriph_Driver文件夹

Libraries目录下的STM32F10x_StdPeriph_Driver文件夹中包含inc(include的缩写)和src(source的缩写)两个文件夹,其中所包含的是不属于CMSIS文件夹的片上外设相关文件。src文件夹中包含每个外设的驱动源文件,而inc文件夹中包含相对应的头文件,这些是ST公司针对每个STM32外设所编写的库函数文件,是STM32标准函数库的主要内容,其重要性不言而喻。

每个外设对应一个.c后缀的驱动源文件和一个.h后缀的头文件,这些外设文件分别统称为stm32f10x_ppp.c文件和stm32f10x_ppp.h文件,其中ppp表示外设名称。例如,对于ADC外设,在src文件夹中有一个stm32f10x_adc.c驱动源文件,而在inc文件夹中有一个stm32f10x_adc.h头文件与之相对应。若开发的工程用到了STM32内部的ADC,则至少要把这两个文件添加到工程中。src文件夹和inc文件夹中的所有驱动源文件和头文件如图2.5所示,从中可以看出,除了stm32f10x_ppp.c文件和stm32f10x_ppp.h文件,这两个文件夹中还有一个很特别的misc.c文件和与之对应的misc.h头文件。这个文件包含外设对内核中的NVIC的访问函数,在配置中断时,必须把这个文件添加到工程中。

图2.5 src文件夹和inc文件夹中的所有驱动源文件和头文件

3. 库工程模板

在文件目录STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template下,存放了一个官方的库工程模板。当使用库函数建立一个完整的工程时,需要添加该目录下的stm32f10x_it.c文件、system_stm32f10x.c文件和stm32f10x_conf.h头文件。

stm32f10x_it.c文件是专门用来编写中断服务函数的。该文件已经定义好了一些系统异常中断(特殊中断)的接口,而其他普通中断服务函数可以在开发过程中自行添加。在编写中断服务函数时,其函数接口并不是随意定义的,相关接口可以在汇编启动文件中找到,这部分内容在学习中断时再详细介绍。

system_stm32f10x.c文件在前面已经介绍过了,它包含STM32芯片上电后初始化系统时钟和扩展外部存储器所用的函数。在实际应用中如果需要修改系统时钟频率,可以参照该文件重写时钟配置函数。为了保持STM32标准函数库的完整性,建议不要直接在这个文件中修改时钟配置函数。

stm32f10x_conf.h头文件包含所有片上外设的头文件,它被包含在stm32f10x.h头文件中。如果没有stm32f10x_conf.h头文件,在使用库函数编程时,用到某个外设的驱动库,就必须把该外设的头文件包含进来。如果用了很多外设,则需要分别将每个外设对应的头文件都包含进来,这不仅影响代码的美观性,也不好管理。stm32f10x_conf.h头文件很好地实现了片上外设头文件的统一管理,因此应用程序只要包含这个头文件即可。由于这个头文件被包含在stm32f10x.h头文件中,所以最终只需要包含stm32f10x.h头文件即可。stm32f10x_conf.h头文件中的程序代码如下。

在默认情况下,所有头文件都被包含,但在开发过程中可以把不用的头文件注释掉,只留下需要的即可。

stm32f10x_conf.h头文件还可以配置是否使用断言编译选项,程序代码如下。

STM32标准函数库中的函数一般会包含输入参数的检查,即代码中的assert_param宏。当参数不符合要求时,会调用assert_failed函数,这个函数默认是空的。

在实际开发中使用断言编译选项时,先通过定义USE_FULL_ASSERT宏来使能断言,然后定义assert_failed函数,通常会让它调用printf函数,以输出错误说明。在使能断言后,程序在运行时会对函数的输入参数进行检查,当通过测试可以发布时,会通过取消USE_FULL_ASSERT宏来去掉断言功能,使程序全速运行。

4. 库文件之间的相互关系

将库文件对应到基于CMSIS标准的软件架构上,其层次关系如图2.6所示。

图2.6 库文件之间的层次关系

根据前面对主要库文件及其作用的简要介绍,我们已大致了解了STM32标准函数库,下面将从整体上来把握该库中各个文件之间的相互关系。在基于CMSIS标准的软件架构的库文件层次关系中,位于用户应用层的几个文件需要针对不同的应用场合进行配置和修改。在编程时需要把位于CMSIS层的文件包含进工程中,除了个别应用场合在修改系统时钟频率时,可以对system_stm32f10x.c文件进行适当改动(最好另外重写时钟配置函数),为了保持STM32标准函数库的完整性,建议不修改CMSIS层中的其他文件。

2.2.3 如何使用官方资料

由2.2.2节的介绍可知,库函数是指STM32标准函数库文件中编写好的驱动外设的函数接口。只要调用这些库函数,就可以实现STM32寄存器的配置。在实际开发过程中,可以不知道库函数驱动外设的具体实现过程,但是在调用函数时必须知道所使用的函数的功能、可传入参数及其意义和函数的返回值,如何才能记住这么多函数呢?其实,并不需要耗费精力去记住这些函数,在开发过程中只要会查阅就可以了,所以学会查阅官方帮助文档是很有必要的。

事实上,目前人们所能接触到的所有关于STM32的嵌入式系统设计与开发教程,都来自STM32官方资料。这些官方资料是所有关于STM32知识的源头,几乎包含了开发过程中所有可能遇到的问题。通过查阅这些官方资料,不仅能够更加顺利地进行嵌入式系统的设计与开发,还能够进一步深入、全面地了解STM32。下面讲解开发过程中较为常用的官方资料及其使用。

(1)《STM32F10x中文参考手册》。《STM32F10x中文参考手册》翻译自STM32英文参考手册 STM32 Reference Manual ,该手册全方位地介绍了STM32芯片的各种片上外设,把STM32的时钟、存储器架构、各种外设、寄存器都描述得清清楚楚。当对STM32的外设感到困惑时,可以查阅该手册。如果以直接配置寄存器的方式进行系统设计与开发,则查阅该手册的寄存器部分的频率会相当高。采用这种开发方式比采用库函数开发方式的效率要低很多。

(2)《Cortex-M3权威指南》。《Cortex-M3权威指南》由ARM公司提供,是针对Cortex-M3内核的经典官方资料,它详细讲解了Cortex-M内核的架构和特性。如果需要深入了解Cortex-M内核的相关知识,那么这个文档应该是首选参考资料。

(3)《Cortex-M3内核编程手册》。《Cortex-M3内核编程手册》由ST公司提供,主要介绍STM32内核寄存器的相关知识,如系统定时器、NVIC等核内外设寄存器。这部分内容是对《STM32F10x中文参考手册》没有涉及的内核部分所进行的补充。但是相对来说,《Cortex-M3内核编程手册》对内核架构和特性方面的介绍不如《Cortex-M3权威指南》详细,当需要学习Cortex-M内核编程时,这两个官方资料可以相互配合使用。

(4)《STM32规格书》。《STM32规格书》相当于STM32的数据手册,它包含STM32芯片所有的引脚功能说明、存储器架构和芯片外设架构说明。当在设计开发过程中使用STM32的其他外设时,需要用到《STM32规格书》,通过它能够查阅所使用的外设具体应该对应STM32中的哪个引脚。

(5)stm32f10x_stdperiph_lib_um.cbm。stm32f10x_stdperiph_lib_um.cbm是本章提到的STM32F10x_StdPeriph_Lib_V3.5.0文件夹中的库帮助文档。在使用库函数设计嵌入式系统时,可以先通过查阅该文档来了解STM32标准函数库提供的外设、函数原型或库函数的调用的方法,这会使开发过程更为顺畅。当然也可以直接查阅STM32标准函数库的源码,库帮助文档的说明是根据源码生成的,所以直接查看源码也可以了解函数功能。

库帮助文档如图2.7所示。逐层打开库帮助文档中的目录标签Modules\STM32F10x_StdPeriph_Driver,可看到标签下有很多外设驱动文件,如MISC、ADC、BKP和CAN等,这些驱动文件中介绍了每个库函数的使用方法。

图2.7 库帮助文档

以查阅GPIO端口的位设置函数GPIO_SetBits为例,打开标签GPIO\GPIO_Private_Functions\Functions\GPIO_SetBits,可以看到如图2.8所示的库帮助文档的函数说明。通过阅读这个函数说明,即使不去看它的程序源代码,也能够知道它所实现的功能和具体的使用方法。

图2.8 库帮助文档的函数说明

从图2.8中可以看出,GPIO_SetBits函数的原型为void GPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin),其功能是通过输入一个类型为GPIO_TypeDef的指针参数GPIOx选定要控制的GPIO端口,其中x可以取A~G中的任何一个,由此选择所控制的GPIO端口;再通过输入GPIO_Pin宏指定要写入的端口位,此参数可以是GPIO_Pin_x的任意组合,其中x的值可以是0~15。调用的函数没有返回值,通过输入相应的参数即可实现对端口位的置位操作。

GPIO_SetBits函数中的两个传入参数属于结构体指针,以图2.8中的GPIO_TypeDef为例,如果开发者在函数调用过程中不了解某个参数类型要表达的意思,可以通过单击函数原型中带下画线的“GPIO_TypeDef”直接获得该类型的具体声明,操作非常简单方便。在后面的嵌入式系统设计过程中,也会简要介绍经常用到的STM32库函数,以保证开发者能够顺利地进行系统程序设计。但是若要详细地了解某个库函数的信息,则建议开发者查阅“stm32f10x_stdperiph_lib_um.cbm”库帮助文档。

通过解读库函数说明,我们会发现每个函数及其数据类型都符合“见名知义”的原则,可以看出STM32标准函数库的编写十分美观,使用库函数设计和开发STM32嵌入式系统不仅简单迅速,而且可读性非常强。 /7E1l+13U6wiTZwuq5J3UXuI9cTJUE2KY8dRqgkrCZmifc6xt/REKbe5dM9w9d6L

点击中间区域
呼出菜单
上一章
目录
下一章
×