GPIO简介和LED点灯实验

1、GPIO简介

        利用固件库建立好的工程模板,就可以方便地使用STM32 标准库编写应用程序了,可以说从这一 章我们才开始迈入STM32 开发的大门,本章节学习控制 IO 口电平高低实现 LED 灯闪烁的效果。
        GPIO是英文 General Purpose Input/Output 的缩写,中文翻译为通用输入 / 输出。它是一种在数字电
子系统中常见的接口类型,用于与外部设备进行通信和控制。
GPIO 接口可以配置成输出模式来控制外部设备,也可以配置成输入模式来读取外部信号,是
STM32 的一种外设,连接芯片外部的引脚,其引脚可以供使用者自由的进行控制。将 STM32 芯片的 GPIO引脚与外部设备连接起来,也可以实现与外部通讯、控制以及数据采集的功能。 GPIO 最简单的 功能是输出高低电平;GPIO 还可以被设置为输入功能,用于读取按键等输入信号;也可以将 GPIO 复 用成芯片上的其他外设的控制引脚。
        通过使用GPIO 接口,可以方便地与各种外部设备进行交互,如传感器、执行器、显示器、键盘 等。在嵌入式系统、单8 片机和物联网应用中, GPIO 是一种非常常见和重要的接口类型。

2.GPIO输出——LED

STM32F407ZGT6有8组IO。分别为GPIOA~GPIOH,除了GPIOH只有两个IO,其余每组IO有16根引脚。
任务: 编写代码对 GPIO 引脚控制,实现输出高低电平,从而控制 LED 灯闪烁。

2.1 硬件原理

查看开发板原理图,找到 LED 灯原理图和对应的控制引脚
通过原理图我们可知:
LED0 LED1 的阴极都是连接到 STM32 GPIO 引脚,只要我们控制 GPIO 引脚的电平输出状
态,即可控制 LED 灯的亮灭。
LED0 ——PF9 引脚
LED1——PF10 引脚

2.2 代码编程

编写代码实现 GPIO 控制
#include "stm32f4xx.h"


void Delay(uint32_t nCount)
 {
 for(;nCount!=0;nCount--);
 }


int main(void)
 {
GPIO_InitTypeDef GPIO_InitStructure; 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
GPIO_Init(GPIOF, &GPIO_InitStructure);
 
while (1)
{
 GPIO_ResetBits(GPIOF,GPIO_Pin_9);
 GPIO_SetBits(GPIOF,GPIO_Pin_10); 
Delay(0xFFFFFF); 
GPIO_SetBits(GPIOF,GPIO_Pin_9); 
GPIO_ResetBits(GPIOF,GPIO_Pin_10);
 Delay(0xFFFFFF);
 
 }
 }
