STM32(一)- 基于固件库的工程模板

一、背景知识

ARM是Contex内核设计公司,设计方案;

STM是Contex微控制器芯片生产厂商,根据内核方案、添加片上外设资源生产MCU芯片;

野火、正点原子等公司基于MCU芯片制作片外资源丰富的PCB电路板;

为了解决不同芯片厂商生产的Contex微控制器在软件上的兼容性,ARM与芯片厂商建立了CMSIS标准。(Cortex MicroController Software Interface Standard/Contex 微控制器软件接口标准)

CMSIS 标准中最主要的为 CMSIS 核心层,它包括了:
(1)内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由 ARM 公司提供。
(2)设备外设访问层:提供了片上的核外外设的地址和中断定义,主要由芯片生产商提供。


1-汇编编写的启动文件
startup_stm32f10x_hd.s:设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、对用C库函数_main最终去到C的世界

2-时钟配置文件
system_stm32f10x.c:把外部时钟HSE=8M,经过PLL倍频为72M。

3-外设相关的
stm32f10x.h:实现了内核之外的外设的寄存器映射
stm32f10x_xx.c:外设的驱动函数库文件                                 注:xx表示:GPIO、USRAT、I2C、SPI、FSMC
stm32f10x_xx.h:存放外设的初始化结构体,外设初始化结构体成员的参数列表,外设固件库函数的声明

4-内核相关的
CMSIS - Cortex 微控制器软件接口标准
core_cm3.h:实现了内核外设的寄存器映射
core_cm3.c:内核外设的驱动固件库

NVIC(嵌套向量中断控制器)、SysTick(系统滴答定时器)
misc.h
misc.c

5-头文件的配置文件
stm32f10x_conf.h:头文件的头文件
//stm32f10x_usart.h    //stm32f10x_i2c.h     //stm32f10x_spi.h    //stm32f10x_adc.h    //stm32f10x_fsmc.h   ......

6-专门存放中断服务函数的C文件
stm32f10x_it.c
stm32f10x_it.h

中断服务函数你可以随意放在其他的地方,并不是一定要放在stm32f10x_it.c

#include "stm32f10x.h" 

int main(void)
{
// 来到这里的时候,系统的时钟已经被配置成72M。
}

二、基于固件库的工程模板—重要文件分析

新建demo文件夹放新建工程的所有文件,个人选择保持keil软件中的文件夹路径与demo文件路径一致,demo文件夹下多一个Project文件夹。

                                    

1、CMSIS文件夹

                              startup_stm32f10x_hd.s:启动文件。设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、

                                                                       用C库函数_main最终去到C的世界

                              core_cm3.c:操作内核外设寄存器函数

                              core_cm3.h:内核外设的寄存器映射,对应于内核外外设(片上外设)的寄存器映射stm32f10x.h

                              stm32f10x.h:内核外外设(片上外设)的寄存器映射,uint8_t、uint16_t类型定义也在其中。

                              system_stm32f10x.c:这个文件包含了 STM32 芯片上电后初始化系统时钟、扩展外部存储器用的函数 。

                                                                 实现了 STM32 的时钟配置, 操作片上RCC 外设。系统在上电之后,首选会执行
                                                                 由汇编编写的启动文件, 启动文件中的复位函数中调用的SystemInit 函数就在
                                                                 这个文件里面定义。调用完之后,系统的时钟就被初始化成 72M。 如果需要重新

                                                                 配置系统时钟,我们就可以参考这个函数重写为了维持库的完整性,不会直接在这个

                                                                 文件里面修改时钟配置函数。

                              system_stm32f10x.h:

  2、Fwlib文件夹ST 公司针对每个 STM32 外设而编写的库函数文件。

                                 CMSIS之外的片上外设部分,incinclude 的缩写),srcsource 的简写) 

                               inc文件夹:每个片上外设的驱动源程序的头文件,存放外设的初始化结构体,外设初始化结构体成员的参数列表,外设固件库函数的声明。

                                                misc.h:提供了外设对内核中的NVIC(中断向量控制器)的访问函数,配置中断时必须把这个文件添加到工程中 

                                                stm32f10x_adc.h

                                                stm32f10x_gpio.h等

                               src文件夹每个片上外设的驱动源程序。

                                                misc.c

                                                stm32f10x_adc.c

                                                stm32f10x_gpio.c等

3、User文件夹

在后续开发中,在此建立用户硬件文件夹,如文件夹LED,目录下建立bsp_led.c和bsp_led.h。

