0301STM32GPIO外设输出功能


GPIO的输出 输入
库函数里用了大量的结构体、指针、枚举等知识。C语言中高级部分
LED闪烁、LED流水灯、蜂鸣器滴滴鸣响

STM32内部的GPIO外设

GPIO简介

GPIO(General Purpose Input Output)通用输入输出口
可配置为8种输入输出模式
引脚电平:0V~3.3V,部分引脚可容忍5V(可以输入5V,但是输出只有3.3V,因为供电只有3.3V)FT(Five Tolerate)
输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序(IIC、SPI、芯片的特性协议)等
输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

基本结构

在这里插入图片描述
GPIO外设的名称按照GPIOA、GPIOB、GPIOC等命令的
每个GPIO外设有16个引脚,编号从0-15。GPIOA的第0号引脚,一般成为PA0,第15号为PA15
每个GPIO模块内,主要包含了寄存器和驱动器这些
寄存器(一段特殊的存储器),内核可以通过APB2总线对寄存器进行读写,来完成输出电平和读取电平的功能。
寄存器的每一位对应一个引脚,其中输出寄存器写1,对应的引脚就会输出高电平,写0就输出低电平
输入寄存器读取为1,就证明对应的端口目前是高电平,读取为0,就是低电平
所有寄存器都是32位的,但是端口只有16位,所以寄存器只有低16位对应有端口,高16位没有用到
驱动器用来增加信号的驱动能力。寄存器只负责存储数据,如果要进行点灯操作,还是需要驱动器来负责增大驱动能力

GPIO位结构

在这里插入图片描述

左边三个是寄存器,中间部分是驱动器,右边是IO引脚

整体结构分为两部分:上面是输入部分,下面是输出部分

输入部分:

IO引脚,接了两个保护二极管,对输入电压进行限幅的。如果输入电压>VDD ,那么上面的二极管就会导通,输入电压产生的电流就会直接流入VDD而不会流入内部电路,可以避免过高的电压对内部的电路产生伤害。如果输入电压<VSS,下方二极管导通,电流从VSS流出去,而不会从内部电路汲取电流,可以保护内部电路。如果输入电压在VSS到VDD之间,两个二极管均不导通,这时二极管对电路没有影响,这是保护二极管的作用。

上拉电阻至VDD,下拉电阻至VSS。开关可以通过程序配置。
上面导通,下面断开,上拉输入模式(默认为高电平的输入方式)
下面导通,上面断开,下拉输入模式(默认为低电平的输入方式)
两个都断开,浮空输入模式。
上拉下拉式为了给输入提供一个默认的输入电平的。因为对于数字端口,输入不是高电平就是低电平,如果浮空的话引脚的输入电平极易受外接干扰而改变,为了避免输出不确定,所以要确定下来用上拉电阻或者下拉电阻。上下拉电阻阻值都比较大,是一种弱上拉和弱下拉,目的是尽量不影响正常的输入操作。

图中的肖特基触发器,应该为施密特触发器才对(翻译错误)(对输入电压进行整形)(类似迟滞比较器),经过施密特触发器整形的波形就可以直接写入数据寄存器了。再用程序读取输入数据寄存器对应的某一位数据,就可以指导端口的输入电平了

模拟输入和复用功能输入就是连接到片上外设的一些端口,其中有模拟输入(连接到ADC上的,因为ADC接收模拟量,所以在施密特触发器之前)。复用功能输入是连接到其他需要读取端口的外设上的,比如串口的输入引脚,这根线接收的是数字量,所以在施密特触发器后面

输出部分:

数字部分可以由输出数据寄存器或片上外设控制,两种方式通过数据选择器接到了输出控制部分。如果通过输出数据寄存器进行控制,就是普通的IO口输出,写这个数据寄存器的某一位就可以操作对应的某个端口了
位设置/清除寄存器,可以用来单独操作输出数据寄存器的某一位,而不影响其他位,因为输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以只想单独控制某一个端口而不影响其他端口的话,就需要一些特殊的操作方式
第一种方式是先读出这个寄存器,然后用按位与和按位或的方式更改某一位,最后再将更改后的数据写回去,在C语言中就是&=和|=操作,比较麻烦,效率不到,对于IO口的操作而言不太合适
第二种方式是设置这个位设置/清除寄存器,如果对某一位置1,在位设置寄存器的对应位写1即可,剩下不需要操作的位写0。内部有电路,自动将输出数据寄存器中的对应位置位1,而剩下的写0的位则保持不变。保证了只操作其中某一位而不影响其他位,并且是一步到位的操作。
如果相对某一位清0,就在位清除寄存器的对应位写1即可,内部有电路,自动将输出数据寄存器中的对应位置位0

