2024年3月23日发(作者:越醉柳)
第六章 STM32库函数架构剖析....................................................................................................1
6.1
6.2
6.3
6.4
STM32库函数到底是什么..........................................................................................1
STM32库函数的好处..................................................................................................2
千人大项目如何分配工作...........................................................................................2
STM32库结构剖析.....................................................................................................3
6.4.1
6.4.2
6.4.3
6.4.4
6.4.5
6.4.6
6.4.7
6.4.8
6.4.9
6.4.10
6.4.11
CMSIS标准.......................................................................................................3
库目录,文件简介...........................................................................................4
关于core_cm3.c文件........................................................................................5
system_stm32f10x.c文件..................................................................................6
stm32f10x.c文件...............................................................................................7
启动文件...........................................................................................................7
STM32F10x_StdPeriph_Driver文件夹............................................................9
stm32f10x_it.c、 stm32f10x_conf.h文件......................................................10
库各文件间的关系.........................................................................................11
常用官方资料.................................................................................................13
库函数帮助文档使用.....................................................................................13
第六章 STM32库函数架构剖析
本章通过简单介绍STM32库的各个文件及其关系,让读者建立STM32库的概念,看完
后对库有个总体印象即可,在后期实际开发时接触了具体的库时,再回头看看这一章,相信
你对STM32库又会有一个更深刻的认识。
6.1 STM32库函数到底是什么
STM32的库函数是ST公司已经封装好一个软件封装库,也就是很多基础的代码,在开
发产品的时候只需要直接调用这个ST库函数的函数接口就可以完成一系列工作;例如,你
原来要自己烧饭洗衣服,现在ST库函数就好像一个保姆,你只需要使唤一声就有饭吃,有
干净的衣服了。
6.2 STM32库函数的好处
在51单片机的程序开发中,我们直接配置51单片机的寄存器,控制芯片的工作方式,
如中断,定时器等。配置的时候,我们常常要查阅寄存器表,看用到哪些配置位,为了配置
某功能,该置1还是置0。这些都是很琐碎的、机械的工作,因为51单片机的软件相对来
说较简单,而且资源很有限,所以可以直接配置寄存器的方式来开发。
STM32库是由ST公司针对STM32提供的函数接口,即API (Application Program
Interface),开发者可调用这些函数接口来配置STM32的寄存器,使开发人员得以脱离最底
层的寄存器操作,有开发快速,易于阅读,维护成本低等优点。
当我们调用库的API的时候可以不用挖空心思去了解库底层的寄存器操作,就像当年我
们学习C语言的时候,用prinft()函数时只是学习它的使用格式,并没有去研究它的源码实
现,如非必要,可以说是老死不相往来。
实际上,库是架设在寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的配
置,向上为用户提供配置寄存器的接口。
6.3 千人大项目如何分配工作
其实大多数项目产品研发都是用类似库函数的方式进行分解的,如果有1000个开发人
员来负责开发板windows操作系统,那么怎么做?一定是有一群人负责最底层的硬件级,
寄存器的读写封装,包括显示器的点亮,图形刷写;然后另外一群人根据底层这群人提供的
接口,同步做二次开发。
所以库函数的理念完全被广泛应用于各种实际的项目和产品中,因为这样才可以使得多
人协同工作,才能做更大的项目产品。
6.4 STM32库结构剖析
6.4.1 CMSIS标准
我们知道由ST公司生产的STM32采用的是Cortex-M3内核,内核是整个微控制器的
CPU。该内核是ARM公司设计的一个处理器体系架构。ARM公司并不生产芯片,而是出
售其芯片技术授权。ST公司或其它芯片生产厂商如TI,负责设计的是在内核之外的部件,
被称为核外外设或片上外设、设备外设。如芯片内部的模数转换外设ADC、串口UART、
定时器TIM等。内核与外设,如同PC上的CPU与主板、内存、显卡、硬盘的关系:
因为基于Cortex的某系列芯片采用的内核都是相同的,区别主要为核外的片上外设的
差异,这些差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂
商生产的Cortex微控制器软件的兼容性问题,ARM与芯片厂商建立了CMSIS标准(Cortex
MicroController Software Interface Standard)。
所谓CMSIS标准,实际是新建了一个软件抽象层。见下图:
CMSIS标准中最主要的为CMSIS核心层,它包括了:
z 内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由ARM公司
提供
z 设备外设访问层:提供了片上的核外外设的地址和中断定义,主要由芯片生产商提
供
可见CMSIS层位于硬件层与操作系统或用户层之间,提供了与芯片生产商无关的硬件
抽象层,可以为接口外设、实时操作系统提供简单的处理器软件接口,屏蔽了硬件差异,这
对软件的移植是有极大的好处的。STM32的库,就是按照CMSIS标准建立的。
6.4.2 库目录,文件简介
STM32的3.5版库可以从官网获得,也可以直接从本书的附录光盘得到。本书主要采
用最新版的3.5库文件,在高级篇的章节有部分代码是采用3.0的库开发的,因为3.5与3.0
的库文件兼容性很好,对于旧版的代码我们仍然使用用3.0版的。
解压后进入库目录:stm32f10x_stdperiph_libSTM32F10x_StdPeriph_Lib_V3.5.0
各文件夹内容说明见图:
Libraries文件夹下是驱动库的源代码及启动文件。
Project 文件夹下是用驱动库写的例子跟一个工程模板。
还有一个已经编译好的HTML文件,是库帮助文档,主要讲的是如何使用驱动库来编
写自己的应用程序。说得形象一点,这个HTML就是告诉我们:ST公司已经为你写好了每
个外设的驱动了,想知道如何运用这些例子就来向我求救吧。不幸的是,这个帮助文档是英
文的,这对很多英文不好的朋友来说是一个很大的障碍。但要告诉大家,英文仅仅是一种工
具,绝对不能让它成为我们学习的障碍。其实这些英文还是很简单的,我们需要的是拿下它
的勇气。
网上流传有一份中文版本的库帮助文档,但那个是2.x版本的,但3.x以上版本的目录
结构和库函数接口跟2.x版本的区别还是比较大的,这点大家要注意下。
在使用库开发时,我们需要把libraries目录下的库函数文件添加到工程中,并查阅库帮
助文档来了解ST提供的库函数,这个文档说明了每一个库函数的使用方法。
进入Libraries文件夹看到,关于内核与外设的库文件分别存放在CMSIS和
STM32F10x_StdPeriph_Driver文件夹中。
LibrariesCMSISCM3文件夹下又分为CoreSupport和DeviceSupport文件夹。
6.4.3 关于core_cm3.c文件
在CoreSupport中的是位于CMSIS标准的核内设备函数层 的M3核通用的源文件
core_cm3.c和头文件core_cm3.h,它们的作用是为那些采用Cortex-M3核设计SOC的芯片
商设计的芯片外设提供一个进入M3内核的接口。这两个文件在其它公司的M3系列芯片也
是相同的。至于这些功能是怎样用源码实现的,我们可以不用管它,我们只需把这个文件加
进我们的工程文件即可,有兴趣的朋友可以深究。
core_cm3.c文件还有一些与编译器相关条件编译语句,用于屏蔽不同编译器的差异,我
们在开发时不用管这部分,有兴趣可以了解一下。里面包含了一些跟编译器相关的信息,如:
RealView Compiler (RVMDK),ICC Compiler (IAR),GNU Compiler。
较重要的是在core_cm3.c文件中包含了stdin.h 这个头文件,这是一个ANSI C 文件,
是独立于处理器之外的,就像我们熟知的C语言头文件 stdio.h 文件一样。位于RVMDK这
个软件的安装目录下,主要作用是提供一些新类型定义,如:
这些新类型定义屏蔽了在不同芯片平台时,出现的诸如int的大小是16位,还是32位
的差异。所以在我们以后的程序中,都将使用新类型如int8_t 、int16_t„„
在稍旧版的程序中还可能会出现如u8、u16、u32这样的类型,请尽量避免这样使用,
在这里提出来是因为初学时如果碰到这样的旧类型让人一头雾水,而且在以新的库建立的工
程中是无法追踪到u8、u16、u32这些的定义的。
core_cm3.c跟启动文件一样都是底层文件,都是由ARM公司提供的,遵守CMSIS标
准,即所有CM3芯片的库都带有这个文件,这样软件在不同的CM3芯片的移植工作就得
以简化。
6.4.4 system_stm32f10x.c文件
在DeviceSupport文件夹下的是启动文件、外设寄存器定义&中断向量定义层 的一些文
件,这是由ST公司提供的。
system_stm32f10x.c,是由ST公司提供的,遵守CMSIS标准。该文件的功能是设置系
统时钟和总线时钟, M3比51单片机复杂得多,并不是说我们外部给一个8M的晶振,M3
整个系统就以8M为时钟协调整个处理器的工作。我们还要通过M3核的核内寄存器来对8M
的时钟进行倍频,分频,或者使用芯片内部的时钟。所有的外设都与时钟的频率有关,所以
这个文件的时钟配置是很关键的。
system_stm32f10x.c在实现系统时钟的时候要用到PLL(锁相环),这就需要操作寄存器,
寄存器都是以存储器映射的方式来访问的,所以该文件中包含了stm32f10x.h 这个头文件。
6.4.5 stm32f10x.c文件
stm32f10x..h 这个文件非常重要,是一个非常底层的文件。所有处理器厂商都会将对内
存的操作封装成一个宏,即我们通常说的寄存器,并且把这些实现封装成一个系统文件,包
含在相应的开发环境中。这样,我们在开发自己的应用程序的时候只要将这个文件包含进来
就可以了。
6.4.6 启动文件
LibrariesCMSISCoreCM3startuparm文件夹下是由汇编编写的系统启动文
件,不同的文件对应不同的芯片型号,在使用时要注意。
文件名的英文缩写的意义如下:
z cl:互联型产品,stm32f105/107系列
z vl:超值型产品,stm32f100系列
z xl:超高密度(容量)产品,stm32f101/103系列
z ld:低密度产品,FLASH小于64K
z md:中等密度产品,FLASH=64 or 128
z hd:高密度产品,FLASH大于128
神舟I号中用的芯片是STM32F103RBT,128K Flash 20KROM,所以启动文件要选择
startup_stm32f10x_hd.s。
启动文件是任何处理器在上点复位之后最先运行的一段汇编程序。在我们编写的c语言
代码运行之前,需要由汇编为c语言的运行建立一个合适的环境,接下来才能运行我们的程
序。所以我们也要把启动文件添加进我们的的工程中去;所以,总的来说,启动文件的作用
是:
1. 初始化堆栈指针SP;
2. 初始化程序计数器指针PC;
3. 设置堆、栈的大小;
4. 设置异常向量表的入口地址;
5. 配置外部SRAM作为数据存储器(这个由用户配置,一般的开发板可没有外部
SRAM);
6. 设置C库的分支入口__main(最终用来调用main函数);
7. 在3.5版的启动文件还调用了在system_stm32f10x.c文件中的SystemIni() 函数配置
系统时钟,在旧版本的工程中要用户进入main函数自己调用SystemIni() 函数。
6.4.7 STM32F10x_StdPeriph_Driver文件夹
LibrariesSTM32F10x_StdPeriph_Driver文件夹下有inc(include的缩写)跟src(source
的简写)这两个文件夹,这都属于CMSIS的设备外设函数 部分。src里面是每个设备外设
的驱动程序,这些外设是芯片制造商在Cortex-M3核外加进去的。
进入libraries目录下的STM32F10x_StdPeriph_Driver文件夹如下图:
在src 和inc文件夹里的就是ST公司针对每个STM32外设而编写的库函数文件,每个
外设对应一个 .c 和 .h 后缀的文件。我们把这类外设文件统称为:stm32f10x_ppp.c 或
stm32f10x_ppp.h文件,PPP表示外设名称。
如针对模数转换(ADC)外设,在src文件夹下有一个stm32f10x_adc.c源文件,在inc文件夹
下有一个stm32f10x_adc.h头文件,若我们开发的工程中用到了STM32内部的ADC,则至
少要把这两个文件包含到工程里:
这两个文件夹中,还有一个很特别的misc.c文件,这个文件提供了外设对内核中的
NVIC(中断向量控制器)的访问函数,在配置中断时,我们必须把这个文件添加到工程中。
6.4.8 stm32f10x_it.c、 stm32f10x_conf.h文件
在库目录的ProjectSTM32F10x_StdPeriph_Template目录下,存放了官方的一个库工程
模板,我们在用库建立一个完整的工程时,还需要添加这个目录下的stm32f10x_it.c、
stm32f10x_it.h、stm32f10x_conf.h这三个文件。
stm32f10x_it.c,是专门用来编写中断服务函数的,在我们修改前,这个文件已经定义了
一些系统异常 的接口,其它普通中断服务函数由我们自己添加。但是我们怎么知道这些中
断服务函数的接口如何写呢?是不是可以自定义呢?答案当然不是的,这些都有可以在汇编
启动文件中找到,具体的大家自个看库的启动文件的源码去吧。
stm32f10x_conf.h,这个文件被包含进stm32f10x.h 文件。是用来配置使用了什么外设
的头文件,用这个头文件我们可以很方便地增加或删除上面driver目录下的外设驱动函数
库。如下面的代码配置表示使用了gpio、rcc、spi、usart的外设库函数,其它的注释掉的部
分,表示没有用到。
stm32f10x_conf.h这个文件还可配置是否使用“断言”编译选项,在开发时使用断言可
由编译器检查库函数传入的参数是否正确,软件编写成功后,去掉“断言”编译选项可使程
序全速运行。可通过定义USE_FULL_ASSERT或取消定义来配置是否使用断言。
6.4.9 库各文件间的关系
前面向大家简单介绍了各个库文件的作用,库文件是直接包含进工程即可,丝毫不用修
改,而有的文件就要我们在使用的时候根据具体的需要进行配置。接下来从整体上把握一下
各个文件在库工程中的层次或关系,这些文件对应到CMSIS标准架构上:
上图描述了STM32库各文件之间的调用关系,这个图省略了DSP核(Cortex-M3没有
DSP核)和实时系统层部分的文件关系。在实际的使用库开发工程的过程中,我们把位于
CMSIS层的文件包含进工程,丝毫不用修改,也不建议修改。
对于位于用户层的几个文件,就是我们在使用库的时候,针对不同的应用对库文件进行
增删(用条件编译的方法增删)和改动的文件。
6.4.10 常用官方资料
1.《STM32数据手册.pdf 》
这个文件相当于STM32的datasheet,管脚定义,内部存储器架构分配,跟芯片硬件相
关的定义都可以从这里找得到。
2.《STM32数据手册.pdf 》
这个文件对STM32的寄存器描述,它把STM32的时钟、存储器架构、及各种外设都
描述得清清楚楚。当我们对STM32的库函数的实现方式 感到困惑时,可查阅这个文件,
以直接配置寄存器方式开发的话查阅这个文档的频率会更高。
3. 《Cortex-M3权威指南》 宋岩译。
该手册详细讲解了Cortex内核的架构和特性,要深入了解Cortex-M3内核,这是首选,
经典中的经典呀。
4.《stm32f10x_stdperiph_lib_》
这个就是前面提到的库的帮助文档,在使用库函数时,我们最好通过查阅此文件来了解
库函数原型,或库函数的调用 的方法。也可以直接阅读源码里面的函数的函数说明。
5. 其他文档
6.4.11 库函数帮助文档使用
所谓库函数,就是STM32的库文件中为我们编写好的函数接口,我们只要调用这些库
函数,就可以对STM32进行配置,达到控制目的。我们可以不知道库函数是如何实现的,
但我们调用函数必须要知道函数的功能、可传入的参数及其意义、和函数的返回值。
于是,有读者就问那么多函数我怎么记呀?神舟的回答是:会查就行了,哪个人记得了
那么多。所以我们学会查阅库帮助文档 是很有必要的。
打开库帮助文档stm32f10x_stdperiph_lib_见下图:
层层打开文档的目录标签ModulesSTM32F10x_StdPeriph_Driver,可看到
STM32F10x_StdPeriph_Driver标签下有很多外设驱动文件的名字MISC、ADC、BKP、CAN
等标签。我们试着查看ADC的初始化库函数(ADC_Init) 看看,继续打开标签
ADCADC_Exported_FunctionsFunctionsADC_Init 见下图:
利用这个文档,我们即使没有去看它的具体代码,也知道要怎么利用它了。
如它的功能是:以ADC_InitStruct参数配置ADC,进行初始化。原型为void
ADC_Init(ADC_TypeDef * ADCx , ADC_Init_TypeDef * ADC_InitStruct)
其中输入的参数 ADCx 和 ADC_InitSturct 均为库文档中定义的 自定义数据类型,这
两个传入参数均为结构体指针。初学时,我们并不知道如ADC_TypeDef这样的类型是什么
意思,可以点击函数原型中带下划线的 ADC_TypeDef 就可以查看这是什么类型了。
就这样初步了解了一下库函数,读者就可以发现STM32的库是写得很优美的。每个函
数和数据类型都符合见名知义 的原则,当然,这样的名称写起来特别长,而且对于我们来
说要输入这么长的英文,很容易出错,所以在开发软件的时候,在用到库函数的地方,直接
把库帮助文档 中函数名称复制粘贴到工程文件就可以了。
2024年3月23日发(作者:越醉柳)
第六章 STM32库函数架构剖析....................................................................................................1
6.1
6.2
6.3
6.4
STM32库函数到底是什么..........................................................................................1
STM32库函数的好处..................................................................................................2
千人大项目如何分配工作...........................................................................................2
STM32库结构剖析.....................................................................................................3
6.4.1
6.4.2
6.4.3
6.4.4
6.4.5
6.4.6
6.4.7
6.4.8
6.4.9
6.4.10
6.4.11
CMSIS标准.......................................................................................................3
库目录,文件简介...........................................................................................4
关于core_cm3.c文件........................................................................................5
system_stm32f10x.c文件..................................................................................6
stm32f10x.c文件...............................................................................................7
启动文件...........................................................................................................7
STM32F10x_StdPeriph_Driver文件夹............................................................9
stm32f10x_it.c、 stm32f10x_conf.h文件......................................................10
库各文件间的关系.........................................................................................11
常用官方资料.................................................................................................13
库函数帮助文档使用.....................................................................................13
第六章 STM32库函数架构剖析
本章通过简单介绍STM32库的各个文件及其关系,让读者建立STM32库的概念,看完
后对库有个总体印象即可,在后期实际开发时接触了具体的库时,再回头看看这一章,相信
你对STM32库又会有一个更深刻的认识。
6.1 STM32库函数到底是什么
STM32的库函数是ST公司已经封装好一个软件封装库,也就是很多基础的代码,在开
发产品的时候只需要直接调用这个ST库函数的函数接口就可以完成一系列工作;例如,你
原来要自己烧饭洗衣服,现在ST库函数就好像一个保姆,你只需要使唤一声就有饭吃,有
干净的衣服了。
6.2 STM32库函数的好处
在51单片机的程序开发中,我们直接配置51单片机的寄存器,控制芯片的工作方式,
如中断,定时器等。配置的时候,我们常常要查阅寄存器表,看用到哪些配置位,为了配置
某功能,该置1还是置0。这些都是很琐碎的、机械的工作,因为51单片机的软件相对来
说较简单,而且资源很有限,所以可以直接配置寄存器的方式来开发。
STM32库是由ST公司针对STM32提供的函数接口,即API (Application Program
Interface),开发者可调用这些函数接口来配置STM32的寄存器,使开发人员得以脱离最底
层的寄存器操作,有开发快速,易于阅读,维护成本低等优点。
当我们调用库的API的时候可以不用挖空心思去了解库底层的寄存器操作,就像当年我
们学习C语言的时候,用prinft()函数时只是学习它的使用格式,并没有去研究它的源码实
现,如非必要,可以说是老死不相往来。
实际上,库是架设在寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的配
置,向上为用户提供配置寄存器的接口。
6.3 千人大项目如何分配工作
其实大多数项目产品研发都是用类似库函数的方式进行分解的,如果有1000个开发人
员来负责开发板windows操作系统,那么怎么做?一定是有一群人负责最底层的硬件级,
寄存器的读写封装,包括显示器的点亮,图形刷写;然后另外一群人根据底层这群人提供的
接口,同步做二次开发。
所以库函数的理念完全被广泛应用于各种实际的项目和产品中,因为这样才可以使得多
人协同工作,才能做更大的项目产品。
6.4 STM32库结构剖析
6.4.1 CMSIS标准
我们知道由ST公司生产的STM32采用的是Cortex-M3内核,内核是整个微控制器的
CPU。该内核是ARM公司设计的一个处理器体系架构。ARM公司并不生产芯片,而是出
售其芯片技术授权。ST公司或其它芯片生产厂商如TI,负责设计的是在内核之外的部件,
被称为核外外设或片上外设、设备外设。如芯片内部的模数转换外设ADC、串口UART、
定时器TIM等。内核与外设,如同PC上的CPU与主板、内存、显卡、硬盘的关系:
因为基于Cortex的某系列芯片采用的内核都是相同的,区别主要为核外的片上外设的
差异,这些差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂
商生产的Cortex微控制器软件的兼容性问题,ARM与芯片厂商建立了CMSIS标准(Cortex
MicroController Software Interface Standard)。
所谓CMSIS标准,实际是新建了一个软件抽象层。见下图:
CMSIS标准中最主要的为CMSIS核心层,它包括了:
z 内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由ARM公司
提供
z 设备外设访问层:提供了片上的核外外设的地址和中断定义,主要由芯片生产商提
供
可见CMSIS层位于硬件层与操作系统或用户层之间,提供了与芯片生产商无关的硬件
抽象层,可以为接口外设、实时操作系统提供简单的处理器软件接口,屏蔽了硬件差异,这
对软件的移植是有极大的好处的。STM32的库,就是按照CMSIS标准建立的。
6.4.2 库目录,文件简介
STM32的3.5版库可以从官网获得,也可以直接从本书的附录光盘得到。本书主要采
用最新版的3.5库文件,在高级篇的章节有部分代码是采用3.0的库开发的,因为3.5与3.0
的库文件兼容性很好,对于旧版的代码我们仍然使用用3.0版的。
解压后进入库目录:stm32f10x_stdperiph_libSTM32F10x_StdPeriph_Lib_V3.5.0
各文件夹内容说明见图:
Libraries文件夹下是驱动库的源代码及启动文件。
Project 文件夹下是用驱动库写的例子跟一个工程模板。
还有一个已经编译好的HTML文件,是库帮助文档,主要讲的是如何使用驱动库来编
写自己的应用程序。说得形象一点,这个HTML就是告诉我们:ST公司已经为你写好了每
个外设的驱动了,想知道如何运用这些例子就来向我求救吧。不幸的是,这个帮助文档是英
文的,这对很多英文不好的朋友来说是一个很大的障碍。但要告诉大家,英文仅仅是一种工
具,绝对不能让它成为我们学习的障碍。其实这些英文还是很简单的,我们需要的是拿下它
的勇气。
网上流传有一份中文版本的库帮助文档,但那个是2.x版本的,但3.x以上版本的目录
结构和库函数接口跟2.x版本的区别还是比较大的,这点大家要注意下。
在使用库开发时,我们需要把libraries目录下的库函数文件添加到工程中,并查阅库帮
助文档来了解ST提供的库函数,这个文档说明了每一个库函数的使用方法。
进入Libraries文件夹看到,关于内核与外设的库文件分别存放在CMSIS和
STM32F10x_StdPeriph_Driver文件夹中。
LibrariesCMSISCM3文件夹下又分为CoreSupport和DeviceSupport文件夹。
6.4.3 关于core_cm3.c文件
在CoreSupport中的是位于CMSIS标准的核内设备函数层 的M3核通用的源文件
core_cm3.c和头文件core_cm3.h,它们的作用是为那些采用Cortex-M3核设计SOC的芯片
商设计的芯片外设提供一个进入M3内核的接口。这两个文件在其它公司的M3系列芯片也
是相同的。至于这些功能是怎样用源码实现的,我们可以不用管它,我们只需把这个文件加
进我们的工程文件即可,有兴趣的朋友可以深究。
core_cm3.c文件还有一些与编译器相关条件编译语句,用于屏蔽不同编译器的差异,我
们在开发时不用管这部分,有兴趣可以了解一下。里面包含了一些跟编译器相关的信息,如:
RealView Compiler (RVMDK),ICC Compiler (IAR),GNU Compiler。
较重要的是在core_cm3.c文件中包含了stdin.h 这个头文件,这是一个ANSI C 文件,
是独立于处理器之外的,就像我们熟知的C语言头文件 stdio.h 文件一样。位于RVMDK这
个软件的安装目录下,主要作用是提供一些新类型定义,如:
这些新类型定义屏蔽了在不同芯片平台时,出现的诸如int的大小是16位,还是32位
的差异。所以在我们以后的程序中,都将使用新类型如int8_t 、int16_t„„
在稍旧版的程序中还可能会出现如u8、u16、u32这样的类型,请尽量避免这样使用,
在这里提出来是因为初学时如果碰到这样的旧类型让人一头雾水,而且在以新的库建立的工
程中是无法追踪到u8、u16、u32这些的定义的。
core_cm3.c跟启动文件一样都是底层文件,都是由ARM公司提供的,遵守CMSIS标
准,即所有CM3芯片的库都带有这个文件,这样软件在不同的CM3芯片的移植工作就得
以简化。
6.4.4 system_stm32f10x.c文件
在DeviceSupport文件夹下的是启动文件、外设寄存器定义&中断向量定义层 的一些文
件,这是由ST公司提供的。
system_stm32f10x.c,是由ST公司提供的,遵守CMSIS标准。该文件的功能是设置系
统时钟和总线时钟, M3比51单片机复杂得多,并不是说我们外部给一个8M的晶振,M3
整个系统就以8M为时钟协调整个处理器的工作。我们还要通过M3核的核内寄存器来对8M
的时钟进行倍频,分频,或者使用芯片内部的时钟。所有的外设都与时钟的频率有关,所以
这个文件的时钟配置是很关键的。
system_stm32f10x.c在实现系统时钟的时候要用到PLL(锁相环),这就需要操作寄存器,
寄存器都是以存储器映射的方式来访问的,所以该文件中包含了stm32f10x.h 这个头文件。
6.4.5 stm32f10x.c文件
stm32f10x..h 这个文件非常重要,是一个非常底层的文件。所有处理器厂商都会将对内
存的操作封装成一个宏,即我们通常说的寄存器,并且把这些实现封装成一个系统文件,包
含在相应的开发环境中。这样,我们在开发自己的应用程序的时候只要将这个文件包含进来
就可以了。
6.4.6 启动文件
LibrariesCMSISCoreCM3startuparm文件夹下是由汇编编写的系统启动文
件,不同的文件对应不同的芯片型号,在使用时要注意。
文件名的英文缩写的意义如下:
z cl:互联型产品,stm32f105/107系列
z vl:超值型产品,stm32f100系列
z xl:超高密度(容量)产品,stm32f101/103系列
z ld:低密度产品,FLASH小于64K
z md:中等密度产品,FLASH=64 or 128
z hd:高密度产品,FLASH大于128
神舟I号中用的芯片是STM32F103RBT,128K Flash 20KROM,所以启动文件要选择
startup_stm32f10x_hd.s。
启动文件是任何处理器在上点复位之后最先运行的一段汇编程序。在我们编写的c语言
代码运行之前,需要由汇编为c语言的运行建立一个合适的环境,接下来才能运行我们的程
序。所以我们也要把启动文件添加进我们的的工程中去;所以,总的来说,启动文件的作用
是:
1. 初始化堆栈指针SP;
2. 初始化程序计数器指针PC;
3. 设置堆、栈的大小;
4. 设置异常向量表的入口地址;
5. 配置外部SRAM作为数据存储器(这个由用户配置,一般的开发板可没有外部
SRAM);
6. 设置C库的分支入口__main(最终用来调用main函数);
7. 在3.5版的启动文件还调用了在system_stm32f10x.c文件中的SystemIni() 函数配置
系统时钟,在旧版本的工程中要用户进入main函数自己调用SystemIni() 函数。
6.4.7 STM32F10x_StdPeriph_Driver文件夹
LibrariesSTM32F10x_StdPeriph_Driver文件夹下有inc(include的缩写)跟src(source
的简写)这两个文件夹,这都属于CMSIS的设备外设函数 部分。src里面是每个设备外设
的驱动程序,这些外设是芯片制造商在Cortex-M3核外加进去的。
进入libraries目录下的STM32F10x_StdPeriph_Driver文件夹如下图:
在src 和inc文件夹里的就是ST公司针对每个STM32外设而编写的库函数文件,每个
外设对应一个 .c 和 .h 后缀的文件。我们把这类外设文件统称为:stm32f10x_ppp.c 或
stm32f10x_ppp.h文件,PPP表示外设名称。
如针对模数转换(ADC)外设,在src文件夹下有一个stm32f10x_adc.c源文件,在inc文件夹
下有一个stm32f10x_adc.h头文件,若我们开发的工程中用到了STM32内部的ADC,则至
少要把这两个文件包含到工程里:
这两个文件夹中,还有一个很特别的misc.c文件,这个文件提供了外设对内核中的
NVIC(中断向量控制器)的访问函数,在配置中断时,我们必须把这个文件添加到工程中。
6.4.8 stm32f10x_it.c、 stm32f10x_conf.h文件
在库目录的ProjectSTM32F10x_StdPeriph_Template目录下,存放了官方的一个库工程
模板,我们在用库建立一个完整的工程时,还需要添加这个目录下的stm32f10x_it.c、
stm32f10x_it.h、stm32f10x_conf.h这三个文件。
stm32f10x_it.c,是专门用来编写中断服务函数的,在我们修改前,这个文件已经定义了
一些系统异常 的接口,其它普通中断服务函数由我们自己添加。但是我们怎么知道这些中
断服务函数的接口如何写呢?是不是可以自定义呢?答案当然不是的,这些都有可以在汇编
启动文件中找到,具体的大家自个看库的启动文件的源码去吧。
stm32f10x_conf.h,这个文件被包含进stm32f10x.h 文件。是用来配置使用了什么外设
的头文件,用这个头文件我们可以很方便地增加或删除上面driver目录下的外设驱动函数
库。如下面的代码配置表示使用了gpio、rcc、spi、usart的外设库函数,其它的注释掉的部
分,表示没有用到。
stm32f10x_conf.h这个文件还可配置是否使用“断言”编译选项,在开发时使用断言可
由编译器检查库函数传入的参数是否正确,软件编写成功后,去掉“断言”编译选项可使程
序全速运行。可通过定义USE_FULL_ASSERT或取消定义来配置是否使用断言。
6.4.9 库各文件间的关系
前面向大家简单介绍了各个库文件的作用,库文件是直接包含进工程即可,丝毫不用修
改,而有的文件就要我们在使用的时候根据具体的需要进行配置。接下来从整体上把握一下
各个文件在库工程中的层次或关系,这些文件对应到CMSIS标准架构上:
上图描述了STM32库各文件之间的调用关系,这个图省略了DSP核(Cortex-M3没有
DSP核)和实时系统层部分的文件关系。在实际的使用库开发工程的过程中,我们把位于
CMSIS层的文件包含进工程,丝毫不用修改,也不建议修改。
对于位于用户层的几个文件,就是我们在使用库的时候,针对不同的应用对库文件进行
增删(用条件编译的方法增删)和改动的文件。
6.4.10 常用官方资料
1.《STM32数据手册.pdf 》
这个文件相当于STM32的datasheet,管脚定义,内部存储器架构分配,跟芯片硬件相
关的定义都可以从这里找得到。
2.《STM32数据手册.pdf 》
这个文件对STM32的寄存器描述,它把STM32的时钟、存储器架构、及各种外设都
描述得清清楚楚。当我们对STM32的库函数的实现方式 感到困惑时,可查阅这个文件,
以直接配置寄存器方式开发的话查阅这个文档的频率会更高。
3. 《Cortex-M3权威指南》 宋岩译。
该手册详细讲解了Cortex内核的架构和特性,要深入了解Cortex-M3内核,这是首选,
经典中的经典呀。
4.《stm32f10x_stdperiph_lib_》
这个就是前面提到的库的帮助文档,在使用库函数时,我们最好通过查阅此文件来了解
库函数原型,或库函数的调用 的方法。也可以直接阅读源码里面的函数的函数说明。
5. 其他文档
6.4.11 库函数帮助文档使用
所谓库函数,就是STM32的库文件中为我们编写好的函数接口,我们只要调用这些库
函数,就可以对STM32进行配置,达到控制目的。我们可以不知道库函数是如何实现的,
但我们调用函数必须要知道函数的功能、可传入的参数及其意义、和函数的返回值。
于是,有读者就问那么多函数我怎么记呀?神舟的回答是:会查就行了,哪个人记得了
那么多。所以我们学会查阅库帮助文档 是很有必要的。
打开库帮助文档stm32f10x_stdperiph_lib_见下图:
层层打开文档的目录标签ModulesSTM32F10x_StdPeriph_Driver,可看到
STM32F10x_StdPeriph_Driver标签下有很多外设驱动文件的名字MISC、ADC、BKP、CAN
等标签。我们试着查看ADC的初始化库函数(ADC_Init) 看看,继续打开标签
ADCADC_Exported_FunctionsFunctionsADC_Init 见下图:
利用这个文档,我们即使没有去看它的具体代码,也知道要怎么利用它了。
如它的功能是:以ADC_InitStruct参数配置ADC,进行初始化。原型为void
ADC_Init(ADC_TypeDef * ADCx , ADC_Init_TypeDef * ADC_InitStruct)
其中输入的参数 ADCx 和 ADC_InitSturct 均为库文档中定义的 自定义数据类型,这
两个传入参数均为结构体指针。初学时,我们并不知道如ADC_TypeDef这样的类型是什么
意思,可以点击函数原型中带下划线的 ADC_TypeDef 就可以查看这是什么类型了。
就这样初步了解了一下库函数,读者就可以发现STM32的库是写得很优美的。每个函
数和数据类型都符合见名知义 的原则,当然,这样的名称写起来特别长,而且对于我们来
说要输入这么长的英文,很容易出错,所以在开发软件的时候,在用到库函数的地方,直接
把库帮助文档 中函数名称复制粘贴到工程文件就可以了。