驱动函数均使用 C 语言编写, 并提供了统一的易于调用的函数接口,供开发者使用。
Project 文件夹中则包括了 ST 官方的所有例程和基于不同编译器的项目模板,这些例程是学习和使用 STM32 的重要参考。
Utilities 包含了相关评估板的示例程序和驱动函数,供使用官方评估板的开发者使用, 很多驱动函数同样可以作为学习的重要参考。
STM32F10xxx 标准外设库体系结构如图 5-4 所示。
图中很好的展示了各层以及具体文件之间的联系,各文件的具体功能说明如表 5-5 所示。
图 5-4 STM32F10xxx 标准外设库体系结构表 5-5 文件功能说明文件名 功能描述 具体功能说明 访问 Cortex-M3 内核及其设备:NVIC,SysTickcore_cm3.h Cortex-M3 内核及其 等core_cm3.c 设备文件 访问 Cortex-M3 的 CPU 寄存器和内核外设的函 数 这个文件包含了 STM32F10x 全系列所有外设寄 微控制器专用头文stm32f10x.h 存器的定义(寄存器的基地址和布局) 、位定 件 义、中断向量表、存储空间的地址映射等system_stm32f10x.h 微 控 制 器 专 用 系 统 函数 SystemInit,用来初始化微控制器system_stm32f10x.c 文件 函数 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 用户文件 行相应的外设配置和功能设计。
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 文CMSIS Core Documentation 档 startup_stm32f10x_hd.s: 大容量产品启动文件 MDK ARM startup_stm32f10x_md.s:CM3 Startup arm 编译器启 中容量产品启动文件 动文件 startup_stm32f10x_ld.s: 小容量产品启动文件 GCC 编译器gcc_ride7 启动文件 IAR 编 译 器iar 启动文件 TrueSTUDIOTrueSTUDIO 编译器启动 文件本文件夹包含 STMF10xxxCMSIS 文件:微控制器外设访问层和内核设备访问层:core_cm3.h : CMSIS 的Cortex-M3 内核设备访问层头文件core_cm3.c : CMSIS 的Cortex-M3 内核设备访问层源文件stm32f10x.h : CMSIS 的Cortex-M3 STM32f10xxx 微控制器外设访问层头文件system_stm32f10x.h :CMSIS 的 Cortex-M3STM32f10xxx 微控制器外设访问层头文件system_stm32f10x.c :CMSIS 的 Cortex-M3STM32f10xxx 微控制器外设访问层源文件在实际开发过程中, 根据应用程序的需要, 可以采取 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 控制器局域网模块CECCRC CRC 计算单元DAC 数模转换器DBGMCU 调试支持DMA 直接内存存取控制器EXTI 外部中断事件控制器FLASH 闪存存储器FSMC 灵活的静态存储器控制器GPIO 通用输入输出I2C I2C 接口IWDG 独立看门狗PWR 电源/功耗控制RCC 复位与时钟控制器RTC 实时时钟SDIO SDIO 接口SPI 串行外设接口TIM 定时器USART 通用同步/异步收发器WWDG 窗口看门狗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_ExamplesADC3ADCs_DMAmian.c 中的一段程序。
DMA_InitType Def DMA_InitStructure/ DMA1 channel1 configuration ----------------------------------------------/DMA_DeInitDMA1_Channel1DMA_InitStructure.DMA_PeripheralBaseAddr ADC1_DR_AddressDMA_InitStructure.DMA_MemoryBaseAddr uint32_tampADC1ConvertedValueDMA_InitStructure.DMA_DIR DMA_DIR_PeripheralSRCDMA_InitStructure.DMA_BufferSize 1DMA_InitStructure.DMA_PeripheralInc DMA_PeripheralInc_DisableDMA_InitStructure.DMA_MemoryInc DMA_MemoryInc_DisableDMA_InitStructure.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWordDMA_InitStructure.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWordDMA_InitStructure.DMA_Mode DMA_Mode_CircularDMA_InitStructure.DMA_Priority DMA_Priority_HighDMA_InitStructure.DMA_M2M DMA_M2M_DisableDMA_InitDMA1_Channel1 ampDMA_InitStructure/ Enable DMA1 channel1 /DMA_CmdDMA1_Channel1 ENABLE这段程序完成了 DMA1 通道的配置,首先定义了 DMA_InitType DMA_InitStructure,接着配置DMA_InitType 的各种参数, 各参数的命名方式也均使用约定的命名方式, 从命名就能够很容易的看出各参数所指代的具体功能。
功能参数配置完成后,使用 DMA_InitDMA1_Channel1ampDMA_InitStructure 完 成 相 应 外 设 的 初 始 化 , 最 后 使 用 DMA_CmdDMA1_Channel1ENABLE 使能相应外设。
从这个例子就能够很容易的看出标准外设库这种规范化的命名规则给编写和阅读程序带来的好处。
3. 变量定义在早期的版本中有 24 个变量定义,在 Keil 的安装根目录下,可以找到对应的定义,路径为:KeilARMINCSTSTM32F10xstm32f10x_type.h/ Includes ------------------------------------------------------------------// Exported types ------------------------------------------------------------/typedef signed long s32typedef signed short s16typedef signed char s8typedef signed long const sc32 / Read Only /typedef signed short const sc16 / Read Only /typedef signed char const sc8 / Read Only /typedef volatile signed long vs32typedef volatile signed short vs16typedef volatile signed char vs8typedef volatile signed long const vsc32 / Read Only /typedef volatile signed short const vsc16 / Read Only /typedef volatile.