这种把所有代码都写在 main.c 文件里肯定是不可取的。
这是我们的第一个实验,我们新写的代码是基于上节课的模板 STM32F407_Template 而来(复制 -
> 修改名称为 1.GPIO_LED
1. 进入我们工程的目录,在工程根目录文件夹下面新建一个 HARDWARE的文件夹,用来存储以
后与硬件相关的代码。然后在 HARDWARE文件夹下新建一个 LED文件夹,用来存放与 LED相关的代 码。
2. 打开我们的工程文件,在LED文件夹内新建led.cled.h文件(KEIL5里建立或者经典方式建
立),然后在 Manage Project Itmes管理里面新建一个 HARDWARE的组,并把 led.c加入到这个组里
3. main.c写逻辑代码,led.c写初始化和功能函数,led.h写函数声明,以便被更好地调用。

2.3 程序下载

STM32F4 的程序下载有多种方法: USB 、串口、 JTAG SWD 等,这几种方式都可以用来给
STM32F4 下载代码
方式一: J-LINK 下载
1. J-LINK连接开发板与电脑,注意接口不要接错了
下载成功
方式二:串口下载
1. 安装CH340驱动,用以识别串口,不然window显示不了下载端口
不同电脑端口号是不一样,你的可能是COM4COM5等,但是USB-SERIAL CH340,这个一定是
一样的。如果没找到USB串口,则有可能是你安装有误,或者系统不兼容。
2. 打开串口下载工具:
这种方式下载速度很慢,而且不支持仿真调试,一般情况下还是建议用 J-LINK

3.GPIO详解

STM32F4077IO。分别为GPIOA~GPIOG,每组IO16IO口,共有112IO口 通常称为
PAxPBxPCxPDxPExPFxPGx,其中x0-15

3.1 GPIO工作模式

4种输入模式
1GPIO_Mode_IN_FLOATING 浮空输入
2GPIO_Mode_IPU 上拉输入
3GPIO_Mode_IPD 下拉输入
4GPIO_Mode_AIN 模拟输入
4种输出模式5GPIO_Mode_Out_OD 开漏输出(带上拉或者下拉)
6GPIO_Mode_AF_OD 复用开漏输出(带上拉或者下拉)
7GPIO_Mode_Out_PP 推挽输出(带上拉或者下拉)
8GPIO_Mode_AF_PP 复用推挽输出(带上拉或者下拉)
4种最大输出速度
12MHZ (低速)
225MHZ (中速)
350MHZ (快速)
4100MHZ (高速)

3.2 GPIO电路图

3.2.1 保护二极管

引脚上的这两个保护二极管可以将引脚外部过高或过低的电压进行钳位,当引脚电压高于VDD_FT
时,上方的二极管导通吸收这个高电压,当引脚电压低于VSS 时,下方的二极管导通,防止不正常电 压引入芯片导致芯片烧毁,也叫钳位二极管。

3.2.2 P-MOS 管和 N-MOS 管

P-MOS管和N-MOS管组成的单元电路使得GPIO具有推挽输出开漏输出的模式,当为输出
模式时,线路经过输出控制缓冲器到一个由P-MOS N-MOS管组成的双MOS电路,因此GPIO 引脚
可以配置成推挽和开漏两种输出模式。
在该结构单元输入一个高电平时,P-MOS 管导通,N-MOS 管截止,对外输出高电平(3.3V)。
在该单元输入一个低电平时,P-MOS 管截止,N-MOS 管导通,对外输出低电平(0V)。

3.2.3 TTL 肖特基触发器

信号经过触发器后,将模拟信号转化为 0 1 的数字信号。但是,当 GPIO 引脚作为 ADC 采集电
压的输入通道时,用其模拟输入功能,此时信号不再经过触发器进行TTL电平转换。

3.3 GPIO工作模式详解

3.3.1 模拟输入

此模式可以检测外部输入的模拟电压,可以检测电压值,只要不高于Vcc即可。
模拟输入模式下,不需要连接上拉和下拉电阻,因为GPIO用于模拟功能时,引脚的上、下拉电阻
是不起作用的。这个时候即使在配置了上拉或下拉电阻,也不会影响到模拟信号的输入。 输入信号不再经过TTL施密特触发器,可将外部电压信号直接输入到内部的ADC 外设中去。因为经过施
密特触发器后信号只有01两种状态,所以ADC外设要采集到原始的、连续变化的模拟信号,信号源输入必须在施密特触发器之前。

3.3.2 浮空输入

输入浮空模式下,指的是该IO口既不配置接上拉电阻也不配置接下拉电阻。如果该引脚悬空的情况
无信号输入时,该端口的电平是不确定的。当有电平信号进入IO时,IO电平状态是完全由外部输入决 定,MCU复位上电后,默认为浮空输入模式。

3.3.3 上拉输入

上拉输入模式下, GPIO 端口悬空无输入信号时,输入端的电平可以默认保持在高电平;而当输入
信号低电平时, IO 口读取的电平就是低电平;当输入信号高电平时, IO 口读取的电平自然就是高电
平。
输入下拉模式下,GPIO端口悬空无输入信号时,输入端的电平可以默认保持在低电平;而当输入
信号高电平时,IO口读取的电平就是高电平;当输入信号低电平时,IO口读取的电平自然就是低电
平。

3.3.5 推挽输出

推挽输出模式就是,对输出数据寄存器进行置0或置1操作,然后通过输出控制缓冲器对双MOS
路进行控制。IO电平输出的双MOS电路通路同时由PMOSNMOS组成。
当输出控制端输出为1时,上方PMOS导通,下方NMOS截止,电流方向为VDD->PMOS->输出
端,对外部引脚输出高电平;当输出控制端输出为0时,上方PMOS截止,下方NMOS导通, 电流方向为VSS->NMOS->输出 端,对外输出低电平; 简单来说就是pmosnmos, 同一时间只有一个mos管导通, 可输出高电平或低电平, 输出寄存器决 定输出什么就是什么。

3.3.6 开漏输出

开漏输出最主要的特性就是高电平没有驱动能力,需要借助外部上拉电阻才能真正输出高电平,这
一特性一个明显的优势就是可以很方便的调节输出的电平,因为输出电平完全由上拉电阻连接的电源电平决定。所以在需要进行电平转换的地方,非常适合使用开漏输出。
开漏输出的另一特性好处在于可以实现"线与"功能,所谓的"线与"指的是多个信号线直接连接在一
起,只有当所有信号全部为高电平时,合在一起的总线为高电平;只要有任意一个或者多个信号为低 电平,则总线为低电平。而推挽输出就不行
开漏输出常用在通信接口,有多个设备连接在同一线上(例如 I2COne-Wire)。线路默认被上拉
电阻拉至高电平,当任意设备有信号触发时,就会将整条线电平拉低。
开漏输出和推挽输出的区别最普遍的说法就是开漏输出无法真正输出高电平,即高电平时没有驱动
能力,需要借助外部上拉电阻完成对外驱动。
两者对比:

3.3.7 复用推挽输出

GPIO不仅仅可以用作普通的 IO 口输出,还可以作为芯片上其他外设的特殊功能引脚,有些引脚可
能可以用作多种不同功能,这种就叫做GPIO的复用,具体用作哪种功能,需要根据使用进行相应的配 置。
使用GPIO复用功能时,当配置成推挽输出,这样片上外设就可以输出高电平或者低电平,例如将
GPIO配置成串口USART输出TXD管脚。
需要注意的是,如果需要实现DAC模拟输出,那么也需要将管脚配置成复用功能,但是此时作为
模拟输出功能,DAC的模拟信号输出就不经过双MOS管结构了。

3.3.8 复用开漏输出

与开漏输出模式的不同在于是片上外设决定输出
关于在 STM32 中选用 IO 模式 :
上拉输入、下拉输入可以用来检测外部信号;例如,按键等;
模拟输入 ——应用ADC模拟输入,或者低功耗下省电
开漏输出一般应用在I2CSMBUS通讯等需要"线与"功能的总线电路中。
推挽输出模式一般应用在输出电平为03.3伏而且需要高速切换开关状态的场合。在STM32的应用
中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式。
复用功能的推挽输出_AF_PP ——片内外设功能(IICSCL,SDA
复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS

4.操作GPIO库函数

实验总结如下:
1 ) 使能 IO 口时钟。调用函数为 RCC_AHB1PeriphClockCmd ()
2 ) 初始化 IO 参数。调用函数 GPIO_Init();
3 ) 操作 IO ,点亮 LED
函数 RCC_AHB1PeriphClockCmd () 为开启挂在其上的外设时钟,因为 STM32 外设很多,为了降
低功耗,每个外设都对应着一个时钟,在芯片刚上电的时候这些时钟都是被关闭的,如果想要外设工
作,必须把相应的时钟打开。
所有的 GPIO 都挂载到 AHB1 总线上,有关 STM32 的时钟系统我们在往后的 RCC 章节会详细的讲
解,此处我们只需知道在访问 GPIO 这个外设的寄存器之前,要先开启它的时钟,可以通俗理解为,要
用这个端口,第一步要先通上电。
GPIO 寄存器可查阅手册《 STM32F4xx 参考手册》 7.4 章节,不在教案里说明,下面介绍操作这些
寄存器的库函数:
在库函数种,操作配置寄存器初始化 GPIO 是通过 GPIO 初始化函数完成
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
第一个参数是用来指定需要初始化的 GPIO 对应的 GPIO 组 ,取值范围为 GPIOA~GPIOK
第二个参数为初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef
typedef struct
{
uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
 This parameter can be any value of @ref
GPIO_pins_define */

 GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected
pins.
This parameter can be a value of @ref
GPIOMode_TypeDef */

 GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
 This parameter can be a value of @ref
GPIOSpeed_TypeDef */

 GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the
selected pins.
 This parameter can be a value of @ref
GPIOOType_TypeDef */

 GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for
the selected pins.
This parameter can be a value of @ref
GPIOPuPd_TypeDef */
 }GPIO_InitTypeDef;
第一个成员变量 GPIO_Pin 用来设置是要初始化哪个或者哪些 IO
第二个成员变量 GPIO_Mode 是用来设置对应 IO 端口的输出输入端口模式
第三个参数 GPIO_Speed IO 口输出速度设置
第四个参数 GPIO_OType GPIO 的输出类型设置
第五个参数 GPIO_PuPd 用来设置 IO 口的上下拉

5.GPIO输入——按键

我们的开发板上载有的 4 个按钮 ( KEY_UP KEY0 KEY1 KEY2 ),可用来控制板上的 2
LED

5.1 硬件原理

由原理图可知:
按键 KEY0连接在 PE4
KEY1连接在 PE3
KEY2连接在 PE2
KEY_UP连接在 PA0
KEY没有上下拉电阻,所以需要在STM32F4芯片内部设置上下拉
按键没有按下时
KEY0KEY1KEY2 KEY_UP 引脚的输入状态取决于上下拉
按键按下时:
KEY0KEY1KEY2为低,KEY_UP为高
提问:要将这4个引脚设置成上拉还是下拉?
KEY0KEY1KEY2是低电平有效的,而 KEY_UP是高电平有效

5.2 代码编程

按键机械触点断开、闭合时,由于触点的弹性作用,按键开关不会马上稳定接通或一下子断开,
使用按键时会产生按键抖动,所以需要在代码里消除其抖动。
提问:使用延时的方式是否是按键消抖的常用方式?
延时的方法最简单,但是会增加主循环的负荷,按键按下时会阻塞主循环,降低主循环实时性,在
实时性要求比较高的工程里,一般不会这么做。
其他方式(了解即可):
a. 硬件消抖,添加滤波电容,利用电容两端电压不能突变的特性减少抖动杂波,使波形更加规整。
b. 软件方式一:采用延时检测的方法错开抖动区域。
c. 软件方式二:按键按下后产生外部中断事件,进入中断处理函数中进行延时,缺点:中断中延时会导致低优
先级中断阻塞,也导致主循环阻塞,实时性很差。
d. 软件方式三:
按键 GPIO 初始化为中断方式,按键按下后产生外部中断事件,进入中断处理函数中,不采用延时
消抖,而是开启了一个定时器,定时器设定为 10ms 后产生中断,定时器中断后再次检测按键 GPIO
如果仍然是按下状态则调用按键处理函数。中断中只是开启了定时器,并未阻塞,主循环也没有阻
塞,从性能上最优,但是这种方法用到了一个定时器,占用了处理器资源。(可优化为状态机)

