1.基于STM32F407的GPIO输入与输出讲解

1.什么是GPIO?

General Purpose Input Output,即通用输入输出端口,简称GPIO
作用:通过IO口采集外部器件的“输入”信息或者“输出”控制外部器件工作,即输入输出
在这里插入图片描述

2.STM32 GPIO简介

(1)STM32 GPIO电气特性

在这里插入图片描述

(2)GPIO引脚分布

STM32引脚类型:
电源引脚、晶振引脚、复位引脚、下载引脚、BOOT引脚、GPIO引脚

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)GPIO的八种模式

在这里插入图片描述

(4)GPIO寄存器介绍

GPIO通用寄存器GPIOX_yyy

MODEROTYPEROSPEEDRPUPDRIDRODRBSRRLCKR
设置模式设置输出类型设置输出速度设置上下拉电阻输入数据输出数据设置ODR寄存器值配置锁定,用得不多

在这里插入图片描述
在这里插入图片描述

3.GPIO的HAL库函数

在这里插入图片描述

函数名功能描述
HAL_GPIO_Init()GPIO引脚初始化
HAL_GPIO_DeInit()GPIO引脚反初始化,恢复为复位后的状态
HAL_GPIO_WritePin()使引脚输出0或1
HAL_GPIO_ReadPin()读取引脚的输入电平
HAL_GPIO_TogglePin()翻转引脚的输出
HAL_GPIO_LockPin()锁定引脚配置,而不是锁定引脚的输入或输出值

4.GPIO使用硬件操作示例

(0)功能要求:

实现右按键按下,LED1灯翻转;左按键按下,LED2灯翻转;上按键按下,两灯同时翻转;下按键按下,蜂鸣器响灭。

(1)电路链接图

开发板有2个LED、4个按键和1个有源蜂鸣器,通过GPIO引脚控制。

  • LED电路:GPIO通过PF9 和 PF10 分别控制2个LED灯,设置为推挽输出。高电平,LED灭;低电平,LED亮;

  • 按键电路:设置为输入模式。在按键按下时,输入PA0引脚为高电平,所以,引脚PA0在初始设置时应为:输入下拉

    另外3个按键,在按键按下时,引脚PE2,PE3,PE4为高电平,所以,引脚PE2,PE3,PE4在初始设置时应为:输入上拉

  • 蜂鸣器电路:蜂鸣器有PF8控制,设置为推挽输出。当PF8输出为0时,蜂鸣器响;为1时,蜂鸣器不响。

    在这里插入图片描述

    LED电路图

在这里插入图片描述

按键电路

在这里插入图片描述

蜂鸣器电路

(2)CUBEMX配置

打开CUBEMX软件:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

配置下载引脚及时钟配置

下载方式设置:

在这里插入图片描述

外部时钟配置:选择外部晶振作为高低速时钟

在这里插入图片描述

在这里插入图片描述

配置GPIO输入输出引脚

用户标签引脚名称引脚功能GPIO模式上下拉模式
LED1FP9GPIO_Output推挽输出
LED2PF10GPIO_Output推挽输出
KeyRightPE2GPIO_Input输入上拉
KeyDownPE3GPIO_Input输入上拉
KeyLeftPE4GPIO_Input输入上拉
KeyUpPA0GPIO_Input输入下拉
BuzzerPF8GPIO_Output推挽输出上拉

在这里插入图片描述

设置引脚模式和用户标签:以PA0和 蜂鸣器PF8为例,其余以此类推

在这里插入图片描述

在这里插入图片描述

生成MDK的工程文件:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.编写驱动程序

keyled.c 程序:

#include "keyled.h"

KEYS ScanPressedKey(uint32_t timeout)
{
	uint32_t tickstart = HAL_GetTick();
	const uint32_t btnDelay = 20;
	while(1)
	{
#ifdef KeyRight_Pin
		if(HAL_GPIO_ReadPin(KeyRight_GPIO_Port,KeyRight_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(btnDelay);
			if(HAL_GPIO_ReadPin(KeyRight_GPIO_Port,KeyRight_Pin) == GPIO_PIN_RESET)
				return KEY_Right;
		}
#endif

#ifdef KeyLeft_Pin
		if(HAL_GPIO_ReadPin(KeyLeft_GPIO_Port,KeyLeft_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(btnDelay);
			if(HAL_GPIO_ReadPin(KeyLeft_GPIO_Port,KeyLeft_Pin) == GPIO_PIN_RESET)
				return KEY_Left;
		}
#endif

#ifdef KeyDown_Pin
		if(HAL_GPIO_ReadPin(KeyDown_GPIO_Port,KeyDown_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(btnDelay);
			if(HAL_GPIO_ReadPin(KeyDown_GPIO_Port,KeyDown_Pin) == GPIO_PIN_RESET)
				return KEY_Down;
		}
#endif

#ifdef KeyUp_Pin
		if(HAL_GPIO_ReadPin(KeyUp_GPIO_Port,KeyUp_Pin) == GPIO_PIN_SET)
		{
			HAL_Delay(btnDelay);
			if(HAL_GPIO_ReadPin(KeyUp_GPIO_Port,KeyUp_Pin) == GPIO_PIN_SET)
				return KEY_Up;
		}
#endif

		if(timeout != KEY_WAIT_ALWAYS)
		{
			if(HAL_GetTick() - tickstart > timeout)
			{
				break;
			}
		}
	}

	return KEY_NONE;
}

keyled.h 程序:

#include "main.h"

typedef enum{
	KEY_Right = 0,
	KEY_Left,
	KEY_Down,
	KEY_Up,
	KEY_NONE,
}KEYS;

#define  KEY_WAIT_ALWAYS 	0

KEYS ScanPressedKey(uint32_t timeout);

#ifdef LED1_Pin
	#define LED1_Toggle() 		HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin)
	#define LED1_ON() 			HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET)
	#define LED1_OFF() 			HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET)
#endif

#ifdef LED2_Pin
	#define LED2_Toggle()		HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin)
	#define LED2_ON()			HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET)
	#define LED2_OFF()			HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET)
#endif

#ifdef Buzzer_Pin
	#define Buzzer_Toggle()		HAL_GPIO_TogglePin(Buzzer_GPIO_Port, Buzzer_Pin)
	#define Buzzer_ON()			HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_SET)
	#define Buzzer_OFF()		HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_RESET)
#endif

main.c 主程序

  while (1)
  {
	  KEYS curKey = ScanPressedKey(20);
	  switch(curKey)
	  {
	  case KEY_Right:
		  LED1_Toggle();
		  break;
	  case KEY_Left:
		  LED2_Toggle();
		  break;
	  case KEY_Down:
		  LED1_Toggle();
		  LED2_Toggle();
		  break;
	  case KEY_Up:
		  Buzzer_Toggle();
		  break;
	  default:
		  break;
	  }
	  HAL_Delay(200);

	  /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }
  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值