stm32学习笔记---新建工程步骤和点灯演示

目录

STM32的三种开发方式

基于寄存器的方式

基于库函数的方式

基于Hal库的方式

固件库介绍

新建基于标准库的工程步骤

配置寄存器来完成点灯操作

添加库函数来完成点灯操作

添加库函数

开始点灯操作

第一步:使能时钟

第二步:配置端口模式

第三步:设置端口的高低电平

新建工程里的启动文件选择

总结一下新建工程的步骤

工程的架构解析


声明:本专栏是本人跟着B站江科大的视频的学习过程中记录下来的笔记,我之所以记录下来是为了方便自己日后复习。如果你也是跟着江科大的视频学习的,可以配套本专栏食用,如有问题可以QQ交流群:963138186

本篇我们来建立一个STM32的工程。 这个STM32的工程结构还是比较复杂的,需要用到很多文件,之后我们的代码也都是需要建立在工程结构上的。所以在开始学习后续内容之前,我们先来学习一下如何新建STM32的工程。

STM32的三种开发方式

目前STM32的开发方式主要有基于寄存器的方式、基于标准库,也就是库函数的方式和基于Hal库的方式。

基于寄存器的方式

这种方式和我们51单片机的开发方式一样,是用程序直接配置寄存器来达到我们想要的功能,这种方式最底层、最直接,效率会更高一些。但是由于STM32的结构复杂,寄存器太多,所以基于寄存器的方式目前是不推荐的。

基于库函数的方式

库函数是使用ST官方提供的封装好的函数,通过调用这些函数来间接的配置寄存器。由于ST对寄存器分装的比较好,所以这种方式既能满足对寄存器的配置,对开发人员也比较友好,有利于提高开发效率。我们将要学习的就是库函数的开发方式。

基于Hal库的方式

Hal库的方式可以用图形化界面快速配置STM32,这个比较适合快速上手STM32的情况。但是这种方式隐藏了底层逻辑,如果你对STM32不熟悉,基本只能停留在很浅的水平。所以目前暂时不推荐HAL库,但是推荐你学过标准库之后去了解一下这个方式,毕竟这个HAL库还是非常方便的。

那使用库函数的方式,我们需要准备一个STM32库函数的压缩包。

压缩包链接:链接:https://pan.baidu.com/s/1_TWD5z51sjYGjot-1gLWww

提取码:60ix

固件库介绍

首先打开固件库,解压

看到一个STM32F10x标准外设库这个压缩包

把它解压,然后打开解压后的文件夹,第二个文件存放的就是我们库函数的文件

打开就可以看到两个文件,我们之后建工程时会用到

第三个文件project是官方提供的工程示例和模版,以后使用库函数的时候可以参考一下

打开可以看到两个文件

第四个是Utilities是STM32官方评估板的相关例程

打开可以看到一个文件,评估板就是官方用STM32做的一个小电路板,用来测评STM32的,

这个文件夹里面存的就是这个小电路板的测评程序。

接下来后面两个文件,一个是库函数的发布文档,一个是使用手册,发布文档里有一些版本的说明,使用手册里有教怎么使用这个库函数的,大家有时间可以看一下。

那接下来我们就正式开始新建一个基于标准库的工程。

新建基于标准库的工程步骤

首先,我们需要先建立一个存放工程的文件夹。 比如在D盘、E盘等位置。 起个名字可以叫STM32PROJECT

以后我们的工程都存在这个文件夹下,这样比较方便管理。 接着我们打开Keil5软件,点击project project

然后选择我们刚才新建的文件夹,

在这里要再新建一个文件夹,用来存放本次的工程,起个名字叫2-1 STM32工程模板。

然后点进去,接下来给工程文件起个名字,在这里我们可以起一个通用一点的名字。

注意:需要说明这个工程是干啥的话可以在文件夹名称说明, 因为文件夹的名称是很方便改的,而这个工程名称以后不太方便改,所以我们就起个project的名称,然后点击保存。

接下来选择器件型号,我们的芯片型号是STM32F103C8T6,所以这里选择STM32F103C8,点击OK。

这里弹出的是KO软件的一个新建工程小助手,这个可以帮助我们快速新建工程,那我们暂时不用这个小助手,可以把它关掉。

接下来工程就建好了,但是这里的工程文件是空的,现在这个工程还是不能直接用的,

