1 基于标准外设库的软件开发

1.1 STM32标准外设库概述

STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。

ST公司2007年10月发布了V1.0版本的固件库,MDK ARM3.22之前的版本均支持该库。2008年6月发布了V2.0版的固件库,从2008年9月推出的MDK ARM3.23版本至今均使用V2.0版本的固件库。V3.0以后的版本相对之前的版本改动较大,本书使用目前较新的V3.4版本。

1.2 使用标准外设库开发的优势

简单的说,使用标准外设库进行开发最大的优势就在于可以使开发者不用深入了解底层硬件细节就可以灵活规范的使用每一个外设。标准外设库覆盖了从GPIO到定时器,再到CAN、I2C、SPI、UART和ADC等等的所有标准外设。对应的C源代码只是用了最基本的C编程的知识,所有代码经过严格测试,易于理解和使用,并且配有完整的文档,非常方便进行二次开发和应用。

2 标准外设库下载

这里介绍的是STM32F4_DSPv1.8版本的外设库。STM32标准外设库可以到ST公司的官方网站下载,需要验证邮箱。

然后进行邮箱验证,下载。

当然,也可以在STM中文社区下载。

3 文件夹介绍

3.1 STM32F10XXX标准外设库结构与文件描述

  1. _htmresc文件夹内是官方Logo图片,可以忽略。

  2. Libraries 文件夹下面有 CMSIS 和 STM32F4xx_StdPeriph_Driver 两个目录,这两个目录包
    含固件库核心的所有子文件夹和文件,是代码移植的重头戏。CMSIS 文件夹存放的是符合 CMSIS 规范的一些文件, Driver 文件夹下是STM32F4 标准外设固件库源码文件和对应的头文件,说白了就是将寄存器封装好的函数接口。

  3. Project 文件夹下面有STM32F4xx_StdPeriph_Examples 和STM32F4xx_StdPeriph_Template 两个文件夹,Examples文件夹下是固件示例源码,Template文件夹下是工程模板。这些源码的学习对以后的开发学习非常重要。

  4. Utilities 文件夹下就是官方评估板的一些对应源码,可以忽略不看。

  5. 根目录中还有一个固件库的帮助文档 stm32f4xx_dsp_stdperiph_lib_um.chm 文件。

3.2 STM32F10xxx标准外设库架构

文件功能说明:

文件名

功能描述

具体功能说明

core_cm3.h

core_cm3.c

Cortex-M3内核及其设备文件

访问Cortex-M3内核及其设备:NVIC,SysTick等

访问Cortex-M3的CPU寄存器和内核外设的函数

stm32f10x.h

微控制器专用头文件

这个文件包含了STM32F10x全系列所有外设寄存器的定义(寄存器的基地址和布局)、位定义、中断向量表、存储空间的地址映射等

system_stm32f10x.h

system_stm32f10x.c

微控制器专用系统文件

函数SystemInit,用来初始化微控制器

函数Sysem_ExtMemCtl,用来配置外部存储器控制器。它位于文件startup_stm32f10x_xx.s /.c,在跳转到main前调用

SystemFrequncy,该值代表系统时钟频率

startup_stm32f10x_Xd.s

编译器启动代码

微控制器专用的中断处理程序列表(与头文件一致)

弱定义(Weak)的中断处理程序默认函数(可以被用户代码覆盖) 该文件是与编译器相关的

stm32f10x_conf.h

固件库配置文件

通过更改包含的外设头文件来选择固件库所使用的外设,在新建程序和进行功能变更之前应当首先修改对应的配置。

stm32f10x_it.h

stm32f10x_it.c

外设中断函数文件

用户可以相应的加入自己的中断程序的代码,对于指向同一个中断向量的多个不同中断请求,用户可以通过判断外设的中断标志位来确定准确的中断源,执行相应的中断服务函数。

stm32f10x_ppp.h

stm32f10x_ppp.c

外设驱动函数文件

包括了相关外设的初始化配置和部分功能应用函数,这部分是进行编程功能实现的重要组成部分。

