STM32 3.5固件库详解

发布于:2021-05-12 21:58:37

STM32 固件库详解
最*考试较多,教材编写暂停了一下,之前写了很多,只是每一章都感觉不是特别完整, 最*把其中的部分内容贴出来一下,欢迎指正。本文内容基于我对固件库的理解,按照便 于理解的顺序进行整理介绍,部分参考了固件库的说明,但是也基本上重新表述并按照我 理解的顺序进行重新编写。我的目的很简单,很多人写教程只是告诉你怎么做,不会告诉 你为什么这么做,我就尽量吧前因后果都说清楚,这是我的出发点,水*所限,难免有很 大的局限性,具体不足欢迎指正。 1.1 基于标准外设库的软件开发 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.1.2 使用标准外设库开发的优势 简单的说, 使用标准外设库进行开发最大的优势就在于可以使开发者不用深入了解底层硬件 细节就可以灵活规范的使用每一个外设。标准外设库覆盖了从 GPIO 到定时器,再到 CAN、 I2C、SPI、UART 和 ADC 等等的所有标准外设。对应的 C 源代码只是用了最基本的 C 编程的 知识,所有代码经过严格测试,易于理解和使用,并且配有完整的文档,非常方便进行二次 开发和应用。 1.1.3 STM32F10XXX 标准外设库结构与文件描述 1. 标准外设库的文件结构 在上一小节中已经介绍了使用标准外设库的开发的优势, 因此对标准外设库的熟悉程度直接 影响到程序的编写,下面让我们来认识一下 STM32F10XXX 的标准外设库。STM32F10XXX 的 标准外设库经历众多的更新目前已经更新到最新的 3.5 版本, 开发环境中自带的标准外设库 为 2.0.3 版本,本书中以比较稳定而且较新的 V3.4 版本为基础介绍标准外设库的结构。 可以从 ST 的官方网站下载到各种版本的标准外设库,首先看一下 3.4 版本标准外设库的文 件结构,如图 5-3 所示。3.0 以*姹镜奈募峁勾笾孪嗤扛霭姹究赡苈杂械髡

图 5-3 STM32F10XXX V3.4 标准外设库文件结构 表 5-4 中介绍了每个文件夹所包含的主要内容。 表 5-4 STM32F10XXX V3.4 标准外设库文件夹描述 STM32F10x_StdPeriph_Lib_V3.4.0 _htmresc Libraries STM32F10x_StdPeriph_Driver src Project Template RIDE EWARM CMSIS inc 标准外设库驱动源文 件 Examples MDK-ARM Raisonance RIDE 的项 目模板示例 IAR EWARM 的项目模 标准外设库驱动的完整例程 KEIL RVMDK 的项目模板示例 本文件夹包含了所有的 html 页面资 源 见表 5-6 标准外设库驱动头文件

板示例 本 文 件 夹 包 含 了 用 于 STM3210B-EVAL 和 STM3210E-EVAL 评估板的专用驱动

Utilities

STM3210-EVAL

标准外设库的第一部分是 CMSIS 和 STM32F10x_StdPeriph_Driver, CMSIS 是独立于供应商的 Cortex-M 处理器系列硬件抽象层,为芯片厂商和中间件供应商提供了简单的处理器软件接 口,简化了软件复用工作,降低了 Cortex-M 上操作系统的移植难度,并减少了新入门的微 控制器开发者的学*曲线和新产品的上市时间。STM32F10x_StdPeriph_Driver 则包括了分别 对应包括了所有外设对应驱动函数, 这些驱动函数均使用 C 语言编写, 并提供了统一的易于 调用的函数接口,供开发者使用。Project 文件夹中则包括了 ST 官方的所有例程和基于不同 编译器的项目模板,这些例程是学*和使用 STM32 的重要参考。Utilities 包含了相*拦腊 的示例程序和驱动函数, 供使用官方评估板的开发者使用, 很多驱动函数同样可以作为学* 的重要参考。 STM32F10xxx 标准外设库体系结构如图 5-4 所示。 图中很好的展示了各层以及具体文件之间 的联系,各文件的具体功能说明如表 5-5 所示。

图 5-4 STM32F10xxx 标准外设库体系结构 表 5-5 文件功能说明 文件名 功能描述 具体功能说明

core_cm3.h core_cm3.c

