摘要:本文介绍了STM32芯片GPIO的功能和原理,HAL库 GPIO函数,以及CubeMX工具的使用;
0. 写在前面
以下内容皆是基于笔者的嵌入式小白理解,部分语句并不够严谨,更多是为了自己和小白能够理解,如有错误敬请指正。
部分软件的使用教程省略。
1. GPIO基本原理
GPIO是STM32的基础功能,能够进行引脚高/低电平是输入输出,通俗来说,就是可以通过编写程序来控制某个引脚是低电平还是高电平(此时引脚的电平控制权在芯片);或者能够检测外部输入的信号的高电平还是低电平(此时引脚的电平控制权在外设)。
例如,如果GPIO是输出模式,那么引脚接LED灯的正极,LED灯的负极接GND(电路中的地线,也就是电路图中的电源负极,电压为0V),如果给出指令,让GPIO输出高电平(即置位),那么灯泡就会亮;反之让GPIO输出低电平(即复位),那么灯泡就会熄灭。
1.1 GPIO输出模式
GPIO共有两种输出模式:推挽输出和开漏输出。
1.1.1 推挽输出
推挽(Push-Pull)输出原理如下图。输出值Q由内部总线传递,通过D触发器输出 非Q,然后连接两个MOS管。PMOS管连接高电平,NMOS连接低电平。Q=0时,非Q=1,NMOS导通,IO输出低电平;反之,Q=1时,非Q=0,PMOS导通,输出高电平。
就是能推(Push)能拉(Pull)的意思。
1.1.2 开漏输出
开漏(Open-Drain)输出原理如下图。和推挽输出的区别在于PMOS管没了,当Q=0时能够将电平拉低,但是Q=1时不能拉高电平,只能输出高阻态。此时可以通过上拉电阻接到所需要的高电平(3.3V~5V)。
另外,开漏输出有“线与”的特点,多个开漏输出电路连在一起时,一个电路输出低电平,所有电路都会被拉低。
1.2 GPIO输入模式
输入模式主要分为三种:上拉输入和下拉输入还有浮空输入。
原理如图所示,实际上就是通过一个上拉电阻和一个下拉电阻来控制没有输入时的电平状态。顾名思义,上拉输入就是接入上拉电阻,没有输入时为高电平,当输入低电平时,电路电平被拉低;下拉输入相反,接入下拉电阻,没有输入时为低电平,输入高电平时电路电平被拉高;浮空输入则是上拉/下拉电阻都不接,电路电平完全取决于输入电平。
例如下面三个开关,如果将这三个开关用于GPIO输入的话,PA0可以设置为浮空或者下拉输入,当按键被按下时,输入高电平。PB2~PB4可以设置为浮空或者上拉输入,当按键被按下时,输入低电平。
整个GPIO模块的原理图如下。
2. 使用GPIO工程
以STM32C8T6为例。要实现的功能是:配置两个GPIO口,一个输入一个输出,输入检测按键是否被按下和弹开,输出给LED供电,以实现按钮开关LED灯。
2.1 新建CubeMX工程
CubeMx的功能是为STM32软件生成代码模板,能够在软件编辑好引脚配置,然后自动生成这些引脚的初始化代码,可以在代码模板中编写用户软件逻辑。
File - New Project - 搜索F103C8T6 - 选择芯片。
主界面如图所示。
然后配置GPIO口。
工程配置,Project选项栏中选择项目的保存地址和名称,笔者用的是MDK-ARM,用Keil软件编写C语言代码。
Code Generator选项栏中可以选择生成C语言头文件。
全部完成后点击右上角的GENERATE CODE,即可生成代码模板。
2.2 使用Keil uVision5编写代码
如图,打开刚才生成的代码,能看到左侧的工程文件目录,生成的文件中含有USER BEGIN
和USER END
字样的注释,在二者之间编写的用户代码在重新生成代码后不会被删除。
这里在main.c
文件中编写业务逻辑,在while(1)
循环中。
最后烧录到开发板上,验证结果。
参考:
- 关于地线: 笔记:电子设备接地,接的到底是什么地?
写在后面
笔者并不是一个勤快的人。目前工作内容主要是嵌入式开发,会经常和部门的硬件同事打交道,但是笔者目前所有的知识只有本科计算机,由于没有微电子硬件相关的基础,所以对于工作过程中的一些电性问题基本处理不了,直到现在工作了五个多月,也就会用个万用表读读电压,然后看看板子的原理图,剩下的就只能求助同事了。
下午打算学一点东西。今年计划考一次研试一试的,但是英语看了一会儿,实在背不下去,数学和专业课也还没复习。我不知道要从哪里开始学起,感觉要学的东西太多了,不管是考研还是工作,我现在都还没有一个明确的学习计划,就这样拖到了下午四点半。在工作之后,个人时间几乎都是靠游戏过去的,像是逃避焦虑一样不去想学习的事情,一旦想起来就会重新陷入深深的焦虑中。
于是抱着这样的心情写了这篇博客,至少解决工作上的问题对我现在而言是有益的,目前我对于STM32的开发还处于只会套库,原理一窍不通的阶段,所以我会尝试记录遇到的所有问题并弄清楚原理,发表于博客上。如果能坚持下来的话,我相信即使是我这样的人,也能有所进步的。
数学公式搞起来麻烦,下次。
电子电路相关的知识,如MOS管、上拉/下拉电阻之类的知识,以后应该会写一些系统一点的博客吧,作学习整理之用。
以上。