【stm32_2.2】【快速入门】对GPIO解析、外设的初始化和配置、细节分析GPIO

目录

一、GPIO外设的概念

1.GPIO的概念

2.GPIO的定义

3.引脚的分布

4.引脚的命名

扩展:51单片机的引脚及引脚分别

5.引脚的功能

二、GPIO外设的使用

案例

三、GPIO外设的细节分析

外设的初始化和配置

MCU总线

寄存器的组成、触发器的概述

为什么要打开时钟?


一、GPIO外设的概念

1.GPIO的概念

GPIO(General Purpose Input/Output)外设是++++用于与外部设备进行交互++++ 。++++GPIO引脚的核心功能是作为通用的数字输入或输出++++ ,++可以++ 通过软件++配置为多种工作模式++ ,以满足不同的应用需求,++++GPIO引脚需要和外设连接在一起的,就可以和外设实现通信以及采集数据等功能++++。

2.GPIO的定义

GPIO指的是++++对芯片的某个引脚进行高低电平的输出(输出),以及可以去检测某个引脚的电平状态(输入)。++++

++++一般电平采用都是TTL电平信号,TTL电平信号规定:+5V等价于逻辑"1",0V等价于逻辑"0"。++++

电平其实有一个电平范围:>2.4V就表示高电平,<0.4V就表示低电平。

3.引脚的分布

电源引脚 :VCC、VDD、VSS、VDDA、VSSA、VREF+等属于电源引脚

晶振引脚 :PC14、PC15、PH0、PH1就属于晶振引脚,也可以作为其他的功能使用

复位引脚 :NRST属于复位引脚

BOOT引脚 :BOOT0是专用引脚,BOOT1就属于功能引脚 (设置芯片的自举模式)

GPIO引脚 :芯片一共有144引脚,但是GPIO引脚有114个

下载引脚 :PA13、PA14、PB3、PB4等都属于下载引脚(JTAG、SWD)

4.引脚的命名

IO口的命名是由P(Pin)开头,分为很多组(端口),以字母A~H来命名,每个组(端口)有16个引脚,引脚的编号为0~15,所以如端口A引脚范围: PA0 ~ PA15 端口B引脚范围:PB0~PB15.....

扩展:51单片机的引脚及引脚分别

51单片机也有IO口,一般8051有40个引脚,其中有1个复位引脚,2个晶振引脚,2个电源引脚,3个存储选择引脚,剩下的32个引脚作为IO口,8051也把32个IO口进行分组,分为4个端口,每个端口有8个引脚,端口是以数字0~3进行区分,每个端口的8个引脚是以数字0~7进行区分,比如 P00 ~ P07 P10 ~ P17 P20 ~ P27 P30 ~ P37

5.引脚的功能

需要注意:++芯片的引脚有很多的功能++ ,一般默认的功能都是作为GPIO(输入输出),但是++引脚也有其他的功能,被称为"第二功能"++ ,++++只有在使用ADC通道和DAC需要把引脚设置模拟模式,其他情况下想要把引脚当做别的功能使用, 需要把引脚设置复用模式。++++ 注意:如果想要了解引脚的功能,应该查阅芯片的数据手册!!!!

++++注意:引脚在芯片复位之后的默认功能一般都是GPIO功能,但是并不绝对,所以用户在使用后任何一个引脚的时候都应该查阅芯片数据手册.++++

FT标记:该GPIO可以容忍5v电压。

因为IO口外设有2个保护二极管,可以一定程度上保护IO口,但是保护的上限是5v。

二、GPIO外设的使用

从点亮LED开始,主要是以基础外设作为入门,掌握外设的控制流程。

为了快速入门编写代码,先使用st公司提供的标准外设库的接口完成入门。

  1. 查看原理图,找到控制发光二极管的芯片的IO口
  2. 分析原理图,理解硬件的控制原理(复杂外设还需要结合数据手册)。

当前发光二极管的一端连接正极,为使当前发光二极管亮,则需要MCU输出低电平。

  1. 3.程序设计,根据ST公司提供的函数库(标准外设库)的帮助手册学习开发流程。

案例

需求:实现利用ST公司的关于GPIO外设的代码案例,来控制点亮开发板的4盏LED灯。

cpp 复制代码
/**
   ******************************************************************************
   * @file    GPIO/GPIO_IOToggle/main.c 
   * @author  
   * @version 
   * @date    03-August-2026
   * @brief   利用MCU点亮4盏LED灯的亮
								D1  LED0      PF9
								D2  LED1      PF10
								D3  FSMC_D10  PE13
								D4  FSMC_D10  PE14
   ******************************************************************************
**/

#include "stm32f4xx.h"  //必须要包含的头文件

int main()
{
	//1.定义GPIO外设的结构体变量
	GPIO_InitTypeDef  GPIO_InitStructure;

	//2.打开GPIOF端口、GPIOE端口的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

	//3.配置PF9引脚为输出模式
	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_NOPULL;
	
	//4.对GPIOF端口进行初始化
	GPIO_Init(GPIOF, &GPIO_InitStructure);

    //初始化到端口F,而端口F记录了上述的参数,下方再改参数,对端口F都不会有影响了
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
	GPIO_Init(GPIOE, &GPIO_InitStructure);

	while(1)
	{
		//5.控制PF9引脚输出低电平,则LED会亮
		GPIOF->BSRRH = GPIO_Pin_9 | GPIO_Pin_10 ;
		GPIOE->BSRRH =GPIO_Pin_13 | GPIO_Pin_14;
	}
}

三、GPIO外设的细节分析

外设的初始化和配置