Application.c

用户文件

用户程序文件,通过标准外设库提供的接口进行相应的外设配置和功能设计。

3.3 STM32F10xxx 标准外设库封装结构

STM32F10x_StdPeriph_Lib 包文件夹说明:

CMSIS 文件夹结构

4 基于CMSIS标准的软件架构

根据调查研究,软件开发已经被嵌入式行业公认为最主要的开发成本。对于ARM公司来说,一个ARM内核往往会授权给多个厂家,生产种类繁多的产品,如果没有一个通用的软件接口标准,那么当开发者在使用不同厂家的芯片时将极大的增加了软件开发成本,因此,ARM与Atmel、IAR、Keil、hami-nary Micro、Micrium、NXP、SEGGER和ST等诸多芯片和软件厂商合作,将所有Cortex芯片厂商产品的软件接口标准化,制定了CMSIS标准。此举意在降低软件开发成本,尤其针对新设备项目开发,或者将已有软件移植到其他芯片厂商提供的基于Cortex处理器的微控制器的情况。有了该标准,芯片厂商就能够将他们的资源专注于产品外设特性的差异化,并且消除对微控制器进行编程时需要维持的不同的、互相不兼容的标准的需求,从而达到降低开发成本的目的。

如下图所示,基于CMSIS标准的软件架构主要分为以下4层:用户应用层、操作系统及中间件接口层、CMSIS层、硬件寄存器层。其中CMSIS层起着承上启下的作用:一方面该层对硬件寄存器层进行统一实现,屏蔽了不同厂商对Cortex-M系列微处理器核内外设寄存器的不同定义;另一方面又向上层的操作系统及中间件接口层和应用层提供接口,简化了应用程序开发难度,使开发人员能够在完全透明的情况下进行应用程序开发。也正是如此,CMSIS层的实现相对复杂。

层主要分为以下3 个部分:

(1) 核内外设访问层(CPAL,Core Peripheral Access Layer):该层由ARM 负责实现。包括对寄存器名称、地址的定义,对核寄存器、NVIC、调试子系统的访问接口定义以及对特殊用途寄存器的访问接口(例如:CONTROL,xPSR)定义。由于对特殊寄存器的访问以内联方式定义,所以针对不同的编译器ARM 统一用来屏蔽差异。该层定义的接口函数均是可重入的。

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

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

对一个Cortex-M 微控制系统而言,CMSIS 通过以上三个部分实现了:

定义了访问外设寄存器和异常向量的通用方法;

定义了核内外设的寄存器名称和核异常向量的名称;

为RTOS 核定义了与设备独立的接口,包括Debug 通道。

这样芯片厂商就能专注于对其产品的外设特性进行差异化,并且消除他们对微控制器进行编程时需要维持的不同的、互相不兼容的标准需求,以达到低成本开发的目的。

在实际开发过程中,根据应用程序的需要,可以采取2种方法使用标准外设库(StdPeriph_Lib):

(1) 使用外设驱动:这时应用程序开发基于外设驱动的API(应用编程接口)。用户只需要配置文件”stm32f10x_conf.h”,并使用相应的文件”stm32f10x_ppp.h/.c”即可。

(2) 不使用外设驱动:这时应用程序开发基于外设的寄存器结构和位定义文件。

这两种方法的优缺点在“使用标准外设库开发的优势”小节中已经有了具体的介绍,这里仍要说明的是,使用使用标准外设库进行开发可以极大的减小软件开发的工作量,也是目前嵌入式系统开发的一个趋势。

标准外设库(StdPeriph_Lib)支持STM32F10xxx系列全部成员:大容量,中容量和小容量产品。启动文件已经对不同的系列进行了划分,实际开发中根据使用的STM32产品具体型号,用户可以通过文件”stm32f10x.h”中的预处理define或者通过开发环境中的全局设置来配置标准外设库(StdPeriph_Lib),一个define对应一个产品系列。

下面列出支持的产品系列

STM32F10x_LD:STM32小容量产品

STM32F10x_MD:STM32中容量产品