注bsp:板级支持包(board support package) ,受限于具体型号的板子。

             main.c:

             stm32f10x_conf.h:这个文件被包含进 stm32f10x.h 文件。 当我们使用固件库编程的时
                                           候,如果需要某个外设的驱动库,就需要包含该外设的头文件: stm32f10x_xx.h,包含一
                                           个还好,如果是用了多外设,就需要包含多个头文件,这不仅影响代码美观也不好管理,
                                           现我们用一个头文件 stm32f10x_conf.h 把这些外设的头文件都包含在里面,让这个配置头
                                           文件统一管理这些外设的头文件,我们在应用程序中只需要包含这个配置头文件即可,我
                                            们又知道这个头文件在 stm32f10x.h 的最后被包含,所以最终我们只需要包含 stm32f10x.h
                                            这个头文件即可,非常方便。 默认情况下是所以头文件都被包含,没有被注释掉。
                                            我们也可以把不要的都注释掉,只留下需要使用的即可。

             stm32f10x_it.c:这个文件是专门用来编写中断服务函数的,在我们修改前,这个文件
                                         已经定义了一些系统异常(特殊中断)的接口,其它普通中断服务函数由我们自己添加。
                                         中断服务函数的接口可以在汇编启动文件中找到, 在学习中断和启动文件的时候我们会详细介绍

             stm32f10x_it.h:

4、Doc文件夹

     说明文件。

5、Project文件夹

     工程文件。

 三、注意细节

1、宏定义

此处需要定义两个宏,原因如下:

(1)

编译   stm32f10x_conf.h   头文件,调用stm32外设库函数。

(2)

 

选择stm32芯片类型,这里stm32f103zet6为   STM32F10X_HD

2、SystemInit函数

在启动文件中有这样一段

开头的是程序注释,在汇编里面注释用的是“;”,相当于 C 语言的“//”注释符
第二行是定义了一个子程序:Reset_Handler。PROC 是子程序定义伪指令。这里就相
当于 C语言里定义了一个函数,函数名为 Reset_Handler。
第三行 EXPORT 表示 Reset_Handler 这个子程序可供其他模块调用。相当于 C语言的
函数声明。关键字[WEAK] 表示弱定义,如果编译器发现在别处定义了同名的函数,则在
链接时用别处的地址进行链接,如果其它地方没有定义,编译器也不报错,以此处地址进
行链接。
第四行和第五行 IMPORT 说明 SystemInit 和__main 这两个标号在其他文件,在链接的
时候需要到其他文件去寻找。相当于 C 语言中,从其它文件引入函数声明。以便下面对外
部函数进行调用。
SystemInit 需要由我们自己实现,即我们要编写一个具有该名称的函数,用来初始化
STM32 芯片的时钟,一般包括初始化 AHB、APB 等各总线的时钟,需要经过一系列的配
置 STM32才能达到稳定运行的状态。其实这个函数在固件库里面有提供,官方已经为我们
写好。即下图中的System_stm32f10x.c,用库函数编程时SystemInit函数不要自己重新定义。

__main 其实不是我们定义的(不要与 C 语言中的 main 函数混淆),这是一个 C 库函数,
当编译器编译时,只要遇到这个标号就会定义这个函数,该函数的主要功能是:负责初始
化栈、堆,配置系统环境,并在函数的最后调用用户编写的 main 函数,从此来到 C 的世
界。
第六行把 SystemInit 的地址加载到寄存器 R0。
第七行程序跳转到 R0 中的地址执行程序,即执行 SystemInit函数的内容。
第八行把__main 的地址加载到寄存器 R0。
第九行程序跳转到 R0 中的地址执行程序,即执行__main 函数,执行完毕之后就去到
我们熟知的 C 世界,进入 main 函数。
第十行表示子程序的结束。
总之,看完这段代码后,了解到如下内容即可:我们需要在外部定义一个 SystemInit
函数设置 STM32 的时钟(这是针对寄存器版编程来说的);STM32 上电后,会
执行 SystemInit 函数,最后执行我们 C 语言中的 main 函数。

这个函数在 STM32 标准库的“system_stm32f10x.c”文件中定义了,而我们的工程已
经包含该文件。标准库中的 SystemInit 函数把 STM32 芯片的系统时钟设置成了 72MHz,
即此时 AHB时钟频率为 72MHz,APB2 为 72MHz,APB1 为 36MHz。当 STM32 芯片上电
后,执行启动文件中的指令后,会调用该函数,设置系统时钟为以上状态。

7

原文地址:https://www.cnblogs.com/wuguangzong/p/10104405.html