我们需要给它添加一些工程的必要文件,那我们打开固件库的文件夹,

进去打开这个文件夹

进去再打开这个文件

进去再打开这个文件夹

进去再打开

进去再打开这个文件夹

进去再打开这个文件夹

进去再打开这个文件夹

进去再打开这个文件夹

进去再打开这个文件夹

就可以看到这些文件

那这些就是STM32的启动文件,STM32的程序就是从启动文件开始执行的。

我们把这些文件全部都复制下来。

然后回到工程模板文件夹里。可以看到这些就是我们刚才新建工程自动生成的文件,

如果直接把启动文件也放在这里,就有点儿太乱了

所以我们需要新建一个文件夹,可以叫做start。

然后把启动文件粘贴到start这里面。

接着我们回到刚刚固件库的STM32F10X文件夹,

可以看到STM32F10X.h和两个system开头的文件。

这个STM32F10X.h就是STM32的外设寄存器描述文件,它的作用就跟51单片机的头文件regx52.h一样,是用来描述STM32有哪些寄存器和它对应的地址的。 那两个system文件主要是用来配置时钟的。STM32,主频72MHz,就是system文件里的函数配置的。

那我们把这3个文件复制下来,

也粘贴到start文件夹下。

接下来,因为这个STM32是内核和内核外围的设备组成的,而且这个内核的寄存器描述和外围设备的描述文件不是在一起的,所以我们还需要添加一个内核寄存器的描述文件。

我们可以打开CM3,

进去打开这个文件夹

看到两个文件

这两个CM3文件就是内核的寄存器描述。当然它还带了一些内核的配置函数,所以多了个点C文件,我们把它俩一并复制下来,也粘贴到start文件夹下。

到此为止,我们工程的必要文件就复制完成了。

然后我们回到keil软件,把我们刚才复制的那些文件添加到工程里来。

我们可以点击选中这个source group,

然后再单击一下,把这个组改一下名字,也叫start,

接着右键选择添加已经存在的文件到组里来。

打开start文件夹,把下面这个文件过滤器选择all files, 这样我们就能看到文件夹里的所有文件了。

我们首先添加一下启动文件,这个启动文件有很多分类,我们只能添加启动一个。 我们当下学习的所用型号需要选择这个后缀为md.s的启动文件。我们选中它。点击add。

至于启动文件这个怎么选择,文章再讲。

然后剩下的.c和.h文件都要添加进来,我们可以按住CTRL键,然后依次选择它们,点击add,然后close。这样我们start文件夹里面的文件就添加好了。

这里的文件都是STM32里最基本的文件,是不需要我们修改的,我们添加进来即可,那大家可以看到这个文件图标上带了个小钥匙,这个意思是它是个只读文件。

 我们可以打开试一下,这些信息都是不让我们修改的。

最后,我们还需要在工程选项里添加上这个文件夹的头文件路径,要不然软件是找不到点去文件的。

我们点击这个魔术棒按钮,打开工程选项,

在C/C++里找到这个include passes栏,然后点击右边三个点的按钮。

 在这里新建路径,然后再点3个点的按钮,

把start的路径添加进来,点击OK,这样就把这个文件夹的头文件路径添加进来了。

接下来我们再新建一个main函数,看看这个工程是不是可行。   

我们打开工程文件夹,然后新建一个文件夹,叫做user,我们的main函数就放在这个文件夹里。

然后Keil里在target这里右键点击添加组。

改个名字叫user。

然后在User右键点击添加新文件,

选择C文件

名字叫main。 下面的路径注意一下,要选择User文件夹,要不然默认是放在文件夹外面的。

选择改成User文件夹

然后点击add,这样我们就有了main.c文件了。

那在工程文件夹的User目录下也可以看到我们新建的main.c文件。

在这个main.c里,我们先右键插入头文件,选择STM32F10X.H,

然后写一个main函数。

这里注意:main函数是一个int型返回值,void的参数的函数,还有文件的最后一行必须要是空行,要不然会报警告。

然后我们点击这个按钮,编译并建立工程。

可以看到下面提示的是0错误,0警告,那这就说明我们建立的工程是没问题的。

这个工程目前还没有添加STM32的库函数,所以它还是一个基于寄存器开发的工程。 如果你想用寄存器开发STM32,那工程建到这里就可以了。