STM32F10x_HD:STM32大容量产品

在库文件中这些define的具体作用范围是:

文件“stm3210f.h”中的中断IRQ定义

启动文件中的向量表,小容量,中容量,大容量产品各有一个启动文件

外设存储器映像和寄存器物理地址

产品设置:外部晶振(HSE)的值等

系统配置函数

因此通过宏定义这种方式,可以使标准外设库适用于不同系列的产品,同时也方便与不同产品之间的软件移植,极大的方便了软件的开发。

5 STM32F10XXX标准外设库的使用

标准外设库中包含了众多的变量定义和功能函数,如果不能了解他们的命名规范和使用规律将会给编程带来很大的麻烦,本节将主要叙述标准外设库中的相关规范,通过这些规范的学习可以更加灵活的使用固件库,同时也将极大增强程序的规范性和易读性,同时标准外设库中的这种规范也值得我们在进行其他相关的开发时使用和借鉴。

5.1 缩写定义

标准外设库中的主要外设均采用了缩写的形式,通过这些缩写可以很容易的辨认对应的外设。

缩写

外设/单元

ADC

模数转换器

BKP

备份寄存器

CAN

控制器局域网模块

CEC

CRC

CRC计算单元

DAC

数模转换器

DBGMCU

调试支持

DMA

直接内存存取控制器

EXTI

外部中断事件控制器

FLASH

闪存存储器

FSMC

灵活的静态存储器控制器

GPIO

通用输入输出

I2C

I2C接口

IWDG

独立看门狗

PWR

电源/功耗控制

RCC

复位与时钟控制器

RTC

实时时钟

SDIO

SDIO接口

SPI

串行外设接口

TIM

定时器

USART

通用同步/异步收发器

WWDG

窗口看门狗

5.2 命名规则

标准外设库遵从以下命名规则 PPP表示任一外设缩写,例如:ADC。源程序文件和头文件命名都以“stm32f10x_”作为开头,例如:stm32f10x_conf.h。常量仅被应用于一个文件的,定义于该文件中;被应用于多个文件的,在对应头文件中定义。所有常量都由英文字母大写书写。寄存器作为常量处理。他们的命名都由英文字母大写书写。在大多数情况下,他们采用与缩写规范一致。外设函数的命名以该外设的缩写加下划线为开头。每个单词的第一个字母都由英文字母大写书写,例如:SPI_SendData。在函数名中,只允许存在一个下划线,用以分隔外设缩写和函数名的其它部分。对于函数命名,总的来说有以下规则:

名为PPP_Init的函数,其功能是根据PPP_InitTypeDef中指定的参数,初始化外设PPP,例如TIM_Init.

名为PPP_DeInit的函数,其功能为复位外设PPP的所有寄存器至缺省值,例如TIM_DeInit.

名为PPP_Init的函数,其功能为通过设置PPP_InitTypeDef 结构中的各种参数来定义外设的功能,例如:USART_Init .

名为PPP_Cmd的函数,其功能为使能或者失能外设PPP,例如: SPI_Cmd.

名为PPP_ITConfig的函数,其功能为使能或者失能来自外设PPP某中断源,例如: RCC_ITConfig.

名为PPP_DMAConfig的函数,其功能为使能或者失能外设PPP的DMA接口,例如:TIM1_DMAConfig.

名为以字符串“Config”结尾,其功能为配置外设功能的函数,例如:GPIO_PinRemapConfig.

名为PPP_GetFlagStatus的函数,其功能为检查外设PPP某标志位被设置与否,例如:I2C_GetFlagStatus.

名为PPP_ClearFlag的函数,其功能为清除外设PPP标志位,例如:I2C_ClearFlag.

名为PPP_GetITStatus的函数,其功能为判断来自外设PPP的中断发生与否,例如:I2C_GetITStatus.

名为PPP_ClearITPendingBit的函数,其功能为清除外设PPP中断待处理标志位,例如: I2C_ClearITPendingBit.

