❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。⭐️ 专栏主要内容: 主要学习STM32单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。
专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
专栏主页:http://t.csdn.cn/HCD8v
本学习过程参考:https://space.bilibili.com/383400717
STM3单片机安装软件、各种资料以及源码的路径:
链接:https://pan.baidu.com/s/1snD0uuTfMhchFqOMWvAiHA?pwd=asdf#list/path=%2F
提取码:asdf
链接里压缩包的解压密码:32
本大节主要学习GPIO通用输入输出口,包含两部分,第一小节主要学习GPIO的输出,第二小节是写三个简单的程序进行练习,分别是LED闪烁、LED流水灯、蜂鸣器等;第三小节是学习GPIO输入,第四小节是写两个简单的程序进行练习,分别是按键控制LED和光敏传感器控制蜂鸣器;
本小节主要学习GPIO的基础知识、GPIO的输出、以及STM32外部设备和电路;
GPIO的引脚电平是0V~3.3V;数据0就是低电平,也就是0V,数据1就是高电平,也就是3.3V;部分引脚可容忍5V,容忍5V的意思是可以在这个端口输入5V的电压,也认为是高电平;但是对于输出而言,最大就只能输出3.3V,因为供电就只有3.3V;具体哪些端口可以容忍5.5V,可以参考一下STM32的引脚定义;如下图所示:
带FT的就是可以容忍5V的,不带FT的,就只能介入3.3V的电压;
关于第四条,我们此节要演示的现象,比如LED和蜂鸣器,就使用到了GPIO的输出模式,另外在其他场景,只要是可以用高低电平来进行控制的地方,都可以用GPIO来完成;如果是控制的功率比较大的设备,只需要再加入驱动电路即可;除此之外,我们可以用GPIO来模拟通讯协议,比如I2C、SPI或者某个芯片特定的协议,我们都可以用GPIO的输出模式来模拟其中的输出时序部分;
关于第五条,输入模式最常见的就是读取按键了;用来捕获我们的按键按下事件,另外也可以读取带有数字输出的一些模块;比如我们套件里的光敏电阻模块、热敏电阻模块等;如果这个模块输出的是模拟量,那GPIO还可以配置成模拟输入的模式,再配合内部的ADC外设,就能直接读取端口的模拟电压了;除此之外,模拟通信协议时,接受数据通信上的数据,也是靠GPIO的输入来完成的;
上图是GPIO的整体构造,左边是APB2外设总线,其在STM32系统结构图的位置如下图所示:
在STM32中,所有的GPIO都是挂载在APB2外设总线上的,其中GPIO外设的名称是按照GPIOA、GPIOB、GPIOC等等这种方式来命名的;每个GPIO外设,总共有16个引脚,编号是0~15;例如GPIOA的第0个引脚,我们称它为PA0,GPIOA的第1个引脚称为PA1,以此列推,一直到PA15;
在每个GPIO模块内,主要包含了寄存器和驱动器这些东西;寄存器就是一段特殊的存储器,内核可以通过APB2总线对寄存器进行读写,这样就可以完成输出电平和读取电平的功能了;寄存器的每一位对应着一个引脚,其中输出起存器写1,对应的引脚就会输出高电平,写0,就输出低电平;输入寄存器读取1,就证明对应的端口目前是高电平,读取0,就是低电平;
因为STM32是32位的单片机,所以STM32内部的寄存器都是32位的,但是这个端口只有16位,所以这个寄存器只有低16位对应有端口 ,高16位是没有用到的;
在GPIO基本结构图中,驱动器是用来增加信号的驱动能力的,寄存器只负责存储数据,如果要进行点灯这样的操作的话,还是需要驱动器来负责增大驱动能力;
以上这些就是GPIO的整体基本结构了。
下面来看一下GPIO中每一位的具体电路结构,上图就是STM32参考手册中的GPIO位结构的电路图了;左边三个是寄存器,中间部分是驱动器,最右边就是某一个IO口的引脚了;
整体结构可以分为两部分,上面是输入部分,下面是输出部分。
在输部分,首先是这个IO引脚,可以看到IO口上下都结了两个保护二极管,这是对输入电压进行限幅的,上面这个二极管接VDD,3.3V,下面接VSS,0V;如果输入电压比3.3V还要高,那上方的这个二极管就会导通,输入电压产生的电流就会直接流入Vdd而不会流入内部电路,如下图:
同样的,如果输入电压比0V还要低,这个电压是相对于VSS的电压,所以是可以有负电压的,那这时下方这个二极管就会导通,电流会从VSS直接出去,也是可以保护内部电路的,如下图所示:
如果输入电压在0~3.3V之间,那两个二极管均不会导通,这时二极管对电路没有影响,这就是保护二极管的用途;
接下来如果是正常电压,电流的流向如下图所示:
这里连接了一个上拉电阻和一个下拉电阻,上拉电阻是VDD,下拉电阻是VSS,这个开关是可以通过程序进行配置的;如果上面导通,下面断开,就是上拉输入模式;如果下面导通,上面断开,就是下拉输入模式;如果两个都断开,就是浮空输入模式;
上拉和下拉的作用是为了给输入提供一个默认的输入电平的,因为对应一个数字的端口,输入不是高电平就是低电平,如果输入引脚什么都不接,那到底算是高电平还是低电平呢?所以实际情况是,如果输入啥都不接,这时输入就处于一种浮空的状态,引脚的输入电平极易受到外界干扰而改变,就像是一个物体悬浮在太空一样,它的位置是不确定的,受到一点扰动就会变化;为了避免引脚悬空导致的输入数据不确定,我们就需要在这里加上上拉或者下拉电阻了;
如果接入上拉电阻,当引脚悬空时,还有上拉电阻来保证引脚是高电平,所以上拉输入又可以称为是默认为高电平的输入模式,如下图所示:
下拉也是同理,就是默认为低电平的输入方式;
再往后是TTL肖特基触发器,其实英文文档里写的是施密特触发器,所以这里写肖特基触发器其实是一个翻译错误;这个施密特触发器的作用就是对输入电压进行整形的,它的执行逻辑是,如果输入电压大于某一阈值,输出就会瞬间升为高电平;如果输入电压小于某一阈值,输出就会瞬间降为低电平;能够抗干扰;
接下来经过施密特触发器整形的波形就可以直接写入输入数据寄存器了,如上图,我们再用程序读取输入数据寄存器对应的某一位的数据,就可以知道端口的输入电平了;
最后上面还有两路线路,这些就是链接到片上外设的一些端口,其中有模拟输入,这个是连接到ADC上的,因为ADC需要接受模拟量,所以这根线是接到施密特触发器前面的;另一个是复用功能输入,这个连接到其他需要读取端口的外设上的,比如串口的输入引脚等,这根线接收的是数字量,所以在施密特触发器的后面;
输出部分可以由输出数据寄存器或片上外设控制,两种控制方式通过这个数据选择器接到了输出控制部分,如上图所示,如果选择输出数据寄存器进行控制,就是普通的IO口输出,写这个数据寄存器的某一位就可以操作对应的某个端口了;
左边还有个叫做位设置/清除寄存器,这个可以用来单独操作输出数据寄存器的某一位,而不影响其他位,因为这个输出寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以如果想单独控制某一个端口而不影响其他端口的话,就需要一些特殊的操作方式,第一种方式是先读出这个寄存器,然后用按位与和按位或的方式更改某一位,最后再将更改后的数据写回去,在C语言中就是&=
和|=
操作;这种方法比较麻烦,效率并不高,对于IO口的操作而言不太适合;第二种方式是通过设置这个位设置和位清除寄存器,如果我们要对某一位进行置1的操作,在位设置寄存器的对应位写1即可,剩下的不需要操作的位写0,这样它内部就会有电路,自动将输出数据寄存器中对应位置为1,而剩下的写0的位则保持不变;这样就保证了只操作其中某一位而不影响其他位,并且这是一步到位的操作; 如果想对某一位进行清零的操作,就在位清除寄存器的对应位写1即可,这样内部电路就会把这一位清0了; 这就是第二种方式也就是这个位设置和位清除寄存器的作用;另外还有第三种方式,那就是读写STM32中的“位带”区域,不再详细讲述;
输出控制之后就接到了两个MOS管,上面是P-MOS,下面是N-MOS,这个MOS管就是一种电子开关,我们的信号来控制开关的到同和关闭,开关负责将IO口接到VDD或者VSS;在这里可以选择推挽、开漏或关闭三种方式;
这些就是GPIO位结构的全部介绍了。
以上是GPIO的8中工作模式,通过GPIO端口配置寄存器,上一小节介绍的位结构电路就会根据我们的配置进行改变,比如开关的通断、N-MOS和P-MOS是否有效、数据选择器的选择等;这个端口的电路就可以配置成上图中的8种模式。
在使用浮空输入时,端口一定要接上一个连续的驱动源,不能出现悬空的状态;
浮空输入、上拉输入、下拉输入的电路图如下图所示:
模拟输入的电路图如下图所示:
其他地方都断开,只有模拟输入这一条路有用;所以当我们使用ADC的时候,将引脚配置位模拟输入就行了;其他时候一般用不到模拟输入;
开漏输入和推挽输入的电路结构如下图所示:
左边两个图是使用STM32的GPIO口驱动LED的电路,
在单片机中,一般倾向于使用第一种接法;
左边两个图是使用STM32的GPIO口驱动蜂鸣器的电路,使用了三极管开关的驱动方案,三极管开关是最简单的驱动电路了,对于功率稍微大一点的,直接使用IO口驱动会导致STM32负担过重,这时就可以用一个三极管驱动电路来完成驱动的任务
最后介绍一下面包板的使用方法,左边上面的图是面包板的正面,左边下面的图是面包板的背面;右边是面包板内部金属爪的示意图,当我们把原件的引脚插到面包板的孔里后,它内部的金属爪就会夹住引脚;在面包板中,竖着的一列是连载一起的,这样当我们原件插在一纵排的不同空位时,内部的金属爪就实现了线路的链接;而上下四排孔整体是连在一起的,这四排是用于供电的;