接下来演示一下如何通过配置寄存器来完成点灯的操作。

配置寄存器来完成点灯操作

当然直接操作寄存器的方式不是我们学习的重点,大家了解一下即可。

接着我们需要拿出STM32的最小系统板和STLINK(或者DAP)以及四根母对母的杜邦线,按照插针边上的标识,把3.3V,SWDIO、SWCLK、GND对应连接好,插好之后就是这个样子的。

SLINK仿真器下载连接图

如果你使用的是DAP,那么就照DAP仿真器下载连接图连接

然后把STLINK或者DAP插在电脑上。

插上电之后,这个板子上的电源灯应该会常亮,另一个连接在PC13口上的灯默认应该是闪烁的状态,这是芯片里的一个测试程序,然后我们在在Keil里面配置一下调试器.

点击魔术棒按钮,选择debug。

这个调试器默认是ULINK,

如果用的是STLIKN, 就改成STLINK debug,如果用的是DAP,就改成DAP debug

然后再点击右边的Setting按钮,

在flash下载这一项,把这个reset and run这一项勾上,勾上这一项之后,我们下载程序后会立马复位并执行,这样方便一些,否则每次下载之后还需要按一下板子上的复位按键才能执行程序。

那配置好调试器之后,点击确认OK,然后重新编译一下。

没有错误

再点击这个Dowdload的按钮,如果一切正常的话,这个程序就会下载到STM32里面了。

我们看一下板子,可以看到这个灯已经不闪了,因为我们目前的程序啥都没有。

那接下来我们就配置一下寄存器来点亮这个灯,我们只需要配置三个寄存器就可以点灯了。

我们可以打开STM32的参考手册,首先是RCC的一个寄存器来使能GPIOC的时钟,

GPIO都是APB2的外设,所以在这个APB2外设时钟使能寄存器RCC APB2ENR里面配置。

可以看到这里有个IOPCEN, 这一位就是使能GPIOC的时钟的。

下面的解释是这一位写1,就是打开GPIOC的时钟。

那这一位写1,其他的无关项我们先都给0,那整个寄存器的二进制数据换成16进制就是四个一分组,也就是00000010。

然后我们回到keil,在while死循环之前写上RCC的APB2ENR寄存器=0X00000010,这样就可以打开GPIOC的时钟了。

然后第二个寄存器,我们需要配置一下PC13口的模式。 我们可以找到端口配置高寄存器GPIOx_CRH,这个x可以是A到E的任意一个字母。

然后右边的CNF13和MODE13就是用来配置13号口的。

下面的说明我们看一下,这个CNF我们需要配置为通用输出模式,也就是这两位为00,MODE要配置为输出模式,最大速度可以给50MHz,也就是这两位为11。

最后我们对照上面的寄存器,这四位为0011,其他的我们也都给它配置为0,这样整个寄存器的值换算成16进制,就是00300000。

然后我们回到keil,在这里写上GPIOC的CRH=0x00300000;

接下来我们就可以给PC3口输出数据了。

我们可以看到这个端口输出数据寄存器GPIOx_ODR。

中间有一位ODR13,这一位写1,13号口就是高电平,写0就是低电平。

如果写1的话,ODR的值就是00002000。

那在这里我们写上GPIOC的ODR=0X00002000;

因为这个灯是低电平点亮的,所以我们给ODR全为0就是亮,给ODR =0X00002000就是灭。

那我们试一下,先给ODR全0。

编译

无错误

下载

这时可以看到这个PC13的灯已经亮起来了。

如果我们给ODR  2000的话

编译下载,再看一下,灯就灭了。

那这就是配置寄存器的方式进行点灯的操作。

可以看出来,这种方式需要不断的查手册,来了解每个寄存器的每一位都是干啥的。而且这个操作方式也有个弊端,就是我们把除了PC13之外的位都配置成了0,这样会影响到其他端口的原有配置。

如果要做到只配置PC13而不影响其他位,那还需要与等于和或等于的操作,这个在51单片机的视频里我们也经常遇到,那这样配置就会更加麻烦。

所以这种寄存器的操作方式虽然代码简洁,但是还是不太方便。

那接下来我们就要为这个工程添加库函数了,看看库函数和寄存器的操作方式有哪些区别。

添加库函数来完成点灯操作