第三种方式是读取STM32中的“位带”区域,这个“位带”作用和51单片机的位寻址作用差不多,在STM32中,专门分配的有一段地址区域,这段地址映射了ARM和外设寄存器所有的位,读写这段地址中的数据,就相当于读写所映射位置的某一位。

目前暂不会用到。库函数方法操作是读写位设置和位清除寄存器的方法

输出控制之后接到两个MOS管,推挽、开漏和关闭三种方式
推挽输出在高低电平均有较强的驱动能力,所以推挽输出模式也叫强推输出模式
开漏输出模式,数据寄存器为1时,输出相当于断开,也就是高阻模式,只有低电平有驱动能力。可以作为通信协议的驱动方式,比如IIC,多机通信时可以避免各个设备的相互干扰。还可以用于输出5V的电平信号(用于兼容5V的设备)
关闭。引脚配置成输入模式时,两个MOS管都无效,输出关闭,端口的电平由外部信号来控制

GPIO位结构的全部介绍

GPIO八种工作模式

通过配置GPIO的端口配置寄存器,位结构的电路就会根据配置进行改变(比如开关的通断,NMOS和PMOS是否有效,数据选择器的选择等),端口可以配置成以下8种模式
在这里插入图片描述

浮空/上拉/下拉输入

浮空输入时,端口一定要接上一个连续的驱动源,不能出现悬空的状态。
在这里插入图片描述
输入模式下,输出驱动器是断开的。端口只能输入不能输出,
VDD或VDD_FT是3.3V端口和容忍5V端口的区别。特殊不同在哪手册没有说,我们也不用管,就知道就行了。上面的保护二极管需要做一下处理,要不然直接接VDD3.3V的话,外部接入5V电压就会导致上边二极管开启,并且产生较大电流,这是不太妥当的。

模拟输入

在这里插入图片描述
从引脚直接接到片上外设ADC,所以使用ADC时,将引脚配置成模拟输入就行了

开漏/推挽输出

在这里插入图片描述
在输出模式下,输入模式也是有效的。但是在输入模式下,输出都是无效的,这是因为一个端口只能有一个输出,但可以有多个输入,所以当配置成输出模式的时候,内部也可以顺便输入,这个没啥影响

复用开漏/推挽输出

在这里插入图片描述
这两个模式和普通的开漏输出和推挽输出差不多,只不过引脚电平由片上外设控制,引脚控制权有片上外设掌控。在输入部分,片上外设也可以读取引脚的电平,同时普通的输入也是有效的,顺便接受一下电平信号

8种模式中,除了模拟输入这个模式会关闭数字的输入功能,其他7个模式中所有的输入都是有效的

手册寄存器描述

English缩写

GPIO(General Purpose Input/Output,通用输入输出)
GPIOx_MODER:GPIO Port Mode Register
GPIOx_IDR:GPIO Port Input Data Register
GPIOx_ODR:GPIO Port Output Data Register
GPIOx_BSRR:GPIO Port Bit Set/Reset Register
GPIOx_LCKR:GPIO Port Configuration Lock Register
GPIOx_LCKR:GPIO Port Configuration Lock Register
GPIO_CRL(Control Register Low)
GPIO_CRH(Control Register High)
CNF(Configuration bits)

GPIO功能描述

可以看GPIO8种方式详情可以看手册,
在这里插入图片描述

外设的GPIO配置

使用片上外设的引脚时,可以参考手册里给的配置(外设的GPIO配置)
在这里插入图片描述

GPIO寄存器描述

GPIO配置寄存器,每个端口的模式由4位进行控制,16个端口需要64位,所以配置寄存器有2个,1个端口配置低寄存器,1个端口配置高寄存器
在这里插入图片描述

多出了GPIO输出的速度(可以限制输出引脚的最大翻转速度),这个设计出来是为了低功耗和稳定性的。一般要求不高时配置50MHz即可。

端口输入数据寄存器

里面的低16位对应16个引脚,高16位没有使用
在这里插入图片描述

端口输出数据寄存器

里面的低16位对应16个引脚,高16位没有使用
在这里插入图片描述

端口位设置/清除寄存器

高16位进行位清除,低16位进行位设置。写1进行设置或者清除,写0不产生影响
在这里插入图片描述

端口位清除寄存器

低16位和端口位设置/清除寄存器的高16位功能一样,为啥还需要这个寄存器,是为了方便操作设置的。如果只想单一地进行位设置或者位清除。位设置时,用上面的寄存器,位清除时,用下面的寄存器。因为设置和清除时,使用的都是低16位的数据,这样方便一些。如果想对多个端口同时进行位设置和位清除,那使用第一个寄存器就可以了,这样可以保证位设置和位清除的的同步性。
在这里插入图片描述

端口配置锁定寄存器

可以对端口的配置进行锁定,防止意外更改。
在这里插入图片描述

STM32外部的设备和电路

LED和蜂鸣器简介

在这里插入图片描述
没有剪过得LED实物,长脚是正极,短脚是负极。
LED内部也可以看正负极,较小的一般是正极,较大的一般是负极

硬件电路

在这里插入图片描述
LED灯的限流电阻一定要接。看IO口的高低电平的驱动能力如何来选取怎么接。一般选取第一种接法。很多单片机或者芯片,使用高电平弱驱动,低电平强驱动的规则。可以一定程度上避免高低电平打架。
三极管驱动电路。(更好的驱动电路和阻值选型可以看模电和数电部分)

面包板

在这里插入图片描述
面包板的正反面。
金属爪的排放规律:
竖着的5孔金属爪连接,上面两排和下面两排的金属爪是横着连接(还标了供电的红+ ,蓝-标识)(有的正中间横的可能断开)

keilkill.bat

批处理文件,可以把工程编译产生的中间文件都删掉,因为编译产生的文件比较大,主要占空间的就是Listing和Objects这两个文件夹,这些都是中间文件,如果要把工程分享给别人,可以双击一下这个批处理文件,会把中间文件都删掉

点亮一个LED灯3步

1.使用RCC开启GPIO的时钟
2.使用GPIO_Init函数初始化GPIO
3.使用输出或者输入的函数控制GPIO口

设计RCC和GPIO两个外设 可以先看下这两个外设都有哪些库函数

RCC外设

可以在Library中找到rcc.h文件,在.h文件的最下面,一般都是库函数所有函数的声明。
可以看到rRCC有很多函数,但是大部分函数我们都不会用到,最常用的只有只有这3个函数
在这里插入图片描述
在这里插入图片描述
以AHB为例:
brief 简介
param 参数
看简介描述它的功能,看参数如何选择。
如果不清楚哪个外设连接在哪一个总线上,还可以到arg这个列表里面找一下

GPIO外设

gpio.h的文件

在这里插入图片描述
需要了解的就是红框里的函数
1.GPIO_DeInit,参数可以写GPIOA、GPIOB等等,调用这个函数之后,所指定的GPIO外设就会被复位
2.GPIO_AFIODeInit,可以复位AFIO外设

3.GPIO_Init 非常重要,作用:用结构体的参数来初始化GPIO口,需要先定义一个结构体变量,然后再给结构体赋值,最后调用这个函数
这个函数内部会自动读取结构体的值,执行一堆判断和运算,写入到GPIO配置寄存器,然后自动把外设的各个参数配置好(操作细节就不需要关心了)。这种Init函数在STM32中基本所有的外设都有,一般初始化外设都使用Init函数来完成。
4.GPIO_StructInit,可以把结构体变量赋一个默认值,

接下来4个是GPIO的读取函数
再下面4个事GPIO的写入函数
这些函数可以实现读写GPIO口的功能,
剩下的函数暂时不会用到
重要的函数就是GPIO_Init和8个读写函数

闪烁小灯&流水灯&蜂鸣器实验

8种工作模式:

AIN (Analog IN) 模拟输入
IN_FLOATING 浮空输入
IPD (In Pull Down) 下拉输入
IPU (In Pull Up) 上拉输入
Out_OD (Out Open Drain)开漏输出
Out_PP (Out Push Pull) 推挽输出
AF_OD (Atl Open Drain) 复用开漏
AF_PP (Atl Push Pull) 复用推挽

GPIO的输入函数

GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 两个参数: GPIOx,GPIO_Pin 可以把指定的端口设置成高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); GPIOx,GPIO_Pin 指定引脚 可以把指定的端口设置成低电平
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); GPIOx,GPIO_Pin 根据第三个参数的值来设置指定的端口
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); GPIOx,可以同时对16个端口进行操作

Delay函数的说明

在这里插入图片描述
提供三个延迟函数,us延迟、ms延迟、s延迟

在这里插入图片描述
使用SysTick定时器来实现的延时,具体如何实现,可以先不用管,延时函数直接用,不用修改什么(是因为72Mhz的主频吗,待考究,要是换了芯片还能一样不?)

如果非要在函数里用0/1来表示
GPIO_WriteBit(GPIOA, GPIO_Pin_0, 0); 这样编译会出现警告,
在这里插入图片描述
枚举类型中混入了其他类型的变量
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);
如果还想写0或者1,就强制把0转化成BitAction类型

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2
可以用 | 的原因:
在这里插入图片描述
换成2进制就是
GPIO_0 0000 0000 0000 0001
GPIO_1 0000 0000 0000 0010
每个端口对应一个位,进行按位或 GPIO_0|GPIO_1时 0000 0000 0000 0011 相当于同时选中2个引脚

除了GPIO_Pin可以用按位或的操作方式外,时钟控制这一项,也可以按位或的操作方式来选择多个外设,输出的规律是每一位对应一个外设
在这里插入图片描述
在这里插入图片描述

GPIO_SetBits也可以用按位或选择多个引脚,这样就能同时设置多个引脚了,所以函数的名字也多了个s,脚SetBits
ResetBits 也是同样的可以选择多个引脚

GPIO_Write 两个参数: GPIOx,PortVal(指定写到输出数据寄存器的值)

在这里插入图片描述
C语言不支持直接写二进制,所以只能转换为16进制来写,分别对应0-15的引脚

在这里插入图片描述
在流水灯实验中,也可以定义一个数组,一次去除数组中的数据来进行花式点灯

蜂鸣器与流水灯实验类似,只是硬件连接电路不同而已

使用库函数的方法

1.先打开.h头文件,看一下都有哪些函数,一般在头文件的最后。然后右键转到定义,查看函数和参数的用法。要会看懂英文,或者工具辅助。

2.打开库函数用户手册,有所有函数的介绍和使用方法。都是中文,且有用例,调用可以直接复制。不过可能用户手册的版本不一定对应所用的库函数版本,会存在有些用法有出入,但是整体上差异不大

在这里插入图片描述

3.固件库里的帮助文档,是纯英文

在这里插入图片描述

4.别人的代码

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 20:52:02       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 20:52:02       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 20:52:02       57 阅读
  4. Python语言-面向对象

    2024-07-11 20:52:02       68 阅读

热门阅读

  1. Oracle 确认被锁对象

    2024-07-11 20:52:02       19 阅读
  2. 【思考Spring Security框架的相关问题】

    2024-07-11 20:52:02       24 阅读
  3. 在SpringBoot使用AOP防止接口重复提交

    2024-07-11 20:52:02       22 阅读
  4. Spring AOP的几种实现方式

    2024-07-11 20:52:02       18 阅读
  5. pytorch 模型保存到本地之后,如何继续训练

    2024-07-11 20:52:02       22 阅读
  6. 【Spring】springSecurity使用

    2024-07-11 20:52:02       16 阅读
  7. 力扣682.棒球比赛

    2024-07-11 20:52:02       17 阅读
  8. STM32学习历程(day4)

    2024-07-11 20:52:02       20 阅读
  9. C# 装饰器模式(Decorator Pattern)

    2024-07-11 20:52:02       20 阅读
  10. 代码随想录-DAY⑦-字符串——leetcode 344 | 541 | 151

    2024-07-11 20:52:02       21 阅读
  11. FastAPI+SQLAlchemy数据库连接

    2024-07-11 20:52:02       18 阅读
  12. 关于vue监听数组

    2024-07-11 20:52:02       18 阅读
  13. SQL 自定义函数

    2024-07-11 20:52:02       22 阅读
  14. linux内核访问读写用户层文件方法

    2024-07-11 20:52:02       21 阅读
  15. RK3568平台开发系列讲解(网络篇)netfilter框架

    2024-07-11 20:52:02       19 阅读
  16. Netty服务端接收TCP链接数据

    2024-07-11 20:52:02       16 阅读