访问 Cortex-M3 内核及其设备:NVIC,SysTick Cortex-M3 内核及其 等 设备文件 访问 Cortex-M3 的 CPU 寄存器和内核外设的函 数 这个文件包含了 STM32F10x 全系列所有外设寄 微控制器专用头文 存器的定义(寄存器的基地址和布局) 、位定 件 义、中断向量表、存储空间的地址映射等 微 控 制 器 专 用 系 统 函数 SystemInit,用来初始化微控制器

stm32f10x.h system_stm32f10x.h

system_stm32f10x.c

文件

函数 Sysem_ExtMemCtl,用来配置外部存储器 控制器。它位于文件 startup_stm32f10x_xx.s /.c,在跳转到 main 前调用 SystemFrequncy,该值代表系统时钟频率 微控制器专用的中断处理程序列表(与头文件 一致) 弱定义(Weak)的中断处理程序默认函数(可以 被用户代码覆盖) 该文件是与编译器相关的 通过更改包含的外设头文件来选择固件库所 使用的外设,在新建程序和进行功能变更之前 应当首先修改对应的配置。 用户可以相应的加入自己的中断程序的代码, 对于指向同一个中断向量的多个不同中断请 求,用户可以通过判断外设的中断标志位来确 定准确的中断源,执行相应的中断服务函数。 包括了相关外设的初始化配置和部分功能应 用函数,这部分是进行编程功能实现的重要组 成部分。 用户程序文件,通过标准外设库提供的接口进 行相应的外设配置和功能设计。

startup_stm32f10x_Xd.s 编译器启动代码

stm32f10x_conf.h

固件库配置文件

stm32f10x_it.h stm32f10x_it.c

外设中断函数文件

stm32f10x_ppp.h stm32f10x_ppp.c Application.c

外设驱动函数文件

用户文件

2. 基于 CMSIS 标准的软件架构 根据调查研究, 软件开发已经被嵌入式行业公认为最主要的开发成本。 对于 ARM 公司来说, 一个 ARM 内核往往会授权给多个厂家,生产种类繁多的产品,如果没有一个通用的软件接 口标准,那么当开发者在使用不同厂家的芯片时将极大的增加了软件开发成本,因此,ARM 与 Atmel、IAR、Keil、hami-nary Micro、Micrium、NXP、SEGGER 和 ST 等诸多芯片和软件厂 商合作,将所有 Cortex 芯片厂商产品的软件接口标准化,制定了 CMSIS 标准。此举意在降 低软件开发成本, 尤其针对新设备项目开发, 或者将已有软件移植到其他芯片厂商提供的基 于 Cortex 处理器的微控制器的情况。有了该标准,芯片厂商就能够将他们的资源专注于产 品外设特性的差异化, 并且消除对微控制器进行编程时需要维持的不同的、 互相不兼容的标 准的需求,从而达到降低开发成本的目的。 如图 5-5 所示,基于 CMSIS 标准的软件架构主要分为以下 4 层:用户应用层、操作系统及 中间件接口层、CMSIS 层、硬件寄存器层。其中 CMSIS 层起着承上启下的作用:一方面该层 对硬件寄存器层进行统一实现,屏蔽了不同厂商对 Cortex-M 系列微处理器核内外设寄存器 的不同定义; 另一方面又向上层的操作系统及中间件接口层和应用层提供接口, 简化了应用 程序开发难度, 使开发人员能够在完全透明的情况下进行应用程序开发。 也正是如此, CMSIS 层的实现相对复杂。

图 5-5 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 通过以上三个部分实现了: l 定义了访问外设寄存器和异常向量的通用方法; l 定义了核内外设的寄存器名称和核异常向量的名称; l 为 RTOS 核定义了与设备独立的接口,包括 Debug 通道。 这样芯片厂商就能专注于对其产品的外设特性进行差异化,并且消除他们对微控制器进 行编程时需要维持的不同的、互相不兼容的标准需求,以达到低成本开发的目的。CMSIS 中 的具体文件结构如表 5-6 所示。 表 5-6 CMSIS 文件夹结构 CMSIS Core Documentation CMSIS 文 档

startup_stm32f10x_hd.s: MDK ARM CM3 Startup arm 大容量产品启动文件 startup_stm32f10x_md.s:

编译器启 中容量产品启动文件 动文件 startup_stm32f10x_ld.s: 小容量产品启动文件

gcc_ride7 iar

GCC 编译器 启动文件 IAR 编 译 器 启动文件 TrueSTUDIO 编译器启动 文件