添加库函数

我们打开工程文件夹,在这里新建一个文件夹叫library,用来存放库函数。

接着打开固件库的文件夹,

打开libraries,

stm32标准外设驱动

打开SRC,

这些就是库函数的原文件,

这个misc.c是内核的库函数,其他的就是内核外的外设库函数了,misc就是混杂的意思。

ST公司把内核的库函数都发配到杂项里面去了。

那我们按ctrl +A全选,然后复制

在我们刚刚自己创建的library文件夹下粘贴。

然后再打开固件库的inc文件夹。

这些是库函数的头文件,我们继续ctrl +A全选,然后复制在library文件夹下粘贴。

接着回到Keil软件,同样在target处右键,然后添加组。

改个名字叫library。

再右键添加已经存在的文件,

打开library,

ctrl+A全选,Add

这样就把所有的库函数文件都添加进来了。

但是对于这个库函数来说,现在还不能直接使用,我们需要再添加一个文件。

我们打开固件库文件夹,打开project

打开stm32 template,

可以看到STM32f10x_conf.h和两个it结尾的文件。

这个conf.h文件是用来配置库函数头文件的包含关系的。另外这里面还有一个用来参数检查的函数定义,这是所有库函数都需要的。 2个it.c文件是用来存放中断函数的.

我们把这3个文件复制下来。

然后粘贴到工程的User目录下。

接着回到keil软件,在User组里把刚才那3个文件添加进来。

最后还需要一个宏定义。

我们可以在这个头文件右键打开文件,然后滑到最下面。

看到这个语句,

这是一个条件编译,意思是如果你定义了使用标准外设驱动(USE_STDPERIPH_DRIVER)这个字符串,下面这个#include "stm32f10x_conf.h"语句才有效,所以我们还需要复制一下这个字符串。

然后打开工程选项。

在C/C++的define栏目粘贴这个字符串。

这样才能包含标准外设库,也就是库函数。

当然还有下面的头文件路径,

也不要忘了把这个user和library目录的路径也都添加上,然后OK。

这样我们基于库函数的工程就建好了。

我们可以看一下这个library里面的库函数也都带了钥匙,不需要我们更改。

我们唯一需要更改的就是user组里面的这些文件。

那我们点一下这个三个箱子的按钮,把这个library往上挪一下,把这些不用改的都放到最上面,这样看着舒服一下。

那我们编译看一下。 这个第一次编译会比较慢,以后就快一些了。 可以看到是0错误,0警告,这说明我们的工程建立是成功的。

开始点灯操作

然后我们再用库函数来实现点灯的操作,我们先把这3句删了,

第一步:使能时钟

那库函数其实也是间接的配置寄存器,所以他们的步骤也是一样的,首先是使能时钟,那库函数就有这样一个函数来开启时钟。

RCC_APB2PeriphClockCmd外设时钟控制。 然后这里提示有两个参数,第一个是选择外设,第二个是选择新的状态。

我们可以右键跳到函数定义。

这上面有函数的简介和参数说明:

简介说这个函数是用来使能或者失能APB2的外设时钟。 第一个参数可以是下面这些值。

那我们可以找到APB2外设GPIOC这一项,然后复制。

直接作为第一个参数即可。

然后我们再回过去看第二个参数new state的值可以是enable或者disable。

那么复制enable。

放在第二个参数的位置。

这样GPIOC的外设时钟就配置好了。

我们可以看一下这个函数,它的内部其实还是配置RCC_APB2ERNR这个寄存器,

但是经过函数的包装,我们不需要再去查手册来确认哪一位是干啥的了,而且这里它已经帮我们用“或等于”和“与等于”来操作了,所以这个库函数的配置是不会影响到寄存器的其他位的。这就是库函数和寄存器的区别。

那我们看到这个代码虽然比寄存器长,但是语义更加明确,也不需要我们再查表计算这个寄存器的值了。 我们只需要调用库函数,按照它的提示把参数填好就行了,所以说从这点儿对比上来看,库函数是比寄存器有更大优势的。

第二步配置端口模式

配置端口模式我们需要用到GPIO_Init这个函数。然后有两个参数,第一个是选择哪个GPIO,第二个是参数的结构体。

这个比上一个函数要麻烦一些,但也是一个套路,我们根据提示来配置参数即可。

