LED闪烁&LED流水灯&蜂鸣器

直插LED正负极区分(3种最简单方法,一看就懂)
- 看引脚长度(最常用)
◦ 长脚 = 正极(阳极 A)
◦ 短脚 = 负极(阴极 K)
- 看灯珠内部铁片
◦ 小块铁片 = 正极
◦ 大块铁片 = 负极(图里能清晰看到,一边大一边小)
- 看灯头边缘
◦ 灯珠侧边有扁平缺口/切角的一侧:为负极




系统的供电是 STLink 的 3.3 伏,接到最小系统。然后最小系统又通过跳线接到上下四排的供电孔上。最后我们拿出一个 LED, 长脚正极接到正极供电孔,短脚负极接到 PA0 端口上。
这里采用低电平点亮方式,为了方便没有接限流电阻:



新建工程:




新建三个文件夹:


放到Start:

这也放到这里:



标准外设驱动文件:复制到Library下




复制到user:main也复制过来不用新建文件了



















小工具:

我把它放到了工程的第二个文件夹里。这个东西是一个批处理文件,它可以把工程编译产生的中间文件都删掉。我们可以把它复制到工程文件夹里,放在这里。

因为这个工程编译产生的文件比较大,我们可以看一下。这个 LED 闪烁的工程就有 20 兆。

这里主要大空间的就是 listing 和 objects 这两个文件夹。这些都是工程的中间文件。如果你要把工程分享给别人的话,可以先双击一下这个批处理文件。这时它就会把这些中间文件都删掉,我们再看一下,这样就只要两兆左右的大小了。然后你就可以把这个文件夹打包,把工程分享给别人了。好
操作 STM32 的 GPIO 总共需要三个步骤。
第一步使用 RCC 开启 GPIO 的时钟。
第二步使用 GPIO 一例的函数初始化 GPIO。
第三步使用输出或者输入的函数控制 GPIO 口。
在这里总共涉及了 RCC 和 GPIO 两个外设。那我们先来看一下这两个外设都有哪些库函数吧。
我们可以在 library 中找到 RCC .h 这个文件,双击打开,然后拖到最下面。

在点 h 文件的最下面一般都是库函数所有函数的声明啊。在这里我们可以看到 RCC 有很多的库函数,但实际上这里的大部分函数我们都不会用到,我们最常用的只有这三个函数, RCC_ AHB1 外设时钟控制, RCC_ APB2 外设时钟控制, RCC_ APB1 外设时钟控制。我们可以右键跳到定义啊

接着我们再看一下 GPIO 的库函数。我们打开 GPIO . h 的文件,然后拖到最后。这些就是 GPIO 的全部库函数了。我们目前需要了解的就是前面的这些函数。
第一个就是 GPIO DInit,参数可以写 GPIOA、 GPIOB 等等。调用这个函数之后,所指定的 GPIO 外设就会被复位啊,这就是这个函数的用途。
第二个 A F L DInit 也是一样,可以复位 A F L O外设。这个 A F LO 我们后面再接着
第三个 GPIO_ Init 就是非常重要的函数了。这个函数的作用是用结构体的参数来初始化 GPIO 口。我们需要先定义一个结构体变量,然后再给结构体赋值,最后调用这个函数,这个函数内部就会自动读取结构体的值,然后自动把外设的各个参数配置好。这种以例的函数在 STM32 中基本所有的外设都有啊。一般我们初始化外设都是使用这个以例的函数来完成的。
然后第四个是 GPIO_ Struct_ 以例的,这个函数可以把结构体变量赋一个默认值。
接下来这四个就是 GPIO 的读取函数了,然后下面跟着的四个就是 GPIO 的写入函数,这些函数就可以实现读写 GPIO 口的功能。然后剩下的这些函数呢我们暂时不会用到,所以这里面重要的函数就是 GPIO Init和这 8 个读写函数。