TrueSTUDIO 本文件夹包含 STMF10xxx CMSIS 文件:微控制器外 设访问层和内核设备访问 层: core_cm3.h : CMSIS 的 Cortex-M3 内核设备访问 层头文件 core_cm3.c : CMSIS 的 Cortex-M3 内核设备访问 层源文件 stm32f10x.h : CMSIS 的 Cortex-M3 STM32f10xxx 微 控制器外设访问层头文件 system_stm32f10x.h : CMSIS 的 Cortex-M3 STM32f10xxx 微控制器外 设访问层头文件 system_stm32f10x.c : CMSIS 的 Cortex-M3 STM32f10xxx 微控制器外 设访问层源文件

在实际开发过程中, 根据应用程序的需要, 可以采取 2 种方法使用标准外设库(StdPeriph_Lib): (1) 使用外设驱动:这时应用程序开发基于外设驱动的 API(应用编程接口)。用户只需要配置 文件”stm32f10x_conf.h”,并使用相应的文件”stm32f10x_ppp.h/.c”即可。 (2) 不使用外设驱动:这时应用程序开发基于外设的寄存器结构和位定义文件。 这两种方法的优缺点在“使用标准外设库开发的优势”小节中已经有了具体的介绍, 这里仍要 说明的是, 使用使用标准外设库进行开发可以极大的减小软件开发的工作量, 也是目前嵌入 式系统开发的一个趋势。 标准外设库(StdPeriph_Lib)支持 STM32F10xxx 系列全部成员:大容量,中容量和小容量产品。 从表 5-6 中也可以看出,启动文件已经对不同的系列进行了划分,实际开发中根据使用的

STM32 产品具体型号, 用户可以通过文件”stm32f10x.h”中的预处理 define 或者通过开发环境 中的全局设置来配置标准外设库(StdPeriph_Lib),一个 define 对应一个产品系列。 下面列出支持的产品系列 STM32F10x_LD:STM32 小容量产品 STM32F10x_MD:STM32 中容量产品 STM32F10x_HD:STM32 大容量产品 在库文件中这些 define 的具体作用范围是: l 文件“stm3210f.h”中的中断 IRQ 定义 l 启动文件中的向量表,小容量,中容量,大容量产品各有一个启动文件 l 外设存储器映像和寄存器物理地址 l 产品设置:外部晶振(HSE)的值等 l 系统配置函数 因此通过宏定义这种方式, 可以使标准外设库适用于不同系列的产品, 同时也方便与不同产 品之间的软件移植,极大的方便了软件的开发。 1.1.4 STM32F10XXX 标准外设库的使用 标准外设库中包含了众多的变量定义和功能函数, 如果不能了解他们的命名规范和使用规律 将会给编程带来很大的麻烦, 本节将主要叙述标准外设库中的相关规范, 通过这些规范的学 *可以更加灵活的使用固件库, 同时也将极大增强程序的规范性和易读性, 同时标准外设库 中的这种规范也值得我们在进行其他相关的开发时使用和借鉴。 1. 缩写定义 标准外设库中的主要外设均采用了缩写的形式,通过这些缩写可以很容易的辨认对应的外 设。 缩写 ADC BKP CAN CEC CRC DAC DBGMCU DMA EXTI FLASH FSMC GPIO I2C IWDG PWR CRC 计算单元 数模转换器 调试支持 直接内存存取控制器 外部中断事件控制器 闪存存储器 灵活的静态存储器控制器 通用输入输出 I2C 接口 独立看门狗 电源/功耗控制 外设/单元 模数转换器 备份寄存器 控制器局域网模块

RCC RTC SDIO SPI TIM USART WWDG

复位与时钟控制器 实时时钟 SDIO 接口 串行外设接口 定时器 通用同步/异步收发器 窗口看门狗