这里使用了结构体来配置参数,代码逻辑还是有些复杂的,这个我们下篇还会继续讲,大家先跟着操作就行了。

我们首先还是去到这个函数的定义,

可以看到这个函数的介绍是根据GPIO_Init结构体的参数来配置GPIO,

第一个参数GPIOx,其中X可以是A到G,来选择你要配置哪个GPIO,

那我们是PC13口的led,所以第一个参数就写GPIOC:

第二个参数是一个GPIO_InitTypeDef的结构体

我们需要先定义一个结构体。那在上面我们先把这个结构体的类型写上。

然后给结构体起个名字,这个名字可以随便起,但是根据官方的推荐,我们最好起这样的名字,叫GPIO_InitStructure;

然后我们把结构体的每一个参数填上。 复制粘贴结构体的名字

然后用”.”来引出结构体的参数,可以看到这个结构体有3个参数,分别是GPIO模式,GPIO端口,GPIO速度。

那我们先把这3个参数都罗列出来。

最后也还是一样,右键转到mode的定义,

在右边的介绍说,这个参数可以是GPIO Mode_TypeDef里面的一个值。

因为这是注释里面的东西,所以没办法用右键跳转了。 那这里我们需要选中这个字符,按一下CTRL+F,搜索一下这个定义的位置。

点击find next,

可以看到这是个枚举,GPIOMode就是这里的其中一个值。

然后我们选择Out_PP这一项,复制,这个就是通用推挽输出

然后在这里写上GPIO_Mode_Out_PP;

这样这个参数就配置好了。

然后我们继续看下一个参数,同样转到它的定义这里,

下面出现了一个框,这个是说它的定义有很多个,我们来看一下。

我们选择这个member这一项双击,

然后跳转的其实还是刚才那个位置。

然后看一下这个GPIO_Pin的说明,它说这个参数在GPIO_ pins_define里面定义了

我们还是一样,选中ctrl+F,find next.

可以看到这里有个宏定义的列表,

我们选择GPIO_Pin_13,复制,然后填在第二个位置,

第三个参数也是一样,右键跳到定义。选中ctrl+F, find NEXT

在这里选中50MHz的速度复制。

在这里粘贴,

那结构体变量就有了,我们就可以填这个GPIO_Init的第二个参数了。 那在这里有说明,这个第二个参数是一个指向结构体的指针。

所以这里我们需要传递结构体的地址,那我们复制结构体的名字,粘贴到这个位置,然后前面加上一个取地址的符号。

这个GPIO模式配置就完成了。

这个配置的操作方式看上去比较难理解,但是STM32的这种方式都是固定的,大家多打几次就知道怎么用了。

第三步:设置端口的高低电平

最后我们设置端口的高低电平来进行点灯:

这里有个函数GPIO_SetBits, 这个就可以把指定端口设置为高电平,大家也可以右键去看一下参数的说明。

那这里我就直接填了,第一个是GPIOC,第二个是GPIO_Pin_13

这一句就可以将PC13号口置为高电平。

接下来置低电平也有函数,叫GPIO_ResetBits,参数同样是GPIOC,第二个是GPIO_Pin_13

这一句就可以将PC13号口置为低电平。

我们依次试一下。

先把高电平的注释掉,编译并下载,可以看到灯已经亮了,

再把低电平的注释掉,编译并下载,可以看到灯就灭了,

那这就是使用库函数的基本操作了。

最后还要补充新建工程里的启动文件选择。

新建工程里的启动文件选择

我们新建工程第一个加的就是启动文件。

这个启动文件有很多类型,至于选择哪一个,我们要根据芯片型号来选择。

那我们看这个表,

这里是STM32F1系列中的型号分类,其中根据flash的大小分为了:小容量产品flash为16~32K,简写为LD,中容量产品flash为16~128K,简写为MD,大容量产品flash为256~512K,减小为HD,加大容量产品flash>512K,简写为XL。

STM3F100的系列,ST把它叫做超值系列,简写为VL(Value Line);

STM32F105和107系列,ST把它叫做互联型产品,这个就没有根据flash大小再分类了。 如果你使用STM32F100的型号,就选择带VL的启动文件,然后再根据flash的大小选择LD、MD还是HD;如果你使用STM32F101/102/103的型号,就选择不带VL的,然后根据flash的大小选择LD/MD/HD还是XL。如果你使用STM3F105/107的型号,直接选择CL的启动文件即可。

