左左右学堂 · 课程目录

第04期 一节课讲明白GPIO口

观看B站原视频 · 文稿与高清画面

hello,小伙伴们,大家好。这里是左左右。今天通过这节课的学习让大家学明白什么是GPIO口。通过上一节课的学习,大家对GPIO应该有了一定的了解。GPIO就是通用输入输出口。

下面我们打开STM32中文手册的第106页。这张图就是IO口的基本结构图。没有的小伙伴可以关注我的个人公众号领取。这里我们把这张图单独拿出来。这里的IO引脚就是我们单片机上一根根银色的金属条。其余部分指的就是我们stm32单片机的芯片内部了。这里的VDD和VSS分别代表3.3V和0V。

当我们的输入电压大于3.3V时,电流就会从VDD流出。当我们的输入电压是负压,小于0V时,电流就会沿着VSS从IO引脚流出。所以,只有输入电压在0V和3.3V之间。我们的电流才会流入芯片内部。对我们的芯片起到一个保护的作用。既然是IO口,那么它肯定包含输入和输出两种模式。

大家已经听过上节课的讲解。那么,我就从大家熟悉的输出模式开始讲起吧。输出模式由输出驱动器和输出寄存器两部分构成。我们先讲(输出驱动器)。这里我们将P-MOS和N-MOS可以理解为两个开关。当P-MOS闭合时,从VDD通过IO引脚向外输出3.3V的高电平。当N-MOS闭合时,从VSS通过IO引脚向外输出0V的低电平。

当在推挽输出模式下,我们对P-MOS和N-MOS的开合有绝对的控制权。就是说IO口是输出3.3V的高电平 还是0V的低电平。完全是由我们说了算的,在开漏模式下P-MOS相当于彻底断开了,我们只能从VSS通过IO引脚向外输出0V的低电平。这种模式下是有特殊用途的,留个悬念,我们在后面的课程揭晓。

视频画面 02:15.6
视频画面 02:15.6 · 1080P 原图 · 查看对应视频

那么P-MOS和N-MOS的开合是靠什么来控制的呢?就是前面的输出寄存器。这里假设我们的需求是将PA5输出3.3V的高电平。要想输出3.3V的高电平。我们必须首先把输出模式设置为推挽模式。由于我们的STM32单片机是32位的,而不管是PA还是PB引脚都只有16个。所以,我们将输出寄存器的后16位保留。

前16位和我们的PA引脚一一对应,这时通过编写程序控制位设置寄存器。来改变输出数据寄存器中PA5对应的值。通过输出控制将PA5对应的P-MOS管闭合。电流沿VDD从PA5对应的IO口输出3.3V高电平。我们可以把输出模式分为4种。当走上面这条路时分为推挽输出和开漏输出两种模式,当走下面这条路时分为复用推挽输出和复用开漏输出,一共加起来就是4种模式。

下面我们接着讲输入模式。他和输出模式一样。也是包括输入驱动器和输入寄存器这两大块。在输入驱动器这里我们可以看到两个开关。当上面这个开关闭合时 此时默认输入高电平 称为上拉输入模式,当下面这个开关闭合时 此时默认输入低电平 称为下拉输入模式,那这里的这个斯密特触发器起到一个什么作用呢?

视频画面 04:19.3
视频画面 04:19.3 · 1080P 原图 · 查看对应视频

外部电压输入时难免会有波动。这时斯密特触发器设置了一高一低两个阈值电压。当输入电压高于高的那个阈值电压时 输入高电平,当输入电压低于低的那个阈值电压时 输入低电平,经过斯密特触发器形成一个稳定的方波信号。当上下两个开关都处于打开状态时 输入电压不确定 称为浮空输入,当电路处浮空输入模式下,输入电压极易受到外部线路的干扰。

前面讲到的上拉和下拉模式都属于弱上拉和弱下拉。这是因为在VSS和VDD上都串联了一个阻值很大的电阻。在模拟输入模式下,VDD、VSS和施密特触发器的这三个开关都处于失效状态。电流从IO引脚直接到片上外设。由于模拟输入我们需要的到的真实的输入电压值,如果经过斯密特触发器,IO口的输入电压值就失真了。

模拟输入的使用情况。我也会在后面的课程中为大家一一讲解的。通过刚才的学习我们不难得出。输入模式分为上拉、下拉、浮空、模拟四种模式。好了 我们趁热打铁开始今天的案例。