2. 命名规则 标准外设库遵从以下命名规则 PPP 表示任一外设缩写,例如:ADC。源程序文件和头文件命 名都以“stm32f10x_”作为开头,例如:stm32f10x_conf.h。常量仅被应用于一个文件的,定义 于该文件中; 被应用于多个文件的, 在对应头文件中定义。 所有常量都由英文字母大写书写。 寄存器作为常量处理。他们的命名都由英文字母大写书写。在大多数情况下,他们采用与缩 写规范一致。 外设函数的命名以该外设的缩写加下划线为开头。 每个单词的第一个字母都由 英文字母大写书写,例如:SPI_SendData。在函数名中,只允许存在一个下划线,用以分隔 外设缩写和函数名的其它部分。对于函数命名,总的来说有以下规则: l 名为 PPP_Init 的函数,其功能是根据 PPP_InitTypeDef 中指定的参数,初始化外设 PPP,例 如 TIM_Init. l 名为 PPP_DeInit 的函数,其功能为复位外设 PPP 的所有寄存器至缺省值,例如 TIM_DeInit. l 名为 PPP_Init 的函数,其功能为通过设置 PPP_InitTypeDef 结构中的各种参数来定义外设 的功能,例如:USART_Init . l 名为 PPP_Cmd 的函数,其功能为使能或者失能外设 PPP,例如: SPI_Cmd. l 名为 PPP_ITConfig 的函数,其功能为使能或者失能来自外设 PPP 某中断源,例如: RCC_ITConfig. l 名为 PPP_DMAConfig 的函数,其功能为使能或者失能外设 PPP 的 DMA 接口,例如: TIM1_DMAConfig. l 用以配置外设功能的函数,总是以字符串“Config”结尾,例如 GPIO_PinRemapConfig. l 名为 PPP_GetFlagStatus 的函数,其功能为检查外设 PPP 某标志位被设置与否,例如: I2C_GetFlagStatus. l 名为 PPP_ClearFlag 的函数,其功能为清除外设 PPP 标志位,例如:I2C_ClearFlag. l 名为 PPP_GetITStatus 的函数,其功能为判断来自外设 PPP 的中断发生与否,例如: I2C_GetITStatus. l 名为 PPP_ClearITPendingBit 的函数,其功能为清除外设 PPP 中断待处理标志位,例如: I2C_ClearITPendingBit. 这样的命名方式非常便于程序的编写和阅读, 以标准外设库中的示例函数为例, 下面摘录了 STM32F10x_StdPeriph_Examples\ADC\3ADCs_DMA\mian.c 中的一段程序。 DMA_InitType Def DMA_InitStructure; /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 1;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); 这段程序完成了 DMA1 通道的配置,首先定义了 DMA_InitType DMA_InitStructure,接着配置 DMA_InitType 的各种参数, 各参数的命名方式也均使用约定的命名方式, 从命名就能够很容 易的看出各参数所指代的具体功能。功能参数配置完成后,使用 DMA_Init(DMA1_Channel1, &DMA_InitStructure); 完 成 相 应 外 设 的 初 始 化 , 最 后 使 用 DMA_Cmd(DMA1_Channel1, ENABLE) 使能相应外设。从这个例子就能够很容易的看出标准外设库这种规范化的命名规则 给编写和阅读程序带来的好处。 3. 变量定义 在早期的版本中有 24 个变量定义,在 Keil 的安装根目录下,可以找到对应的定义,路径为: Keil\ARM\INC\ST\STM32F10x\stm32f10x_type.h /* Includes ------------------------------------------------------------------*/ /* Exported types ------------------------------------------------------------*/ typedef signed long s32; typedef signed short s16; typedef signed char s8; typedef signed long const sc32; /* Read Only */ typedef signed short const sc16; /* Read Only */ typedef signed char const sc8; /* Read Only */ typedef volatile signed long vs32; typedef volatile signed short vs16; typedef volatile signed char vs8; typedef volatile signed long const vsc32; /* Read Only */ typedef volatile signed short const vsc16; /* Read Only */ typedef volatile signed char const vsc8; /* Read Only */ typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8; typedef unsigned long const uc32; /* Read Only */ typedef unsigned short const uc16; /* Read Only */ typedef unsigned char const uc8; /* Read Only */ typedef volatile unsigned long vu32; typedef volatile unsigned short vu16; typedef volatile unsigned char vu8; typedef volatile unsigned long const vuc32; /* Read Only */ typedef volatile unsigned short const vuc16; /* Read Only */