那在这里我们可以看一下,

这个启动文件后面带的字母和表中的字母都是对应的,这样我们就知道了我们这个STM32F103的芯片就需要选择这四列。

又因为C8T6的flash是64K,所以选择MD的启动文件。

这就是STM32F1系列的型号分类和启动文件的选取。

总结一下新建工程的步骤

接下来我们再总结一下新建工程的步骤:

第一步,建立工程文件夹Keil中新建工程选择型号

第二步,工程文件夹里建立start library user等文件夹,复制固件库里面的文件到工程文件夹。这一步是为了添加工程文件准备的,建文件夹是因为文件比较多,需要分类管理一下。 这个文件夹的名称和数量没有限制,大家也可以根据自己的理解来建。另外,需要用的文件一定要复制到工程文件夹里面来,不要添加工程文件夹外面的文件。要不然你外面的文件一旦挪位置,工程里就找不到文件了,所以我们要复制文件到工程里来,保持工程的独立性。

第三步是工程里对应建立start library user等同名称的分组,然后将文件夹内的文件添加到工程分组里。 这一步的原因是在keil里方便管理文件,因为keil没法直接添加文件夹,所以还得重复一下,在keil里建立分组,然后添加文件。这个添加文件我们是把所有的.h文件和.c文件都添加进来了。因为.h文件是不参与编译的,所以其他很多工程都是不添加.h文件的。但是我认为把.h文件加进来比较方便,而且.h文件也是需要经常打开看的,所以我比较习惯把所有的文件都添加进来。

步是工程选项C/C++,Include Paths内声明所有包含头文件的文件夹。这一步是因为你这个start、 library等文件夹是你自己建的,keil软件并不知道,所以你要用自己文件夹里面的.h文件,就必须声明一下这个路径。最好就是你自己建的所有文件夹都声明一下,这样就不会出现.h文件找不到的问题了。

