因为我使用的STM32F103ZET6是512K字节的闪存,所以启动文件选择hd 。
启动文件的作用
1.设置堆栈指针
2.设置PC指针
3.初始化中断向量表
4.配置系统时钟
系统会执行Reset_Handler这个汇编,它会调用两个函数,一个SystemInit和__main,SystemInit用于配置系统时钟, __main是C库函数,用于初始化堆栈,最终调用C语言中的main函数,实现从汇编到C语言的环境的跳跃。
把外部时钟HSE=8M,经过PLL倍频为72M。当执行完启动文件后,系统时钟已经配置为72M.
1. 配置RCC_CR寄存器:首先,需要打开外部时钟HSE,并等待HSE稳定。这可以通过设置RCC_CR寄存器的HSEON位来实现。
2. 配置RCC_CFGR寄存器:接下来,需要配置RCC_CFGR寄存器,以将外部时钟HSE经过PLL倍频为72MHz。具体来说,需要设置PLL输入时钟源为HSE,PLL倍频因子为9(即72MHz / 8MHz = 9),并将PLL作为系统时钟源。这可以通过设置RCC_CFGR寄存器的相应位来实现。
3. 等待PLL稳定:在配置完RCC_CR和RCC_CFGR寄存器后,需要等待PLL稳定。这可以通过检查RCC_CR寄存器的PLLRDY位来实现。
4. 将PLL作为系统时钟源:当PLL稳定后,需要将其作为系统时钟源。这可以通过设置RCC_CFGR寄存器的SW位来实现。
5. 等待系统时钟稳定:最后,需要等待系统时钟稳定。这可以通过检查RCC_CFGR寄存器的SWS位来实现。
执行完这些配置后,系统时钟就已经被设置为72MHz了。
通过上面的系统结构框图我们可以知道,AHB系统总线上连接这许多的外设,这些外设都以存储器的形式存在,都有自己的地址,stm32f10x.h这个文件就这给这些外设取别名,实现内核之外外设的寄存器的映射,这样方便我们使用,不用每次都去查找每个外设的地址,也能够提高代码的可读性。
stm32f10x_xx.c这类命名的文件是外设的驱动函数库文件 。
stm32f10x_xx.h这类命名的文件是存放外设的初始化结构体,外设初始化结构体成员的参数列表,外设固件库函数声明。
这里的xx就是ABH上的外设,列如:GPIO、I2C、USRAT、SPI、FSMC等。下面是stm32f10x_gpio.h和stm32f10x_gpio.c的部分代码:
#ifndef __STM32F10X_GPIO_H
#define __STM32F10X_GPIO_H
#include "stm32f10x.h"
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!<选择Pin0 */ //(0000000 0000001)b
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!<选择Pin1 */ //(0000000 0000001)b
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!<选择Pin2 */ //(0000000 0000001)b
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!<选择Pin3 */ //(0000000 0000001)b
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!<选择Pin4 */ //(0000000 0000001)b
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!<选择Pin5 */ //(0000000 0000001)b
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!<选择Pin6 */ //(0000000 0000001)b
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!<选择Pin7 */ //(0000000 0000001)b
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!<选择Pin8 */ //(0000000 0000001)b
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!<选择Pin9 */ //(0000000 0000001)b
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!<选择Pin10 */ //(0000000 0000001)b
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!<选择Pin11 */ //(0000000 0000001)b
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!<选择Pin12 */ //(0000000 0000001)b
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!<选择Pin13 */ //(0000000 0000001)b
#define GPIO_Pin_14 ((uint16_t)0x3000) /*!<选择Pin14 */ //(0000000 0000001)b
#define GPIO_Pin_15 ((uint16_t)0x4000) /*!<选择Pin15 */ //(0000000 0000001)b
#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!<选择全部引脚*/ //(0000000 0000001)b
typedef enum
{
GPIO_Speed_10MHZ = 1,
GPIO_Speed_2MHZ,
GPIO_Speed_50MHZ
}GPIOSpeed_TypeDef;
typedef enum
{
GPIO_Mode_AIN = 0x0,
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28,
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_0D = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18,
}GPIOMode_TypeDef;
#include "stm32f10x_gpio.h"
void GPIO_SetBit(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{
GPIOx->BSRR |= GPIO_Pin;
}
void GPIO_ResetBit(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{
GPIOx->BRR |=GPIO_Pin;
}
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
uint32_t tmpreg = 0x00, pinmask = 0x00;
/* Check the parameters */
// assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
// assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
// assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
/*---------------------------- GPIO Mode Configuration -----------------------*/
currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
{
/* Check the parameters */
// assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
/* Output mode */
currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
}
/*---------------------------- GPIO CRL Configuration ------------------------*/
/* Configure the eight low port pins */
CMSIS : Cortex 微控制器软件接口标准
core_cm3.h:实现内核里面外设的寄存器的映射
core_cm3.h 文件通过提供相关的宏、类型定义和函数声明,帮助开发者在 STM32F103 系列微控制器上利用 Cortex-M3 内核的特性和功能,更方便地编写和调试应用程序。
core_cm3.c:提供了与 Cortex-M3 内核相关的基本功能和操作
core_cm3.c 文件是针对 ARM Cortex-M3 内核的核心支持文件,它包含了与 Cortex-M3 内核相关的操作和功能。这个文件定义了各种操作模式、寄存器宏和内联汇编函数,以帮助开发者更方便地编写和调试基于 Cortex-M3 架构的微控制器应用程序。具体而言,core_cm3.c 文件提供了以下几个方面的功能:异常和中断处理、内存管理单元 (MMU)、系统控制块 (SCB)、中断优先级和向量表、内置功能。
NVIC(嵌套向量中断控制器)
在 STM32F103 系列微控制器中,NVIC(Nested Vectored Interrupt Controller)文件是一个关键的文件,用于配置和管理中断控制器。它包含了与 NVIC 相关的寄存器定义、中断控制函数和中断优先级相关的宏。
具体而言,NVIC 文件的作用如下:
1. 中断优先级:NVIC 文件定义了一些宏,用于配置和管理中断的优先级。通过这些宏,开发者可以设置不同中断的优先级,以确保在多个中断同时发生时,可以按照设定的优先级顺序进行处理。
2. 中断控制:NVIC 文件提供了一系列函数,用于使能、禁用和配置中断。通过这些函数,开发者可以控制特定中断的状态,包括使能或禁用某个具体中断、配置中断触发方式等。
3. 中断向量表:NVIC 文件定义了中断向量表,其中包含了各个中断处理函数的地址。开发者可以通过修改中断向量表中的对应中断位置的函数地址来指定中断发生时执行的处理函数。
总之,NVIC 文件在 STM32F103 系列微控制器中起着重要的作用,它提供了配置和管理中断的功能,包括中断优先级的设置、中断的使能和禁用以及中断向量表的配置,以确保中断能够按照预期的方式进行处理。
SysTick(系统滴答定时器)
在STM32F103系列微控制器中,SysTick(系统滴答定时器)是一个十分重要的计时器模块。它被设计用于提供一种可编程的定时器中断源,以便实现周期性地对系统进行调度、时间戳标记等功能。
具体来说,SysTick文件主要包括以下内容:
1. SysTick寄存器定义:该部分定义了SysTick计时器相关的寄存器及其对应的位域,包括CTRL、LOAD和VAL三个寄存器。
2. SysTick初始化函数:该函数用于初始化SysTick计时器,并设置计时周期、时钟源和中断优先级等参数。
3. SysTick中断服务函数:该函数是SysTick计时器中断的处理函数,当SysTick计时器到达设定的周期后,会自动触发该函数,并执行其中的指令。
通过使用SysTick计时器,我们可以实现很多常用的功能,比如:
1. 精确定时:通过设置SysTick计时器的周期,可以实现精确的定时功能,比如1ms、10ms、100ms等周期性定时。
2. 时间戳标记:可以使用SysTick计时器来记录某个事件的发生时间,从而实现时间戳标记等功能。
3. 系统调度:SysTick计时器还可以用来触发系统的调度程序,以便实现多任务并发处理等功能。
总之,SysTick文件在STM32F103系列微控制器中扮演着十分重要的角色,是实现多种功能的基础。
misc.h
在STM32F103系列微控制器中,misc.h文件是一个头文件,用于定义和配置中断相关的功能。具体来说,misc.h文件的作用有以下几个方面:
1. 中断优先级配置:该文件定义了一些宏,可以用于设置中断的优先级。通过使用这些宏,可以为各个中断通道设置优先级,以确保不同中断之间的正确执行顺序。
2. 中断向量表重定位:该文件还定义了一个函数`NVIC_SetVectorTable()`,用于重新定义中断向量表的起始地址。通过调用这个函数,可以将中断向量表重定位到其他存储器区域,比如外部存储器。
3. 中断使能和禁止:该文件中还定义了一些函数,如`NVIC_EnableIRQ()`和`NVIC_DisableIRQ()`,用于使能或禁止特定中断通道。通过这些函数,可以动态地控制中断的开关状态。
4. 中断状态管理:该文件中定义了一些宏和函数,如`__disable_irq()`和`__enable_irq()`,用于全局地禁止或允许中断的触发。这在某些临界代码区域中非常有用,可以防止中断打断关键操作。
总之,misc.h文件提供了一些宏和函数,用于配置和管理中断相关的功能。通过使用这些定义和函数,可以对中断进行优先级设置、中断向量表重定位、中断使能和禁止,以及中断状态的管理。这些功能在STM32F103系列微控制器中非常重要,用于实现可靠的中断处理机制。
misc.c
在STM32F103系列微控制器中,misc.c文件是与misc.h文件对应的源文件,用于实现misc.h文件中定义的一些函数。具体来说,misc.c文件的作用有以下几个方面:
1. 实现中断向量表重定位:通过调用`NVIC_SetVectorTable()`函数,可以将中断向量表重定位到其他存储器区域,如外部存储器。misc.c文件中实现了这个函数,并根据用户指定的地址重新设置了中断向量表的起始地址。
2. 实现中断使能和禁止:通过调用`NVIC_EnableIRQ()`和`NVIC_DisableIRQ()`函数,可以动态地控制中断的开关状态。misc.c文件中实现了这些函数,可以让用户方便地开启或关闭指定的中断通道。
3. 实现中断状态管理:通过调用`__disable_irq()`和`__enable_irq()`宏,可以全局地禁止或允许中断的触发。misc.c文件中实现了这些宏,可以让用户方便地在临界代码区域中禁止或允许中断的打断。
总之,misc.c文件实现了misc.h文件中定义的一些函数,用于配置和管理中断相关的功能。这些函数包括中断向量表重定位、中断使能和禁止,以及中断状态的管理。这些功能在STM32F103系列微控制器中非常重要,用于实现可靠的中断处理机制。
stm32f10x_conf.h:头文件的头文件,存放你需要的外设头文件,例如:
#include "stm32f10x_gpio.h"
#include" stm32f10x_usart.h"
#include" stm32f10x_i2c.h"
#include" stm32f10x_spi.h"
#include" stm32f10x_adc.h"
#include" stm32f10x_fsmc.h"
如果使用这个头文件,那么我们在main.c中就只需要使用这一个头文件即可。
stm32f10x_it.c和 stm32f10x_it.h
stm32f10x_it.c文件:
1. 定义中断服务函数:该文件包含了各个中断通道对应的中断服务函数的定义。例如,当某个中断发生时,会调用相应的中断服务函数进行处理。在stm32f10x_it.c文件中,可以根据需要编写各个中断通道的处理代码。
2. 中断服务函数的优先级设置:该文件中,可以通过配置中断服务函数的优先级来确定不同中断之间的执行顺序。这样,能够确保关键中断的及时响应和正确处理。
stm32f10x_it.h文件:
1. 声明中断服务函数:该文件定义了各个中断通道对应的中断服务函数的声明。这些声明可以被其他源文件引用,以便正确地链接和调用中断服务函数。
2. 定义中断通道号:该文件中还定义了各个中断通道的编号,这些编号用于区分不同的中断通道。在程序中,可以使用这些定义的中断通道号来配置和管理中断。
当然,中断服务函数你也可以随意放在其他地方,并不一定要放在stm32f10x_it.c中。
官方的固件库可以从ST官网 下载https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries/stsw-stm32054.html#design-scroll
_htmresc文件夹里面是两个LOGO,对我们没什么用
Libraries文件夹
Libraries的第一个是 Cortex 微控制器软件接口标准,里面有一个CM3文件夹,CM3里面又有两个文件夹
CM3的第一个文件夹里面是core_cm3.c和core_cm3.h文件
这里就有STM32里面的一个很重要的文件stm32f10x.h。后面的.c和.h文件是和时钟相关的文件
根据你使用的编程软件选择不同的启动文件,根据你使用的单片机FLASH容量参照下表选择对应的启动文件
Libraries的第二个文件夹是标准的外设驱动,里面又有两个文件夹
inc是 外设的.h文件,形如stm32f10x_xx.h
src是.c文件,包含外设源码和内核misc.c文件
每个例程里面都有几个文件,每个文件夹里面又有一个 main.c和readme文件,main.c里面就是这个外设具体的使用方法,readme里面就相当于是解释,但是是全英文的
Template是模板文件夹
Utilities文件夹里面是官方评估板的例程,对我们也没什么用,因为我们没有官方的评估板