typedef volatile unsigned char const vuc8; /* Read Only */ 3.0 以后的版本中使用了 CMSIS 数据类型,变量的定义有所不同,但是出于兼容旧版本的目 的,以上的数据类型仍然兼容。CMSIS 的 IO 类型限定词如表 5-7 所示,CMSIS 和 STM32 固 件 库 的 数 据 类 型 对 比 如 表 5-8 所 示 。 这 些 数 据 类 型 可 以 在 STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f1 0x.h 中找到具体的定义,此部分定义如下。 /*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ typedef int32_t s32; typedef int16_t s16; typedef int8_t s8; typedef const int32_t sc32; /*!< Read Only */ typedef const int16_t sc16; /*!< Read Only */ typedef const int8_t sc8; /*!< Read Only */ typedef __IO int32_t vs32; typedef __IO int16_t vs16; typedef __IO int8_t vs8; typedef __I int32_t vsc32; /*!< Read Only */ typedef __I int16_t vsc16; /*!< Read Only */ typedef __I int8_t vsc8; /*!< Read Only */ typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; typedef const uint32_t uc32; /*!< Read Only */ typedef const uint16_t uc16; /*!< Read Only */ typedef const uint8_t uc8; /*!< Read Only */ typedef __IO uint32_t vu32; typedef __IO uint16_t vu16; typedef __IO uint8_t vu8; typedef __I uint32_t vuc32; /*!< Read Only */ typedef __I uint16_t vuc16; /*!< Read Only */ typedef __I uint8_t vuc8; /*!< Read Only */ 表 5-7 CMSIS IO 类型限定词 IO 类限定词 _I _O _IO 固件库类型 s32 s16 s8 #define volatile const volatile volatile CMSIS 类型 int32_t int16_t int8_t 描述 易挥发只读有符号 32 位数据 易挥发只读有符号 16 位数据 易挥发只读有符号 8 位数据 描述 只读访问 只写访问 读和写访问

表 5-8 固件库与 CMSIS 数据类型对比

sc32 sc16 sc8 vs32 vs16 vs8 vsc32 vsc16 vsc8 u32 u16 u8 uc32 uc16 uc8 vu32 vu16 vu8 vuc32 vuc16 vuc8

const int32_t const int16_t const int8_t _IO int32_t _IO int16_t _IO int8_t _I int32_t _I int16_t _I int8_t uint32_t uint16_t uint8_t const uint32_t const uint16_t const uint8_t _IO uint32_t _IO uint16_t _IO uint8_t _I uint32_t _I uint16_t _I uint8_t

只读有符号 32 位数据 只读有符号 16 位数据 只读有符号 8 位数据 易挥发读写访问有符号 32 位数据 易挥发读写访问有符号 16 位数据 易挥发读写访问有符号 8 位数据 易挥发只读有符号 32 位数据 易挥发只读有符号 16 位数据 易挥发只读有符号 8 位数据 无符号 32 位数据 无符号 16 位数据 无符号 8 位数据 只读无符号 32 位数据 只读无符号 16 位数据 只读无符号 8 位数据 易挥发读写访问无符号 32 位数据 易挥发读写访问无符号 16 位数据 易挥发读写访问无符号 8 位数据 易挥发只读无符号 32 位数据 易挥发只读无符号 16 位数据 易挥发只读无符号 8 位数据

stm32f10x.h 文件中还包含了常用的布尔形变量定义,如: typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; #define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; 不同版本的标准外设库的变量定义略有不同, 3.4 版本中就没有之前版本的 TRUE 和 FALSE 如 的定义, 用户也可以根据自己的需求按照上面的格式定义自己的布尔形变量。 在使用标准外 设库进行开发遇到相关的定义问题时应首先找到对应的头文件定义。 4. 使用步骤 前面几个小节已经详细介绍了标准外设库的组成结构以及部分主要文件的功能描述, 那么如 果在开发中使用标准外设库需要哪些描述呢?下面就进行简要的介绍, 这儿介绍的使用方法 是与开发环境无关的, 在不同的开发环境中可能在操作方式上略有不同, 但是总体的流程都 是一样的,下一小节将介绍在 MDK ARM 开发环境下使用标准外设库的详细过程。 首先新建一个项目并设置工具链对应的启动文件, 可以使用标准外设库中提供的模板, 也可 以自己根据自己的需求新建。标准外设库中已经提供了不同工具链对应的文件,位于 STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup

目录下。 其次按照使用产品的具体型号选择具体的启动文件, 加入工程。 文件主要按照使用产品的容 量进行区分,根据产品容量进行选择即可。每个文件的具体含义可以在“stm32f10x.h”文件中 找到对应的说明,摘录如下: #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) /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */ /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */ /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */ /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */ /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */ /* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD_VL: STM32 High density value line devices */ /* #define STM32F10X_XL */ /*!< STM32F10X_XL: STM32 XL-density devices */ /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */ #endif /* Tip: To avoid modifying this file each time you need to switch between these devices, you can define the device in your toolchain compiler preprocessor. - Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers where the Flash memory density ranges between 16 and 32 Kbytes. - Low-density value line devices are STM32F100xx microcontrollers where the Flash memory density ranges between 16 and 32 Kbytes. - Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers where the Flash memory density ranges between 64 and 128 Kbytes. - Medium-density value line devices are STM32F100xx microcontrollers where the Flash memory density ranges between 64 and 128 Kbytes. - High-density devices are STM32F101xx and STM32F103xx microcontrollers where the Flash memory density ranges between 256 and 512 Kbytes. - High-density value line devices are STM32F100xx microcontrollers where the Flash memory density ranges between 256 and 512 Kbytes. - XL-density devices are STM32F101xx and STM32F103xx microcontrollers where the Flash memory density ranges between 512 and 1024 Kbytes. - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers. */ “stm32f10x.h”是整个标准外设库的入口文件,这个文件包含了 STM32F10x 全系列所有外设 寄存器的定义(寄存器的基地址和布局) 、位定义、中断向量表、存储空间的地址映射等。 为了是这个文件适用于不同系列的产品, 程序中是通过宏定义来实现不同产品的匹配的, 上 面这段程序的注释中已经详细给出了每个启动文件所对应的产品系列, 与之对应, 也要相应 的修改这个入口文件,需要根据所使用的产品系列正确的注释/去掉相应的注释 define。在 这段程序的下方同样有这样的一个注释程序/*#define USE_STDPERIPH_DRIVER*/ 用于选择是 否使用标准外设库,如果保留这个注释,则用户开发程序可以基于直接访问“stm32f10x.h” 中定义的外设寄存器,所有的操作均基于寄存器完成,目前不使用固件库的单片机开发,如

51、AVR、MSP430 等其实都是采用此种方式,通过在对应型号的头文件中进行外设寄存器 等方面的定义,从而在程序中对相应的寄存器操作完成相应的功能设计。 如果去掉/*#define USE_STDPERIPH_DRIVER*/的注释,则是使用标准外设库进行开发,用户 需要使用在文件“stm32f10x_conf.h”中,选择要用的外设,外设同样是通过注释/去掉注释的 方式来选择。示例程序如下: /* Uncomment the line below to enable peripheral header file inclusion */ #include "stm32f10x_adc.h" /* #include "stm32f10x_bkp.h" */ /* #include "stm32f10x_can.h" */ /* #include "stm32f10x_cec.h" */ /* #include "stm32f10x_crc.h" */ /* #include "stm32f10x_dac.h" */ /* #include "stm32f10x_dbgmcu.h" */ #include "stm32f10x_dma.h" /* #include "stm32f10x_exti.h" */ /* #include "stm32f10x_flash.h" */ /* #include "stm32f10x_fsmc.h" */ #include "stm32f10x_gpio.h" /* #include "stm32f10x_i2c.h" */ /* #include "stm32f10x_iwdg.h" */ /* #include "stm32f10x_pwr.h" */ #include "stm32f10x_rcc.h" /* #include "stm32f10x_rtc.h" */ /* #include "stm32f10x_sdio.h" */ /* #include "stm32f10x_spi.h" */ /* #include "stm32f10x_tim.h" */ /* #include "stm32f10x_usart.h" */ /* #include "stm32f10x_wwdg.h" */ #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”同样通过注释的方式来配置,程序如下: #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) /* #define SYSCLK_FREQ_HSE HSE_VALUE */ #define SYSCLK_FREQ_24MHz 24000000 #else /* #define SYSCLK_FREQ_HSE HSE_VALUE */ /* #define SYSCLK_FREQ_24MHz 24000000 */ /* #define SYSCLK_FREQ_36MHz 36000000 */ /* #define SYSCLK_FREQ_48MHz 48000000 */

/* #define SYSCLK_FREQ_56MHz 56000000 */ #define SYSCLK_FREQ_72MHz 72000000 #endif 如果这儿没有明确的定义那么 HSI 时钟将会作为系统时钟。 至此,已经配置了系统的主要外部参数,这些参数主要是通过更改相关的宏定义来实现的, 有些开发环境,例如 Keil 支持在软件设置中加入全局宏定义,因此像芯片系列定义,是否使 用固件库定义等也可以通过软件添加来实现。 完成了主要参数配置以后就可以进行程序的开发了, 标准外设库开发就可以使用标准外设库 中提供的方便的 API 函数进行相应的功能设计了。在 4.2.2 小节中已经介绍了基于标准外设 库开发的优势,配置完成后,程序中仍然可以直接更改相应寄存器的配置,通过对寄存器的 操作可以提高程序的效率,因此可以使用标准外设库和寄存器操作两种相结合的方式。 分类: STM32 设计相关, 嵌入


相关推荐

最新更新

猜你喜欢