步是工程选项C/C++,Define内定义USE_STDPERIPH_DRIVER(使用标准外设驱动这个字符串。这是使用库函数的条件编译,使用库函数就必须定义这个。另外,其他的工程在这个位置还声明了一个STM32F10X_MD的字符串,由于Keil在新建工程后自动就帮我们声明好了,这个不需要再额外声明了。所以在这个位置只需要声明使用标准外设驱动的字符串即可。 第六步是工程选项debug,下拉列表选择对应调试器settings ,flash download, 勾选reset and run, 这个就是选择调试器来进行下载的选项了,我们用STLINK, 就选择STLINK的那一项即可,如果用DAP,就选择DAP即可。

这就是新建工程的基本步骤,新建工程也是很灵活的,大家只要符合要求都可以编译通过。 每个人建工程的风格也不同,大家学会了之后,也可以建立一个属于自己风格的工程。

最后再额外的讲一下这个工程的架构。

工程的架构解析

看一下这个工程的每个文件都是干啥的,为啥需要这些文件?

那我们看到这个图,

首先是startup启动文件,这个是程序执行最基本的文件。 我们可以看到,keil中启动文件是用汇编写的。

启动文件内定义了中断向量表、中断服务函数等。 那这个中断服务函数中有一个复位中断,这就是整个程序的入口。 当STM32上电复位或者按下复位按键之后,程序就会进入复位中断函数执行。 复位中断函数主要就做了两件事情,第一个是调用SystemInit函数,第二个是调用main函数。对应启动文件的这里:

可以看到这是复位的中断函数,然后调用SystemInit, 再调用main,然后程序就结束了。

当然,实际上单片机的程序永远也不会结束,所以在main函数的最后一定是一个死循环。

SystemInit函数就是定义在这个System开头的.c文件里的。 在keil里我们也可以看到这个函数的定义:

这里的简介写了这个函数的作用,是设置微控制器的启动,初始化嵌入式闪存接口、锁相环、更新系统内核的时钟变量。下面的note写的是这个函数仅在复位后需要调用。

那下面这些就是用来配置这些东西的,这个也不需要我们更改,我们只需要知道在main函数之前,单片机就已经执行了一堆东西了,帮我们把这个闪存接口、时钟等一系列杂碎的东西都配置好了。

另外在启动文件还定义了STM32所有的其他中断。

这些中断达到触发条件后就会自动执行。

在启动文件下面都是其他的中断调用了。

中断函数的定义就是在STM32Fx_it里面的。我们打开keil可以看到这些就是中断函数的定义。

ST建议我们把自己的中断写在这个位置,

当然我们还是习惯在哪用中断就写在哪里,写在别的地方也是可以的。

这些就是中断部分的执行逻辑了,另外也可以自己定义一些用户文件来封装一些模块供主函数和中断调用,这些也都是没问题的,同时也有利于我们程序结构的模块化。要不然所有的程序都堆在主函数里,那主函数就太长了。

到此为止,这个工程结构主动执行的部分就介绍完了,剩下右边的就是被动执行的东西了,相当于STM32的资源,我们在主函数或者中断函数里就可以调用这些资源。

右上角这两个STM32F10x.h和core_cm3这些文件就是外设和内核外设的寄存器描述。 在keil中我们可以看到这里面都是寄存器和寄存器每一位的名字,还有地址信息等。

如果直接调用这些寄存器来使用STM32,那就是寄存器的开发方式,我们已经试过了,这种方式会有一些弊端,也比较麻烦。 所以ST公司就提供了下面这两个文件,这个就是库函数的文件。

在keil中可以看到这每个外设都提供了一大堆的函数。

这些函数封装了寄存器的操作,给我们提供更加人性化的函数调用方式,只要学会了操作套路,那配置一个外设就是很简单的,连手册都不需要看一眼。

这个conf文件就是用来配置头文件的包含关系的。

我们可以看到,在这里conf文件include了所有的库函数头文件。

同时,我们在STM32F10x.h的最后又包含了conf.h,

所以在使用这些库函数时,我们只需要包含STM32F10x.h这一个头文件,就相当于包含了所有的库函数头文件,这样我们就可以任意的调用库函数了。

这些就是整个工程的结构和每个文件的作用。 下一节就开始从这个工程上学习STM32的第一个外设GPIO。

以上步骤记不住没关系,后面正式用面包板组装电路进行点灯的时候还会复习一遍,那个时候就会对新建工程的步骤很清晰了。

以上先做个基本的了解,不要求记忆,以后学完了就熟悉了。

QQ交流群:963138186

本篇就到这里,下篇继续!欢迎点击下方订阅本专栏↓↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/735629.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ic基础|功耗篇03:ic设计人员如何在代码中降低功耗?一文带你了解行为级以及RTL级低功耗技术

大家好,我是数字小熊饼干,一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结,并通过汇总成文章的形式进行输出,相信无论你是在职的还是…

鞠婧祎多个商标被丝芭传媒申请注册!

近日鞠婧祎与丝芭传媒合约引发网络关注,普推商标老杨经检索发现,丝芭传媒早在2016起就申请注册了“鞠婧祎”24个商标,涉及多个商标分类,这些基本都下商标注册证。 不管对经纪公司还是网红公司,有实力的基本都会对旗下的…

# Kafka_深入探秘者(2):kafka 生产者

Kafka_深入探秘者(2):kafka 生产者 一、kafka 消息发送流程解析 1、kafka :java 客户端 数据生产流程解析 二、kafka 发送类型 1、kafka 发送类型–发送即忘记:producer.send(record) 同步发送 //通过 send() 发送完…

【Vue3组件】分享一下自己写的简约风格评论区组件

代码比较简单,方便大家二次开发,旨在快速提供基础的样式模板,自行迭代定制 预览 简介 通用评论组件 组件功能 此组件旨在创建一个具备嵌套回复能力的通用评论区域,适用于构建动态、互动性强的用户讨论场景。 接收数据结构 组件通…

Paimon Trino Presto的关系 分布式查询引擎

Paimon支持的引擎兼容性矩阵: Trino 是 Presto 同项目的不同版本,是原Faceboo Presto创始人团队核心开发和维护人员分离出来后开发和维护的分支,Trino基于Presto,目前 Trino 和 Presto 都仍在继续开发和维护。 Trino 生态系统-客…

虚拟机IP地址频繁变化的解决方法

勾八动态分配IP,让我在学习redis集群的时候,配置很多的IP地址,但是由于以下原因导致我IP频繁变动,报错让我烦恼!!!! 为什么虚拟机的IP地址会频繁变化? 虚拟机IP地址频繁…

webpack处理js资源10--webpack入门学习

处理 js 资源 有人可能会问,js 资源 Webpack 不能已经处理了吗,为什么我们还要处理呢? 原因是 Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运…

Zabbix+Garafana监控部署

ZabbixGarafana监控部署 一、IP规划 服务器IP备注zabbix-server192.168.100.128zabbix服务端zabbix-mysql192.168.100.130数据库zabbix-client192.168.100.132zabbix客户端garafana-server192.168.100.134Garafana 二、zabbix-server安装zabbix ​ 配置IP地址为&#xff1a…

俄语打招呼和问候的12种表达方式,柯桥俄语培训

- Как дела ? 近况如何? -Нормально, а ты как? 还行吧,你呢? Vol.2 -Как себя чувствуете? 你感觉如何? -Все замечательно! 一切都非常棒。 Vol.3 -Ка…

基于matlab的图像灰度化与图像反白

1原理 2.1 图像灰度化原理 图像灰度化是将彩色图像转换为灰度图像的过程,使得每个像素点仅包含一个灰度值,从而简化了图像的复杂度。灰度化原理主要可以分为以下几种方法: 亮度平均法 原理:将图像中每个像素的RGB值的平均值作为…

Vue40 修改默认配置

修改默认配置 在官网查看各个属性的作用 ### 在vue.config.js文件中,修改属性的值

计算机网络 静态路由及动态路由RIP

一、理论知识 1.静态路由 静态路由是由网络管理员手动配置在路由器上的固定路由路径。其优点是简单和对网络拓扑变化不敏感,缺点是维护复杂、易出错,且无法自动适应网络变化。 2.动态路由协议RIP RIP是一种基于距离向量的动态路由协议。它使用跳数作…

接口自动化拓展:Flask框架安装、介绍及工作中的应用!

Flask是一个轻量级的Python Web框架,用于构建Web应用程序和API。它简洁而灵活,容易上手,并且非常适合用于开发小型到中型规模的应用程序。在接口自动化测试中,Flask可以作为服务器框架,用于搭建测试接口。 本文将从零…

使用USI作为主SPI接口

代码; lcd_drive.c //***************************************************************************** // // File........: LCD_driver.c // // Author(s)...: ATMEL Norway // // Target(s)...: ATmega169 // // Compiler....: AVR-GCC 3.3.1; avr-libc 1.0 // // D…

UltraEditUEStudio软件安装包下载及安装教程

​根据软件大数据显示提供预定义的或使用者创建的编辑“环境”,能记住 UltraEdit 的所有可停靠窗口、工具栏等的状态。实际上我们可以这样讲HTML 工具栏,对常用的 HTML 功能作了预配置;文件加密/解密;多字节和集成的 IME。根据使用者情况表明Git Editor&…

day41--Redis(三)高级篇之最佳实践

Redis高级篇之最佳实践 今日内容 Redis键值设计批处理优化服务端优化集群最佳实践 1、Redis键值设计 1.1、优雅的key结构 Redis的Key虽然可以自定义,但最好遵循下面的几个最佳实践约定: 遵循基本格式:[业务名称]:[数据名]:[id]长度不超过…

【Linux系列】find命令使用与用法详解

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-26网络中的网络NiN

26网络中的网络NiN import torch from torch import nn import liliPytorch as lp import matplotlib.pyplot as plt# 定义一个NiN块 def nin_block(in_channels, out_channels, kernel_size, strides, padding):return nn.Sequential(# 传统的卷积层nn.Conv2d(in_channels, ou…

兰州理工大学24计算机考研情况,好多专业都接受调剂,只有计算机专硕不接收调剂,复试线为283分!

兰州理工大学(Lanzhou University of Technology),位于甘肃省兰州市,是甘肃省人民政府、教育部、国家国防科技工业局共建高校,甘肃省高水平大学和“一流学科”建设高校;入选国家“中西部高校基础能力建设工…

年薪50w+的项目经理,手把手教你如何复盘

复盘是一种重要的学习和改进工具,对于项目经理来说,能帮助识别项目中的成功与失败,为未来的项目管理提供宝贵经验。 理论部分 定义目标。在开始复盘之前,明确复盘的目标是什么。是为了找出项目中的问题并提出解决方案&#xff0c…