这样的命名方式非常便于程序的编写和阅读,以标准外设库中的示例函数为例,下面摘录了STM32F10x_StdPeriph_Examples\ADC\3ADCs_DMA\mian.c中的一段程序。

 1 DMA_InitType Def DMA_InitStructure;2 3 /* DMA1 channel1 configuration ----------------------------------------------*/4 5 DMA_DeInit(DMA1_Channel1);6 7 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;8 9 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue;
10
11 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
12
13 DMA_InitStructure.DMA_BufferSize = 1;
14
15 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
16
17 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
18
19 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
20
21 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
22
23 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
24
25 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
26
27 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
28
29 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
30
31 /* Enable DMA1 channel1 */
32
33 DMA_Cmd(DMA1_Channel1, ENABLE);

这段程序完成了DMA1通道的配置,首先定义了DMA_InitType DMA_InitStructure,接着配置DMA_InitType的各种参数,各参数的命名方式也均使用约定的命名方式,从命名就能够很容易的看出各参数所指代的具体功能。功能参数配置完成后,使用DMA_Init(DMA1_Channel1, &DMA_InitStructure);完成相应外设的初始化,最后使用DMA_Cmd(DMA1_Channel1, ENABLE) 使能相应外设。从这个例子就能够很容易的看出标准外设库这种规范化的命名规则给编写和阅读程序带来的好处。

5.3 变量定义

在早期的版本中有24个变量定义,在Keil的安装根目录下,可以找到对应的定义,路径为:Keil\ARM\INC\ST\STM32F10x\stm32f10x_type.h

 1 /* Includes ------------------------------------------------------------------*/2 3 /* Exported types ------------------------------------------------------------*/4 5 typedef signed long s32;6 7 typedef signed short s16;8 9 typedef signed char s8;
10
11 typedef signed long const sc32; /* Read Only */
12
13 typedef signed short const sc16; /* Read Only */
14
15 typedef signed char const sc8; /* Read Only */
16
17 typedef volatile signed long vs32;
18
19 typedef volatile signed short vs16;
20
21 typedef volatile signed char vs8;
22
23 typedef volatile signed long const vsc32; /* Read Only */
24
25 typedef volatile signed short const vsc16; /* Read Only */
26
27 typedef volatile signed char const vsc8; /* Read Only */
28
29 typedef unsigned long u32;
30
31 typedef unsigned short u16;
32
33 typedef unsigned char u8;
34
35 typedef unsigned long const uc32; /* Read Only */
36
37 typedef unsigned short const uc16; /* Read Only */
38
39 typedef unsigned char const uc8; /* Read Only */
40
41 typedef volatile unsigned long vu32;
42
43 typedef volatile unsigned short vu16;
44
45 typedef volatile unsigned char vu8;
46
47 typedef volatile unsigned long const vuc32; /* Read Only */
48
49 typedef volatile unsigned short const vuc16; /* Read Only */
50
51 typedef volatile unsigned char const vuc8; /* Read Only */

3.0以后的版本中使用了CMSIS数据类型,变量的定义有所不同,但是出于兼容旧版本的目的,以上的数据类型仍然兼容。CMSIS的IO类型限定词如下表所示,CMSIS和STM32固件库的数据类型对比如下下表所示。这些数据类型可以在STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h中找到具体的定义,此部分定义如下。

CMSIS IO类型限定词

IO类限定词

#define

描述

_I

volatile const

只读访问

_O

volatile

只写访问

_IO

volatile

读和写访问

固件库与CMSIS数据类型对比

固件库类型

CMSIS类型

描述

s32

int32_t

易挥发只读有符号32位数据

s16

int16_t

易挥发只读有符号16位数据

s8

int8_t

易挥发只读有符号8位数据

sc32

const int32_t

只读有符号32位数据

sc16

const int16_t

只读有符号16位数据

sc8

const int8_t

只读有符号8位数据

vs32

_IO int32_t

易挥发读写访问有符号32位数据

vs16

_IO int16_t

易挥发读写访问有符号16位数据

vs8

_IO int8_t

易挥发读写访问有符号8位数据

vsc32

_I int32_t