点亮LED:
首先调用的是 RCC 里面的 APB2 外设时钟控制函数,我们复制粘贴到这里。然后右键跳转到定义,我们需要点亮 PA0 口的 LED,所以选择 RCC APB2 外设 GPIOA 这一项

放到第一个参数,然后继续。第二个参数选择一 label 放到第二个参数,这样时钟就开启了。

接着调用 GPIO_ Init 函数,跳转定义,第一个参数选择 GPIOA

第二个参数是一个结构体哈,我们先把结构体类型复制下来,在 GPIO_ Init 上面粘贴,起个名字叫 GPIO_ Init_ Structure。 这里这个结构体实际上也是一种局部变量啊。在有些老的编译器,它要求所有的局部变量定义必须放到函数的最前面啊。如果你的编译器是这样的话,就需要把这一行提到最前面去。那我这个编译器是支持在函数中间定义变量的,所以就放在这个位置。接着我们复制结构体名字,用点把结构体的成员都引出来。

然后还是一个套路,右键跳转看一下说明,复制粘贴下参数。这样看上去库函数还是很简单的是吧?基本上都是复制粘贴复制粘贴,这就印证了程序员的最高境界, Ctrl C、 Ctrl V 走天下对吧?那我们选择这个 GPIOMode_TypeDef, Ctrl F 搜索一下。然后这里就是 GPIO 的 8 种工作模式。

AIN 是模拟输入, In floating 是浮空输入, IPD 是下拉输入, IPU 是上拉输入, out_OD 是开漏输出, out_PP 是推挽输出, AF_OD 是复用开漏, AF_PP 是复用推挽。那我们点灯用的是推挽输出,所以复制 out_PP 这一项,粘贴到 GPIO mode 的这里来。

接下来 GPIO pin 选择引脚,我们继续右键跳转,这里 GPIO 有多个定义。我们选择 Member 这一项,然后选中这个


选中Ctrl F。 这里因为我们用的是 GPIOA 外设的 0 号引脚,所以选择 GPIO_ Pin0 放在这里。

接着第三个还是一样的套路啊。输出速度选择 50 兆赫兹就行了。

最后把 GPIO 初始化结构体的地址放到 GPIO_ Init 的第二个参数,这样初始化就完成了。当这个 GPIO_ Init 函数执行完,这个 GPIOA 外设的 0 号引脚就自动被配置为推挽输出 50 兆赫兹的速度了。它内部的主要执行逻辑就是读取结构体的参数啊,执行一堆判断和运算啊,最后写入到 GPIO 配置寄存器。再那到现在 GPIO 初始化就已经完成了

我们接下来就可以使用 GPIO 的这些输入输出函数了。本小节先介绍这四个 GPIO 的输出函数。

这四个 GPIO 的输出函数。
第一个 GPIO Set bits, 第一个参数是 GPIOX(第一个参数:GPIOA 你要操作哪一组 GPIO), 第二个参数是 GPIO pin(你要操作这一组里的 哪一个引脚)。 这个函数可以把指定的端口设置为高电平。
第二个 GPIO Reset bits, 参数和上面的一样啊。这个可以把指定的端口设置为低电平。
第三个 GPIO Write bit, 这个函数有三个参数,前两个也是指定端口的,第三个是 bit value。 这个是根据第三个参数的值来设置指定的端口(输出 高电平 还是 低电平)。
第四个是 GPIO Write, 第一个参数是 GPIOX,选择外设。第二个参数是 port value。 这个函数可以同时对 16 个端口进行写入操作啊。
那我们分别来用一下试试,首先试一下Reset bits。 可以看一下函数说明啊。第一个是 GPIOX, X 可以是 A 到 G。 第二个是要写入的 GPIOX, X 可以是 0~15。那我们就写入 GPIOA, GPIO 0。这样就行了。

这个函数可以把指定的端口设置为低电平:


这个函数可以把指定的端口设置为高电平:


Write bit, 这个函数有三个参数,前两个也是指定端口的,第三个是 bit value。 这个是根据第三个参数的值来设置写入的数据值:输出 高电平 还是 低电平
Bit_RESET → 输出 低电平(0V) → LED 亮
Bit_SET → 输出 高电平(3.3V) → LED 灭


实现LED闪烁:
用到了延时函数:

在项目中新建文件夹复制过来:







led就开始闪烁了:


想写1或0:



在推挽模式下高低电平,都有驱动能力



说明开漏输出模式,高电平没有驱动能力

更换位置:

推挽输出高低电平均有驱动能力。开漏输出高电平相当于高阻态,没有驱动能力,低电平有驱动能力啊。一般输出用推挽模式就行了,特殊的地方才会用到开漏模式。
LED流水灯:




第一句打开 GPIOA 的时钟,因为我们连接的都是 GPIOA 的端口,所以第一句不用变的。
接着初始化端口的这一部分,这里只初始化了 GPIO的 0 号端口,我们流水灯用的是 GPIO 的 0~7 号端口,所以这里要加。那怎么加呢?在这里我们可以直接在 GPIOB pin 0 后面加上或。 GPIO pin 一,再加上或 GPIOpin 二。这样就可以一次性把三个端口都初始化。为什么可以这样来使用呢?我们转到定义看一下。这里可以看到, pin 零对应的数据是 0X0001,然后 pin 一, pin 二, pin 三依次为 0X0002, 0X0004, 0X0008。

如果把这个十六进制换成二进制的话,就是 0000000000000001,
然后是 0010。
0100
1000。
在这里每个端口对应一个位啊。如果把它们进行按位或的操作,比如 P0 P1 和 P2 按位或,那结果就是 0111。
这样就相当于同时选中了三个端口,这就是按位或的操作逻辑。最后我们还可以看到,这里有个 GPIOPinAll, 它对应的数据就是 0X F F F F, 也就是所有位都为一,这样就相当于选中了所有的引脚。
在这里除了这个 GPIOPin 可以用按位或的操作方式外,这个时钟控制的这一项也是可以用按位或的操作方式来选择多个外设的。

你看它这里的定义也是一样的,数据的规律是每一位对应一个外设。

还有这个 GPIOSetBit 这里也可以用按位或选择多个引脚,这样就能同时设置多个引脚了。所以这个函数名字也多了个 s,叫 SetBit。

SetBit 也是一个意思。在这个函数介绍里也写了,这个参数可以是 GPIOPinX 的任意组合。说的就是这个方式啊。那
介绍完按位或的这种操作方式,我们就可以在这里使用按位或把这 8 个引脚都选上了。当然这里我就直接写 GPIOPin2All了,这样就把 16 个端口全部配置为了推挽输出模式。然后是主循环里面,我们先把这些删掉。
GPIO_Write:第一个参数是 GPIOX,选择外设。第二个参数是 port value。 这个函数可以同时对 16 个端口进行写入操作

依次点亮:



蜂鸣器:


VCC接到正极供电孔, GND 负极接到负极供电孔。然后 I / O 控制级就随便选择一个 I / O 口接上就行了。这里我选择的是 PB12 号口。那大家注意一下哈,这个 A15、 B3、 B4 这三个口大家先别选。

我们从引脚定义图可以看到,这三个口默认是 JTAG 的调试端口。如果要用作普通端口的话,还需要再进行一些配置。

我们给PB12输出低电平,蜂鸣器就会向,输出高电平,蜂鸣器就不向
首先是时钟,因为我们用的是 PB 口,所以这里改为 GPIO_ B。 然后是端口, PB 12 号,所以这里是 Pin 12。端口模式仍然是推挽输出,速度 50 兆。初始化这里也应该是对 GPIO_ B 的初始化。到这里我们的 PB 12 号口就已经初始化好了。然后是输出,我们把这些先删掉啊。这两个地方都改为 B12,这就完成了,我们看一下,编译。

这样蜂鸣器就向了
可以自己设置响停时间