首先,我们打开STM32cubeide这款软件。点击收藏。找到我们上节课收藏好的stm32。点击next。这里我们新建一个项目。并给他命名。第一步我们仍然是点击SYS。选择Debug模式为 serial wire。这时我们设置PA15引脚为GPIO_output。这时我们设置默认输出低电平。

输出模式选择为推挽输出。我们点击保存。这时代码就自动生成了。我们找到main.c的文件。这里的main函数,就是我们程序执行的入口,也就是我们程序开始的地方。

下面是一些初识化的函数。下面我们按下ctrl按键用鼠标点击GPIO_init这个函数。我们就跳转到定义这个函数的地方了。这个函数里的代码是和我们前面的设置是一一对应的。我们在前面设置好了 代码就自动生成了。是不是很方便?

好的 我们回到主函数。这里我们看到一些绿色的注释。

/* 和 */之间的代码是不执行的  起到一个解释代码的作用

方便自己或者其他人维护代码时。一眼就能看出这段代码的作用。接着,我们可以看到,user code begin和user code end两行注释。我们自己写的代码必须放到这两行注释之间。否则在自动生成代码时。不在这两行注释之间的代码会被删掉。

视频画面 06:22.9
视频画面 06:22.9 · 1080P 原图 · 查看对应视频

那么,我们的程序就白写了。上节课我们讲到想要把学习板上的小灯点亮。只需要设置PA15引脚为低电平就可以了。那么,我们看代码是怎么实现的?前面我们刚讲HAL_GPIO_WritePin这个函数时。就是设置PA15引脚为低电平。我们将他复制下来,将他放到WHILE(1)的大括号里。

视频画面 09:48.9
视频画面 09:48.9 · 1080P 原图 · 查看对应视频
视频画面 11:11.4
视频画面 11:11.4 · 1080P 原图 · 查看对应视频

这时我的小灯就被点亮。下面我们给他一个延时,让小灯亮一会。我们输入HAL_DEL。然后,同时按下键盘上的ALT键和/。我们的代码就被自动补全了。这里我们输入500ms也就是0.5秒。还有每行代码后的分号是必不可少的,那么,我们如何实现小灯的熄灭呢?我们还是打开LED小灯的电路原理图。

这时我们将PA15引脚输出3.3V的高电平。小灯两边没有电压差。是不是小灯就熄灭了?前面我讲过 只有在推挽输出模式下。我们对GPIO输出低电平还是高电平才有绝对的控制权。这就是我们前面为什么要把PA15设置为推挽输出的原因?好了,我们接着复制上面这行代码,将RESET改为SET就实现了将PA15输出高电平。

然后,我们接着给一个500ms的延时。还有这个while(1)代表什么呢?它代表下面这个大括号里的代码由第一行开始执行到最后一行。然后,再从第一行开始执行到最后一行。反复无限循环。以我们这段代码为例。第一行执行将PA15设置为低电平,小灯被点亮。第二行等待500ms。第三行执行将PA15设置为高电平,小灯熄灭。

第四行等待500ms。接着,在重新执行第一行代码。这样就是实现了LED小灯亮0.5秒灭0.5秒的效果。小灯就会这样一闪一闪的无限循环下去。好了,拿出我们的学习板和电脑连接。手里之前买过最小系统板的小伙伴们可以按这个图接线。接着,我们点击运行就能实现视频开始LED小灯闪烁的效果了。

可能最近大家也发现我更新的速度并没有之前那么快了。一方面是因为自己制作一期视频用时很长。需要写稿。写稿的目的是以尽量精简语言来提高大家学习的效率。再加上制作动画、添加字幕。一期十几分钟的视频制作时间都在十个小时以上。由于白天还有自己的本职工作要做,每天晚上都会抽出两三个小时去做视频。

另一方面是因为之前发布的视频。播放量和互动量都没有预想的那么好。所以,我把更多的时间投入到了的视频的打磨上。值得欣慰的是最近没有更新的日子里。视频的播放量和关注还是在慢慢上涨的,我始终坚信 好的视频迟早都会得到大家的认可。好了 今天的视频就到这里了。制作不易。您的关注、收藏和点赞是我更新下去的最大动力。

下集我们讲一下C语音的基础。下集见。