易挥发只读有符号32位数据

vsc16

_I int16_t

易挥发只读有符号16位数据

vsc8

_I int8_t

易挥发只读有符号8位数据

u32

uint32_t

无符号32位数据

u16

uint16_t

无符号16位数据

u8

uint8_t

无符号8位数据

uc32

const uint32_t

只读无符号32位数据

uc16

const uint16_t

只读无符号16位数据

uc8

const uint8_t

只读无符号8位数据

vu32

_IO uint32_t

易挥发读写访问无符号32位数据

vu16

_IO uint16_t

易挥发读写访问无符号16位数据

vu8

_IO uint8_t

易挥发读写访问无符号8位数据

vuc32

_I uint32_t

易挥发只读无符号32位数据

vuc16

_I uint16_t

易挥发只读无符号16位数据

vuc8

_I uint8_t

易挥发只读无符号8位数据

stm32f10x.h文件中还包含了常用的布尔形变量定义,如:

1 typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
2
3 typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
4
5 #define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
6
7 typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;

不同版本的标准外设库的变量定义略有不同,如3.4版本中就没有之前版本的TRUE和FALSE的定义,用户也可以根据自己的需求按照上面的格式定义自己的布尔形变量。在使用标准外设库进行开发遇到相关的定义问题时应首先找到对应的头文件定义。

6 使用步骤

前面几个小节已经详细介绍了标准外设库的组成结构以及部分主要文件的功能描述,那么如果在开发中使用标准外设库需要哪些描述呢?下面就进行简要的介绍,这儿介绍的使用方法是与开发环境无关的,在不同的开发环境中可能在操作方式上略有不同,但是总体的流程都是一样的,下一小节将介绍在MDK ARM开发环境下使用标准外设库的详细过程。

首先新建一个项目并设置工具链对应的启动文件,可以使用标准外设库中提供的模板,也可以自己根据自己的需求新建。标准外设库中已经提供了不同工具链对应的文件,位于STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup目录下。

其次按照使用产品的具体型号选择具体的启动文件,加入工程。文件主要按照使用产品的容量进行区分,根据产品容量进行选择即可。每个文件的具体含义可以在“stm32f10x.h”文件中找到对应的说明,摘录如下:

 1 #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)2 3 /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */4 5 /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */6 7 /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */8 9 /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */ /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
10
11 /* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD_VL: STM32 High density value line devices */
12
13 /* #define STM32F10X_XL */ /*!< STM32F10X_XL: STM32 XL-density devices */
14
15 /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
16
17 #endif
18
19 /* Tip: To avoid modifying this file each time you need to switch between these
20
21 devices, you can define the device in your toolchain compiler preprocessor.
22
23 - Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
24
25 where the Flash memory density ranges between 16 and 32 Kbytes.
26
27 - Low-density value line devices are STM32F100xx microcontrollers where the Flash
28
29 memory density ranges between 16 and 32 Kbytes.
30
31 - Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
32
33 where the Flash memory density ranges between 64 and 128 Kbytes.
34
35 - Medium-density value line devices are STM32F100xx microcontrollers where the
36
37 Flash memory density ranges between 64 and 128 Kbytes.
38
39 - High-density devices are STM32F101xx and STM32F103xx microcontrollers where
40
41 the Flash memory density ranges between 256 and 512 Kbytes.
42
43 - High-density value line devices are STM32F100xx microcontrollers where the
44
45 Flash memory density ranges between 256 and 512 Kbytes.
46
47 - XL-density devices are STM32F101xx and STM32F103xx microcontrollers where
48
49 the Flash memory density ranges between 512 and 1024 Kbytes.
50
51 - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
52
53 */

