本博文是基于建立好STM32的keil5软件后建立工程,如果还没下载软件建议先下载好该软件,在
B站江科大32教学有,并把相关文件下好。
STM32的开发方式有:基于寄存器的方式,基于标准库也就是库函数的方式,基于HAL库的方式,基于寄存器的方式与使用51单片机一样,是程序直接配置寄存器。来达到我们想要的功能,最底层,也最高效,但是由于STM32的结构复杂,寄存器太多,所以基于寄存器的方式不推荐。
基于库函数的方式是使用ST官方提供封装好的函数,通过调用这些函数来间接配置寄存器,由于ST对寄存器封装的比较好,所以这种方式既能满足对寄存器的配置,对开发人员也比较友好,提高了开发效率。所以我们大多都是使用这种方式。
基于HAL库的方式可以用图形化界面快速配置STM32,这个适合快速上手STM32的情况,但是这种方式隐藏了底层逻辑,如果你对STM32不熟悉,基本只能停留在很浅的水平,所以这种方式不太推荐,建议了解标准库这种方式后,再去好好了解一下这种方式,毕竟HAL库是非常方便的。
使用库函数的方式,我们需要准备一个STM32库函数的压缩包。
打开下载好的文件夹 打开固件库:有如下文件
1.
这个文件里面就是库函数的文件了,我们之后建立工程会用到
2.
project是官方提供的·工程示例和模版,以后使用库函数可以参考一下
3.
Utilities是STM32官方评估板的相关例程,
这个评估板就是官方用STM32做的一个小电路板,用来评测STM32的。
所以这个文件夹里面存的就是这个小电路板的测评程序。
4.
一个是库函数的发布文档,一个是使用手册。
使用手册有教如何使用这个库函数的。
好,我们接下来就正式开始新建一个基于标准库的工程。
我们先先建一个存放工程的文件夹,这里我在桌面建立了一个文件夹。
打开Keil5,选择如下:
在自己建立的文件夹中再新建一个文件:
点击上图文件夹2-2STM工程模版1,起一个工程的名字,一般通用project,点击OK,
进入选择芯片环节。(前提是已经安装好32的软件)选择如下芯片
选择自己要操作的芯片,我这里是
点击ok,出现如下界面:这里弹出的是keil软件的一个新建工程小助手,这个可以帮助我们快速新建工程,我们暂时不用这个小助手,可以叉掉。
下面工程就是建好了,但是这里工程文件空空如也,这个工程还是不能直接用的。我们需要给他添加一些工程的必要文件,
打开上面 固件库的文件夹,打开
依次打开如下文件:
最后见到如下界面:这些就是STM32的启动文件,STM32的程序就是从启动文件开始执行的,
我们把这些文件全部复制下来,回到工程模版文件夹里,也就是我之前建立工程的文件夹中。如下图,如果把启动文件全部复制在里面,会显得太乱了,
我们在这里再新建一个文件夹,名字自己起:我这里新建一个Start文件夹,把刚刚粘贴的文件复制在这个文件夹里面。
接着回到 固件库里面STM32F10x这个文件夹。即如下图所示。
会看到如下界面:有stm32f10x.h和两个system开头的文件。
这个stm32f10x.h,就是STM32的外设寄存器描述文件。他的作用与51单片机头文件REGX52.h一样,是用来描述STM32有哪些寄存器和他对应的地址的,两个system文件是用来配置时钟的,STM32主频72Mhz,就是system文件里的函数配置的。
所以我们把这三个文件复制下来,粘贴到Start这个文件夹里面
接下来,因为这个STM32是内核和内核外围的设备组成的,而且这个内核的寄存器描述和外围设备的描述文件不是在一起的,所以我们还需要添加一个内核寄存器的描述文件。
打开如下文件夹:
看到如下界面:
这两个cm3文件就是内核的寄存器描述。当然,他还带了一些内核的配置函数所以多了个.c文件,我们把这两个一起复制下来。粘贴到Start文件夹下。
start文件夹有如下文件
到此,我们工程的必要文件就复制完成了。
回到keil5软件。 接着如下操作,把Source Group 1 改名字为Start,单击一下就好了
点击如下操作:右键点击Start.
选择我们之前建好的Start文件,
我们首先添加一下启动文件,这个启动文件有很多分类,我们只能添加其中一种。
我们所用的型号需要选择这个后缀为md.s的启动文件,启动文件如何选择,后面我会讲、
然后把带有文件.c和.h文件都添加进来,下图是所要的文件总和。
好,到这里,我们Start文件夹里面的文件就添加好了。
这里的文件都是STM32里最基本的文件,是不需要我们修改的,我们添加进来即可。
我们看上图文件图标上带了个小钥匙,这个意思是他只是个只读文件。不能修改的。
最后我们还需要在工程选项里添加上这个文件夹的头文件路径
要不然软件是找不到.h文件的。按如下操作进行:
选择Start文件夹,点击OK,后会出现如下图所示
点击ok,这样我们就把这个文件夹的头文件路径添加进来了。
最后,在建立的文件夹里再先建一个User文件,用来存放我们的main函数
再继续如下操作。右键Target,
把新建的文件夹改名为User
到这里,这个工程目前还没有添加STM32的库函数,所以还是基于寄存器开发的工程。
如果你想用寄存器开发STM32,那工程建到这就可以了,
下面用寄存器完成点灯操作。在操作之前,可以完成如下设置。
打开STM32参考手册,首先是RCC的一个寄存器,来使能GPIOC的时钟 ,GPIO都是APB2的外设,所以在这个APB2外设时钟使能寄存器RCC_APB2ENR里面配置
如图所示,这一位就是使能GPIOC的时钟的,
接下来我们找到端口配置高寄存器GPIOx_CRH,这个x可以是A到E的任意一个字母,
然后下图的CNF13和MODE13就是用来配置13号口的,
这个CNF我们需要配置为通用推挽输出模式,
MODE要配置为输出模式,最大速度可以给50MHZ
接下来我们就可以给PC13口输出数据了。找到下图输出寄存器。
因为灯是低电平点亮的,所以我们给ODR全为0就是亮。
给ODR 0x00002000就是灭。下图所示代码,就是点亮灯,
下图所示代码,灯就灭了。
上面就是配置寄存器的方式进行点灯操作。可以看出这种方式需要不断查手册来了解每一个寄存器的每一位是用来干啥的,而且这个操作方式也有一个弊端,就是我们除了PC13之外的位都配置了0,这样就会影响到其他端口的原有配置,如果我们要做到只配置PC13而不影响其他位,需要&=和|=的操作,所以寄存器的操作方式,代码简单,不太方便操作。
接下来我们位这个工添加库函数,看看库函数与寄存器的操作方式有哪些区别。
新建一个文件夹,叫做library,用来存放库函数。
打开下列文件夹
出现
misc.c就是内核的库函数,其他的是内核外的外设库函数,CTRL+A全选
粘贴到新建的文件夹Library中
打开如下图文件,
下图是库函数的头文件:全选,复制,粘贴到新建的文件夹Library中
同理,在keil5中新建一个组,改名字为Library,然后把刚刚所有 文件放进来。如图所示
但是对于这个库函数来说,现在还不能使用,我们需要再添加一个文件。
打开如图文件夹
把箭头指向的三个文件复制下来粘贴到User的文件夹里面
在keil5里面把三个文件添加进来。
最后需要一个宏定义,我们可以右键如图的头文件,打开文件
找到下图所示,在上面的文件最下面,这是一个条件编译。意思是如果你定义了USE_STDPERIPH_DRIVER这个字符串,下面这个#include "stm32f10x_conf.h"才有效
我们复制 USE_STDPERIPH_DRIVER这个字符串,点击魔术棒,在下面图示粘贴。
这样才能包含标准外设库,也就是库函数。
按之前的操作,把User和Library路径也添加上
这样,基于库函数的工程所有操作就完成了,
下面我们用库函数实现点灯操作。
库函数 也是间接配置寄存器,所以操作步骤差不多。
首先是使能时钟,那库函数就有这样一个函数来开启时钟
RCC_APB1PeriphClockCmd()这个函数有两个提示。第一个是选择外设,第二个是选择新的状态。
外设,状态选择下图所示,
GPIO_Init()也有两个参数,一个是选择哪个GPIO,第二个是参数的结构体。
第一个是GPIOx,其中x可以是A到G,来选择你要配置哪个GPIO,
我们是PC13口的LED,所以我们第一个参数就写GPIOC,
第二个参数是一个GPIO_InitTypeDef的结构体,我们需要先定义一个结构体
我们先把结构体的类型写上,先给结构体起一个名字,官方建议起GPIO_InitStructure
然后我们用.来引出结构体的参数,可以看到这个结构体有三个参数,分别是GPIO模式,GPIO端口,GPIO速度,
我们转到GPIOmode的定义,
右边介绍说,这个参数可以是GPIOMode_TypeDef里面的一个值。
我们选中这个GPIOMode_TypeDef字符,按一下Ctrl+F,搜索一下定义的位置。
可以看出,这是个枚举,GPIOMode就是这里的其中一个值。
然后我们选择out-pp,复制,这一个就是通用推挽输出。
同理,我们转到GPIO_pin的定义,这时出现下面这个框,这是说他定义有很多个,
我们选择下图所示,跳转。
下图可知,它说,这个参数在GPIO_pins_define里面定义了
同理,选择GPIO_pins_define,按一下Ctrl+F,搜索一下定义的位置。可以看到下图宏定义列表
我们选择GPIO_pin_13,复制。
最后一个同理,找到他最原始的定义,复制,最后是下图的代码所示。
OK,结构体变量就有了,我们就可以填这个GPIO_Init 第二个参数了
这里说明了,第二个参数是一个指向结构体的指针。所以我们需要传递结构体的地址。
&GPIO_InitStructure 就是结构体的地址,
上面就是GPIO模式配置就完成了。
这个配置的操作方式看上去十分难理解,但是STM32的这种方式都是固定的, 大家多打几次就会用了,
最后设置高低电平来进行点灯。
GPIO_SetBits这个函数就可以把指定端口设置为高电平。
GPIO_SetBits(GPIOC,GPIO_Pin_13);这样就可以把PC13号口设置为高电平。
置低电平也有函数,GPIO_ResetBits
GPIO_ResetBits(GPIOC,GPIO_Pin_13);这样就可以把PC13号口设置为低电平。
OK,上面就是使用库函数的基本操作了,
至于STM32 GPIO口的结构,结构体和库函数的操作那些,下一篇博客会详细介绍。
下面是一些注意事项:
首先是新建工程里的启动文件选择,我们新建工程第一个加的是启动文件。
这个启动文件有很多类型。至于选择哪一个,我们要根据芯片型号来选择。
下图是STM32F1系列中的型号分类,其中根据flash的大小,分为下图所示
最下面CL不是根据flash大小来分。根据不同型号,再根据flash大小,选择启动文件。
总结一下先建工程的步骤:
工程的架构: