STM32 CubeIDE(四) GPIO标准通用输入/输出端口

STM32 CubeIDE(四) GPIO标准通用输入/输出端口

STM32 GPIO

GPIO是标准通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。

STM32F407ZGT6是LQFP144封装的芯片,共有144个引脚,共有140个标准通用输入/输出端口(GPIO),包括7个标准通用输入/输出端口(GPIO)组,分别为GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG,通常简略称为PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。STM32的大部分引脚除了当GPIO使用之外,还可以复用位外设功能引脚,这部分在后面具体用到某个模块时再做介绍。
GPIO结构
根据数据手册中列出的每个 I/O 端口的特性,可通过软件将GPIO端口的各个端口位分别配置为多种模式:
● GPIO_MODE_INPUT,输入模式
● GPIO_MODE_ANALOG, 模拟输入
● GPIO_MODE_OUTPUT_OD,开漏输出
● GPIO_MODE_OUTPUT_PP,推挽输出
● GPIO_MODE_AF_PP,复用功能推挽
● GPIO_MODE_AF_OD,复用功能开漏

也可以对每个IO进行上拉电阻或者下拉电阻操作:
● GPIO_NOPULL,浮空电阻
● GPIO_PULLUP,上拉电阻
● GPIO_PULLDOWN,下拉电阻

同时,GPIO还支持四种最大翻转速度:
● GPIO_SPEED_FREQ_LOW,2MHz
● GPIO_SPEED_FREQ_MEDIUM,25MHz
● GPIO_SPEED_FREQ_HIGH,50MHz
● GPIO_SPEED_FREQ_VERY_HIGH,100MHz

在STM32中一般如何选择GPIO工作模式?
● 浮空输入,用于检测标准信号输入,例如按键识别
● 模拟输入,用于ADC的输入
● 推挽输出,用于标准高低电平输出
● 开漏输出,用于实现“线与”逻辑
● 复用推挽,用于片内外设
● 复用开漏,用于片内外设

STM32 GPIO实验
本次实验基于野火STM32F407-霸天虎V2开发板实现,使用按键控制RGBLED的状态,涉及GPIO的推挽输出与浮空输入两种模式,并以此介绍基于CubeMX环境下,使用HAL库对GPIO进行配置的方法。

HAL库对于GPIO的结构体定义如下:

typedef struct
{
  uint32_t Pin;       /* 引脚,GPIO_Pin_0~15 */

  uint32_t Mode;      /* GPIO模式  */

  uint32_t Pull;      /* GPIO上/下拉电阻  */

  uint32_t Speed;     /* GPIO翻转速度  */

  uint32_t Alternate;  /* GPIO复用功能引脚映射  */
  
}GPIO_InitTypeDef;

HAL库对于GPIO的操作基本函数如下:

/**
  * @brief   GPIO初始化
  * @param   具体的端口,引脚
  *		@arg GPIOx:GPIOA~G
  *		@arg GPIO_Init: GPIO结构体
  */
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
/**
  * @brief   在GPIO初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值
  * @param   具体的端口,引脚
  *		@arg GPIOx:GPIOA~G
  *		@arg GPIO_PIN: GPIO_PIN_0~15
  */
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
/**
  * @brief   读取引脚的电平状态、函数返回值为0或1
  * @param   具体的端口,引脚
  *		@arg GPIOx:GPIOA~G
  *		@arg GPIO_PIN: GPIO_PIN_0~15
  * @retval  返回值
  *		@arg 1:高电平返回1
  *		@arg 0:低电平返回0
  */
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/**
  * @brief   GPIO引脚输出电平
  * @param   具体的端口,引脚,输出电平状态
  *		@arg GPIOx:GPIOA~G
  *		@arg GPIO_PIN: GPIO_PIN_0~15
  *		@arg PinState:GPIO_PIN_SET高电平,GPIO_PIN_RESET低电平
  */
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
/**
  * @brief   GPIO引脚电平翻转
  * @param   具体的端口,引脚
  *		@arg GPIOx:GPIOA~G
  *		@arg GPIO_PIN: GPIO_PIN_0~15
  */
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/**
  * @brief   GPIO引脚当前电平锁定
  * @param   具体的端口,引脚
  *		@arg GPIOx:GPIOA~G
  *		@arg GPIO_PIN: GPIO_PIN_0~15
  */
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