“stm32f10x.h”是整个标准外设库的入口文件,这个文件包含了STM32F10x全系列所有外设寄存器的定义(寄存器的基地址和布局)、位定义、中断向量表、存储空间的地址映射等。为了是这个文件适用于不同系列的产品,程序中是通过宏定义来实现不同产品的匹配的,上面这段程序的注释中已经详细给出了每个启动文件所对应的产品系列,与之对应,也要相应的修改这个入口文件,需要根据所使用的产品系列正确的注释/去掉相应的注释define。在这段程序的下方同样有这样的一个注释程序/*#define USE_STDPERIPH_DRIVER*/ 用于选择是否使用标准外设库,如果保留这个注释,则用户开发程序可以基于直接访问“stm32f10x.h”中定义的外设寄存器,所有的操作均基于寄存器完成,目前不使用固件库的单片机开发,如51、AVR、MSP430等其实都是采用此种方式,通过在对应型号的头文件中进行外设寄存器等方面的定义,从而在程序中对相应的寄存器操作完成相应的功能设计。

如果去掉/*#define USE_STDPERIPH_DRIVER*/的注释,则是使用标准外设库进行开发,用户需要使用在文件“stm32f10x_conf.h”中,选择要用的外设,外设同样是通过注释/去掉注释的方式来选择。示例程序如下:

 1 /* Uncomment the line below to enable peripheral header file inclusion */2 3 #include "stm32f10x_adc.h"4 5 /* #include "stm32f10x_bkp.h" */6 7 /* #include "stm32f10x_can.h" */8 9 /* #include "stm32f10x_cec.h" */
10
11 /* #include "stm32f10x_crc.h" */
12
13 /* #include "stm32f10x_dac.h" */
14
15 /* #include "stm32f10x_dbgmcu.h" */
16
17 #include "stm32f10x_dma.h"
18
19 /* #include "stm32f10x_exti.h" */
20
21 /* #include "stm32f10x_flash.h" */
22
23 /* #include "stm32f10x_fsmc.h" */
24
25 #include "stm32f10x_gpio.h"
26
27 /* #include "stm32f10x_i2c.h" */
28
29 /* #include "stm32f10x_iwdg.h" */
30
31 /* #include "stm32f10x_pwr.h" */
32
33 #include "stm32f10x_rcc.h"
34
35 /* #include "stm32f10x_rtc.h" */
36
37 /* #include "stm32f10x_sdio.h" */
38
39 /* #include "stm32f10x_spi.h" */
40
41 /* #include "stm32f10x_tim.h" */
42
43 /* #include "stm32f10x_usart.h" */
44
45 /* #include "stm32f10x_wwdg.h" */
46
47 #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */

上面一段程序来自于例程中的AD采集程序,程序使用了AD和DMA,因此去掉相应的注释,同时几乎所有的应用都需要使用复位与时钟以及通用I/O,因此这两项是必须的,而多数程序同样要使用NVIC中断IRQ设置和SysTick时钟源设置,那么 “misc.h”这一项也是必须的。

上面已经针对具体的产品信号和程序功能进行了针对性的配置,接下来需要配置系统所使用的时钟,系统时钟在“system_stm32f10x.c”同样通过注释的方式来配置,程序如下:

1 #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)2 /* #define SYSCLK_FREQ_HSE HSE_VALUE */3 #define SYSCLK_FREQ_24MHz 240000004 #else5 /* #define SYSCLK_FREQ_HSE HSE_VALUE */6 /* #define SYSCLK_FREQ_24MHz 24000000 */7 /* #define SYSCLK_FREQ_36MHz 36000000 */8 /* #define SYSCLK_FREQ_48MHz 48000000 */9 /* #define SYSCLK_FREQ_56MHz 56000000 */10 #define SYSCLK_FREQ_72MHz 7200000011 #endif

如果这儿没有明确的定义那么HSI时钟将会作为系统时钟。

至此,已经配置了系统的主要外部参数,这些参数主要是通过更改相关的宏定义来实现的,有些开发环境,例如Keil支持在软件设置中加入全局宏定义,因此像芯片系列定义,是否使用固件库定义等也可以通过软件添加来实现。

完成了主要参数配置以后就可以进行程序的开发了,标准外设库开发就可以使用标准外设库中提供的方便的API函数进行相应的功能设计了。在4.2.2小节中已经介绍了基于标准外设库开发的优势,配置完成后,程序中仍然可以直接更改相应寄存器的配置,通过对寄存器的操作可以提高程序的效率,因此可以使用标准外设库和寄存器操作两种相结合的方式。

