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

news2024/11/25 4:49:02

目录

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何降低MCU系统功耗?

大家在做MCU系统开发的时候,是否也碰到过降低MCU系统功耗的需求? MCU系统整板功耗是个综合的数据,包括MCU功耗以及外部器件功耗,在此我们主要介绍如何降低MCU的功耗: 可以在满足应用的前提下,降低MCU的运…

MySQL之复制(十三)

复制 复制的问题和解决方案 在主-主复制结构总写入两台主库 试图向两台主库写入并不是一个好主意,如果同时还希望安全地写入两台主库,会碰到很多问题,有些问题可以解决,有些则很难。一个专业人员可能需要经历大量的教训才能明白…

2024 年值得推荐的 10 款 iPhone 数据恢复软件

iPhone 从来都不是一个简单的打电话电话。它就像一台微型电脑,让我们互相联系、拍照、拍视频、发邮件、看文档、看书。然而,随着它成为日常生活的必需品,我们总是容易因各种原因丢失数据,如删除、恢复出厂设置、iOS 错误、文件同步…

Day11 —— 大数据技术之Spark

Spark快速入门系列 Spark的概述什么是Spark?Spark的主要特点Spark的主要组件 Spark安装Spark三种运行模式Spark Standalone架构Spark Standalone的两种提交方式Spark On YARN架构 RDD算子转化算子行动算子 Spark RDDRDD的创建从对象集合创建RDD从外部存储创建RDD Sp…

Apollo9.0 PNC源码学习之Planning模块(一)—— 规划概览

0 前言 规划本质就是搜索问题,数学角度来看就是寻找函数最优解 规划模块复杂的就是相关的逻辑处理和过程计算 对于规划的三维问题,目前解决方案:降维+迭代 将SLT问题分解为ST和SL二维优化问题:在一个维度优化之后,再另一个维度再进行优化,最后整合成三维的轨迹。 虽然降…

Linux常用命令(15)—grepsed命令(有相关截图)

写在前面: 最近在学习Linux命令,记录一下学习Linux常用命令的过程,方便以后复习。仅供参考,若有不当的地方,恳请指正。如果对你有帮助,欢迎点赞,关注,收藏,评论&#xf…

【2024.6.23】今日 IT 速递 | 亚布力创新年会热点新闻盘点

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

细胞核的分割与分类模型·hover net| 补充文档

小罗碎碎念 这期推文算是hover net系列的一个补充文档,把几个非常重要的脚本拿出来单独做了一个分析,感兴趣的自取。 extract_patches.pyconfig.pydataset.pyopt.pyrun_infer.py 一、extract_patches.py 1-1:加载和处理图像数据集 注意 da…

53【场景作图】纵深感

1 想清楚什么是前 什么是后 如果背景虚化,就不要处理地很平面,如果很平面,就留一个清晰的边缘 2 重叠 遮挡 被遮挡的物体会更远

如何让表格标题栏具有粘性?

让表格标题栏具有粘性 什么意思呢? 就是当表格的内容(行数)比较多的时候, 滚动屏幕,看下面的内容的时候, 表格标题栏可以一直显示在屏幕最上方, 以前呢, 我会通过JSCSS 的 pos…

开发一个python工具,pdf转图片,并且截成单个图片,然后修整没用的白边及循环遍历文件夹全量压缩图片

今天推荐一键款本人开发的pdf转单张图片并截取没有用的白边工具 一、开发背景: 业务需要将一个pdf文件展示在前端显示,但是基于各种原因,放弃了h5使用插件展示 原因有多个,文件资源太大加载太慢、pdf展示兼容性问题、pdf展示效果…

基于nsight_compute进行kernel性能分析

当利用nsight进行性能分析时,当涉及到内核级别的性能分析时,nvidia提供了系统级别(nsight system),和内核级别的性能分析工具(nsight compute)。 其中,内核级别的性能分析,可以检查kernel实现的…

apollo规划架构

算法的基本架构 我们在最开始直接给出规划决策算法架构框图,然后一一介绍每个框图结构的细节: 模块的入口是 PlanningComponent,在 Cyber 中注册模块,订阅和发布消息,并且注册对应的 Planning 类。Planning 的过程之前…

基于SpringBoot+Vue教材订购系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…

DNF手游攻略:云手机辅助流光星陨刀详细攻略大全!

DNF手游中,流光星陨刀是鬼剑士的专属神器之一,拥有快速的攻击速度和优秀的物理与法术攻击属性,因其出色的性能和未来升级的潜力,成为广大玩家关注的焦点。 流光星陨刀的背景与起源 流光星陨刀作为鬼剑士的标志性武器之一&#xf…

使用 Ubuntu x86_64 平台交叉编译适用于 Linux aarch64(arm64) 平台的 QT5(包含OpenGL支持) 库

使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库 目录 使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库写在前面前期准备编译全流程1. 环境搭建2. 复制源码包并解压,创…

论文《Universal Graph Convolutional Networks》笔记

【UGCN】论文提出一个基本问题,即是否不同的网络结构属性应该采用不同的传播机制。通过实验发现,对于完全同配性、完全异配性和随机性的网络,1-hop、2-hop和k-nearest neighbor(kNN)邻居分别更适合作为信息传播的邻域。…

stm32学习笔记---GPIO输出(理论部分)

目录 GPIO通用输入输出口 GPIO的基本结构 I/O端口位的基本结构 输入部分 输出部分 推挽模式 开漏模式 GPIO的8种工作模式 STM32手册GPIO和AFIO大致介绍 STM32外部的设备和电路 声明:本专栏是本人跟着B站江科大的视频的学习过程中记录下来的笔记&#xff0…

CISP-PTE综合靶机-WinServer2003

1.收集网站的地址和开放的端口,完成前期信息收集。10分 2.访问站点,找出站点的敏感文件,利用返回数据找到相关敏感信 息,完成网站结构的信息收集。10分 3.利用文件包含漏洞读取敏感文件,找出数据库连接凭证,利用此 凭证连接数据库。10分 4.网站后台提权:找出后台管理员登…

Attention系列总结-粘贴自知乎

1. 梦想做个翟老师:阿里:Behavior Sequence Transformer 解读48 赞同 7 评论文章 优点:捕捉用户行为历史序列中的顺序信息。w2v也是捕捉用户序列信息的,本质差异在于啥? 添加图片注释,不超过 140 字(可选&#xff0…