|-----------------|
| 1.定义外设的结构体变量 |
| 2.打开外设的时钟 |
| 3.对外设的结构体成员进行赋值 |
| 4.对外设进行初始化 |

  1. 定义GPIO外设的和初始化相关的结构体变量,结构体类型是定义在stm32f4xx_gpio.h
  1. 2.想要使用GPIO外设,必须提前打开GPIO端口外设时钟

++++STM32的MCU内部有很多外设,每个外设的作用和性能都各不相同++++ ,ST公司为了降低芯片功耗,把不同性能的外设挂载在不同性能的总线上,需要掌握++++3条总线:AHB高级高性能总线(总线频率是168MHZ)、APB1高级外设总线(总线频率是42MHZ)、APB2高级外设总线(总线频率是84MHZ)。++++

MCU总线

而++++MCU内部的外设的性能不同,++++ 所以++++就需要把外设挂载到对应的总线 ,利用总线对外设进行控制。++++

寄存器的组成、触发器的概述

  • 寄存器由若干触发器组成。
  • ++二值信号++ 不仅需要进行算术运算和逻辑运算 ,还经常需要将这些信号和运算结果保存起来 。为此 ====> ++需要使用具有记忆功能的基本逻辑单元++ 。能够存储1位二值信号的基本单元电路 统称为触发器。

记忆1位二值信号触发器的两个基本特点:

  1. 双稳态。具有两个能自行保持的稳定状态,用来表示逻辑状态的0和1
  2. 在触发信号的操作下,根据不同的输入信号可以置成1或0状态。

触发方式:电平触发、脉冲触发和边沿触发三种。

为什么要打开时钟?

++(从功耗的角度)++芯片是低功耗的,为了降低功耗,复位之后,外设都是关闭状态。所以在用外设之前都 要打开时钟。

++(打开时钟的目的,从底层的角度讲)++打开时钟的目的是为了使用寄存器。

++++时钟相当于外设的开关,不打开时钟,则晶振产生的振荡信号就无法输入到++++ MCU内部的外设中,则没有时钟信号,触发器无法触发,则触发器无法锁存数据,而寄存器是由N个触发器组成,所以寄存器就无法工作,而控制硬件,必须通过寄存器实现。

  1. 3.打开GPIO外设的时钟之后,可以对GPIO外设的初始化结构体中的成员进行赋值

设置GPIO引脚编号

/** @defgroup GPIO_pins_define

* @{

*/

#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */

#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */

#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */

#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */

#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */

#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */

#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */

#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */

#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */

#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */

#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */

#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */

#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */

#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */

#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */

#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */

#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */

设置GPIO引脚的模式

typedef enum

{

GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ //输入模式

GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ //输出模式

GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ //复用模式

GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ //模拟模式

}GPIOMode_TypeDef;

设置GPIO引脚的输出速度

指的是引脚电平的切换速度。

输出速度指的是引脚电平的翻转速度,如果选择高速,则会增加功耗和噪声,如果不知道选择哪种,则选择高速即可(为了不影响IO口的性能)。

/**

* @brief GPIO Configuration PullUp PullDown enumeration

*/

typedef enum

{

GPIO_PuPd_NOPULL = 0x00,

GPIO_PuPd_UP = 0x01,

GPIO_PuPd_DOWN = 0x02

}GPIOPuPd_TypeDef;

设置GPIO引脚的输出类型

/**

* @brief GPIO Output type enumeration

*/

typedef enum

{

GPIO_OType_PP = 0x00, //推挽输出

GPIO_OType_OD = 0x01 //开漏输出

}GPIOOType_TypeDef;

设置GPIO引脚的内部电阻

上拉电阻、下拉电阻、不用电阻。

上拉电阻、下拉电阻的作用:在引脚没有外部电平的情况下,选择给引脚提供一个外部电平。

上拉电阻的作用:在引脚没有外部电平的情况下,选择给引脚提供一个高电平。

下拉电阻的作用:在引脚没有外部电平的情况下,选择给引脚提供一个低电平。

/**

* @brief GPIO Configuration PullUp PullDown enumeration

*/

typedef enum

{

GPIO_PuPd_NOPULL = 0x00,

GPIO_PuPd_UP = 0x01,

GPIO_PuPd_DOWN = 0x02

}GPIOPuPd_TypeDef;

4.设置好了GPIO结构体的各个成员的值,需要把结构体中的值写入到GPIO端口寄存器!

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

相关推荐
我是标同学2 小时前
单片机IO增强电流驱动能力的三极管几种接法
单片机·嵌入式硬件
心语星愿112 小时前
STM32单片机高级篇-物联网通信之CAN通讯(学习笔记)
stm32·单片机·物联网
VALENIAN瓦伦尼安教学设备5 小时前
设备对中不良的危害
数据库·嵌入式硬件·算法
爱喝纯牛奶的柠檬5 小时前
【已验证】STM32+MPU6050 姿态解算 + 运动状态识别 + 四阶段摔倒检测
stm32·单片机·嵌入式硬件
戏舟的嵌入式开源笔记5 小时前
STM32 RS485读取SHT20
stm32·单片机·嵌入式硬件
LCG元6 小时前
噪声检测系统:STM32F4驱动MEMS麦克风,FFT频谱分析实战
stm32·单片机·嵌入式硬件
charlie1145141917 小时前
嵌入式C++教程实战之Linux下的单片机编程:从零搭建 STM32 开发工具链(2) —— HAL 库获取、启动文件坑位与目录搭建
linux·开发语言·c++·stm32·单片机·学习·嵌入式
v先v关v住v获v取7 小时前
多功能割草装置的结构设计8张cad+三维图+设计说明书
科技·单片机·51单片机
leiming67 小时前
信号量为什么“不占CPU“
单片机·嵌入式硬件