7 STM32F4xx固件库

7.1固件库文件结构

7.2 CMSIS标准与库的关系

分析固件库之前要了解一下CMSIS是什么,与固件库有什么关系。

基于Cortex系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的Cortex微控制器软件的兼容性问题,ARM与芯片厂商建立了CMSIS标准(Cortex MicroController Software Interface Standard) – Cortex微控制器软件接口标准

从描述中可以看出,CMSIS就是一个软件抽象层,屏蔽相同内核不同外设芯片的差异,用来解决程序的移植性、兼容性问题。如下:

CMSIS是与内核相关的,任何基于这些内核生产的芯片想要编写程序都需要其内核的相关支持;固件库也是必须基于CMSIS开发的。

注意:内核的函数由ARM公司提供,主要是一些内核寄存器的名称、地址定义等;而核外的外设函数则由芯片厂商提供,包括核外外设地址和中断定义等。

CMSIS层位于硬件层与操作系统或用户层之间,提供了与芯片生产商无关的硬件抽象层,可以为接口外设、实时操作系统提供简单的处理器软件接口,屏蔽了硬件差异,这对软件的移植是有极大的好处的。

7.3 STM32F4xx_DSP_StdPeriph_Lib_V1.4.0 实际文件分析

此次使用的是V1.4.0版本固件库。如下:

从上图可以看出,固件库中重要的文件夹是Libraries和Project两个,下面也只分析这两个文件夹。

Libraries文件夹:

Libraries文件夹中有两个文件:CMSIS和STM32F4xx_StdPeriph_Driver,先看CMSIS:

Device文件夹:该文件夹下的是具体芯片直接相关的文件,包含启动文件、芯片外设寄存器定义、系统时钟初始化功能的一些文件,这是由ST公司提供的。

stm32f4xx.h和systems​tm32f4xx.c文件

stm32f4xx.h 这个文件非常重要,是一个STM32芯片底层相关的文件;包含了STM32中所有的外设寄存器地址和结构体类型定义,在使用到STM32标准库的地方都要包含这个头文件。system_stm32f4xx.c文件包含了STM32芯片上电后初始化系统时钟、扩展外部存储器用的函数

Include文件夹:包含了的是位于CMSIS标准的核内设备函数层的Cortex-M核通用的头文件,它们的作用是为那些采用Cortex-M核设计SOC的芯片商设计的芯片外设提供一个进入内核的接口,定义了一些内核相关的寄存器

core_cm4.h对于M4内核来说是一个非常重要的文件, 所有CM4芯片的库都带有这个文件;跟启动文件一样都是底层文件,都是由ARM公司提供的,遵守CMSIS标准。

再看STM32F4xx_StdPeriph_Driver文件夹:

STM32F4xx_StdPeriph_Driver是ST公司针对每个STM32外设而编写的库函数文件,每个外设对应一个 .c 和 .h 后缀的文件 。

Project文件夹:

stm32f4xxi​t.c和stm32f4xxc​onf.h文件

stm32f4xx_it.c:这个文件是专门用来编写中断服务函数的,在我们修改前,这个文件已经定义了一些系统异常(特殊中断)的接口,其它普通中断服务函数由我们自己添加。但是我们怎么知道这些中断服务函数的接口如何写?是不是可以自定义呢?答案当然不是的,这些都有可以在汇编启动文件中找到。stm32f4xx_conf.h:这个文件被包含进stm32f4xx.h 文件。ST标准库支持所有STM32F4型号的芯片,但有的型号芯片外设功能比较多,所以使用这个配置文件根据芯片型号增减ST库的外设文件