由开发板原理图可知,RGBLED对应PF6、PF7、PF8,低电平点亮;按键KEY1对应PA0,按下为低电平。因此我们新建一个工程,对如下IO进行配置,每个IO都有如下参数:
GPIO outp level:初始化后IO的输出电平,选择High高电平
GPIO mode:初始化后IO的工作模式,选择Output Push Pull推挽输出
GPIO Pull-up/Pull-down:初始化后IO上下拉电阻使能,选择No浮空
Maximum output speed:初始化后IO的翻转速度,选择Low 2MHz
User Label:用户标签,配置为KEY1、LED_Red、LED_Green、LED_Blue
设置完成后点击Device Configuration Tool Code Generation自动生成代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
打开main.h头文件,在相应位置添加/修改为如下内容:

/* USER CODE BEGIN EFP */
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/
#define LED_Red_Pin 		GPIO_PIN_6
#define LED_Red_GPIO_Port 	GPIOF
#define LED_Green_Pin 		GPIO_PIN_7
#define LED_Green_GPIO_Port GPIOF
#define LED_Blue_Pin 		GPIO_PIN_8
#define LED_Blue_GPIO_Port 	GPIOF
#define KEY1_Pin 			GPIO_PIN_0
#define KEY1_GPIO_Port 		GPIOA
/* USER CODE BEGIN Private defines */
#define LED_Red_OFF			HAL_GPIO_WritePin(LED_Red_GPIO_Port,LED_Red_Pin,GPIO_PIN_SET);
#define LED_Red_ON			HAL_GPIO_WritePin(LED_Red_GPIO_Port,LED_Red_Pin,GPIO_PIN_RESET);

#define LED_Green_OFF		HAL_GPIO_WritePin(LED_Green_GPIO_Port,LED_Green_Pin,GPIO_PIN_SET);
#define LED_Green_ON		HAL_GPIO_WritePin(LED_Green_GPIO_Port,LED_Green_Pin,GPIO_PIN_RESET);

#define LED_Blue_OFF		HAL_GPIO_WritePin(LED_Blue_GPIO_Port,LED_Blue_Pin,GPIO_PIN_SET);
#define LED_Blue_ON			HAL_GPIO_WritePin(LED_Blue_GPIO_Port,LED_Blue_Pin,GPIO_PIN_RESET);

#define KEY_Touch	1
#define KEY_NOTouch	0
/* USER CODE END Private defines */

打开main.c头文件,在相应位置添加/修改为如下内容:

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint8_t LED_Flag = 0;
/* USER CODE END PV */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(Key_Scan(KEY1_GPIO_Port,KEY1_Pin) == KEY_Touch)
		  LED_Flag++;
	  switch(LED_Flag)
	  {
	  	  case 0:LED_Red_OFF;LED_Green_OFF;LED_Blue_OFF;break;
	  	  case 1:LED_Red_ON;LED_Green_OFF;LED_Blue_OFF;break;
	  	  case 2:LED_Red_OFF;LED_Green_ON;LED_Blue_OFF;break;
	  	  case 3:LED_Red_OFF;LED_Green_OFF;LED_Blue_ON;break;
	  	  case 4:LED_Red_ON;LED_Green_ON;LED_Blue_OFF;break;
	  	  case 5:LED_Red_ON;LED_Green_OFF;LED_Blue_ON;break;
	  	  case 6:LED_Red_OFF;LED_Green_ON;LED_Blue_ON;break;
	  	  case 7:LED_Red_ON;LED_Green_ON;LED_Blue_ON;break;
	  	  case 8:LED_Flag=0;break;
	  }
	  HAL_Delay(30);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
/* USER CODE BEGIN 4 */
/**
  * @brief   检测是否有按键按下
  * @param   具体的端口和端口位
  *		@arg GPIOx: x可以是(A...G)
  *		@arg GPIO_PIN 可以是GPIO_PIN_x(x可以是0...15)
  * @retval  按键的状态
  *		@arg KEY_Touch:按键按下
  *		@arg KEY_NOTouch:按键没按下
  */

uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
	/*检测是否有按键按下 */
	if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == KEY_Touch )
	{
		/*等待按键释放 */
		while(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == KEY_Touch);
		return 	KEY_Touch;
	}
	else
		return KEY_NOTouch;
}
/* USER CODE END 4 */

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值