6.引脚复用

IO 引脚是有限的,但是外设模块是无限的, IO 引脚肯定是不够用的,为了解决引脚不够用的问题,
引出了引脚复用的概念
STM32F4 系列微控制器 IO 引脚通过一个复用器连接到内置外设或模块。该复用器一次只允许一个
外设的复用功能, AF 连接到对应的 IO 口。这样可以确保共用同一个 IO 引脚的外设之间不会发生冲
突。
具体怎么使用,等到具体的实验章节我们再讲,这里大家有个概念即可
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于STM32GPIO输出实验,点亮三色LED,您可以按照以下步骤进行操作: 1. 首先,您需要在STM32的开发环境中创建一个新的工程。 2. 在工程中,您需要包含相应的头文件,如"stm32f10x.h"。 3. 接下来,配置相应的引脚为输出模式。假设红色LED连接到GPIOA的Pin0引脚,绿色LED连接到GPIOA的Pin1引脚,蓝色LED连接到GPIOA的Pin2引脚,您可以使用以下代码进行配置: ``` GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置红色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置绿色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置蓝色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` 4. 现在,您可以使用相应的寄存器来控制LED的点亮和熄灭。例如,要点亮红色LED,可以使用以下代码: ``` GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置高,点亮红色LED ``` 要熄灭红色LED,可以使用以下代码: ``` GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置低,熄灭红色LED ``` 同样的方法,您可以控制绿色和蓝色LED的点亮和熄灭。 这就是点亮三色LED的基本步骤。希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值