STM32官方固件库相关推荐

  1. STM32官方固件库代码解读--GPIO

    最近闲得无聊,又把 stm32 拿了出来.之前学的时候是看的库函数版本,现在和寄存器版本的一起看感觉比一开始接触的时候看得顺畅多了,详细了解了底层寄存器的功能.之前用 stm32 只是调用函数,看了寄 ...

  2. 【STM32】获取STM32官方固件库

    以STM32F103ZET6为例: 第一步:进入ST官网  http://www.st.com/content/st_com/en.html 第二步:搜索需要下载固件库芯片型号,例如: 第三步:找到对 ...

  3. STM32基于固件库学习笔记(11)RTC实时时钟

    实时时钟(RTC) 小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101xx.STM32F102xx和STM32F103xx微控制器. 中容量产品是指闪存存储器容量在64K至128 ...

  4. STM32基于固件库学习笔记(4)(通用定时器)TIM3定时1S中断

    STM32F103ZE系列定时器资源 有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器. 通用定时器:是一个通过可 ...

  5. STM32 串口固件库中定义的几个中断标志什么意思?

    STM32 串口固件库中定义的几个中断标志位什么意思? #define USART_IT_PE                       ((uint16_t)0x0028) #define USA ...

  6. #STM32标准固件库的硬件SPI(NSS为软件)封装函数库

    #基于STM32标准固件库的硬件SPI(NSS为软件)封装函数库: 最近来回顾之前写过的SPI_Flash,打算重写一次SPI配置文件 spi协议最大的特点大概就是全双工了,因此stm32硬件spi的 ...

  7. STM32如何下载官方固件库

    ST官网拥有好多权威的资料库和例程固件库.在ST官网获取stm32f103c8t6标准例程固件库 1)登陆ST官网 官网参考网页 2)点击右上角登陆或者注册 3)当登陆成功时,点击Products-& ...

  8. STM32之固件库的调用(参考洋桃电子视频)

    STM32固件库中有许多函数,每个函数代表着不同的意义. 在工程中,后缀为.s的是汇编语言编写的文件,后缀为.c的是C语言编写的文件. 在整个工程中,只有Startup中的startup_stmf10 ...

  9. STM32建立固件库小结

    最近在复习固件库的使用,顺便写一下当作日记方便复习 1.找到固件库模板下载(已经上传) 2.新设置文件夹将模板里面的内容cv进去 3.打开keil,点击project建立new uvision pro ...

最新文章

  1. ES5-Array-push(),pop(),shift(),unshift()
  2. python包NiBabel对医学影像文件格式进行读写:python包NiBabel简介集示例
  3. 文件上传速度查询方法
  4. recvfrom 无法接收 icmp 差错数据包_利用ICMP隧道技术实现C2通信
  5. python网络编程学习笔记(4):域名系统
  6. Observable与Observer
  7. 条件随机场 Conditional Random Fields
  8. springboot项目控制层的接口注入报错
  9. MAC常用软件127
  10. PHP基于微信小程序的医院预约挂号系统 uniapp 小程序
  11. 农村创业年收入可以实现三五十万元?有哪些投资不大的项目
  12. python小练习6--lambda表达式的使用
  13. CTO与CIO选型数据中台的几大建议
  14. 云管边端架构图_边缘云平台架构与应用案例分析
  15. java实现:归并排序----O(nlogn)
  16. python写透视挂_透视变换 任意角度 三维透视 python c++ opencv两种语言
  17. 广告狂人第一至七季/全集Mad Men迅雷下载
  18. zemax初始结构参数设置、选择初始结构依据、初始结构选择的常见途径
  19. [Android]commit already called错误解决
  20. 攻克名企面试题,剑指心仪offer!——题目7:栈的压入、弹出序列

热门文章

  1. (一)netty介绍
  2. uniapp手写_【转】uni-app框架纯手写微信小程序开发左侧滑动菜单
  3. python 使用整数编码字符串的值
  4. 使用python GluonTS库做概率预测
  5. python计算夏令时的具体日期,python time.time()和“夏令时”;
  6. js option keycode
  7. Selenium +Java自动化环境安装
  8. 剑指offer38 数字在排序数组中出现的次数
  9. C | 看看 C 能做什么
  10. linux shell 逻辑运算符、逻辑表达式