STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)

STM32 CubeMX GPIO 输入/输出实战 (超详细配高清图,附源码)

1. 环境准备

  1. 正点原子探索者 V2 (STM32F407ZGT6)
  2. STM32CubeMX 6.2.0
  3. STM32CubeIDE 1.14.0
  4. ST-Link V2

2. GPIO功能概述

STM32F407ZG有8个16引脚的GPIO端口,从PA到PH,还有一个12引脚的PI端口,这些GPIO端口都链接在AHB1总线上,最高时钟频率可以达到168MHz(如下图时钟树),GPIO引脚能承受5V电压。

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第1张图片

一个端口的16个GPIO引脚的功能可以单独配置,每个引脚的输入/输出数据可以单独读取或输出。一个GPIO引脚的内部结构如下图所示,其内部有双向保护二极管,有可配置的上拉或下拉电阻。每个GPIO引脚可以配置为多种工作模式。

根据数据表中列出的每个I/O端口的具体硬件特性,通用IO(GPIO)端口的每个端口位,可以通过软件在以下几种模式下单独配置:

  • 输入模式

  • 模拟模式

  • 输出模式

  • 复用功能模式

  • 外部中断/事件线

在复位期间和刚好复位后,备用功能和外部中断线不活跃,I/O端口配置为输入浮点模式。 所有GPIO引脚都有微弱的内部上拉和下拉电阻,可以激活或不激活。 在输出或备用模式下,每个IO可以配置为开漏或推挽类型,IO速度可以根据VDD值选择。 所有端口都有外部中断/事件功能。要使用外部中断线,端口必须配置为输入模式。所有可用的GPIO引脚都连接到16个外部中断/事件线,从EXTI0到EXTI15。 外部中断/事件控制器由多达23个边缘检测器(16条线连接到GPIO)组成,用于生成事件/中断请求(每个输入线可以独立配置,以选择类型 ) 。(中断或事件)和相应的触发器事件(上升或下降或两者)。每行也可以被独立屏蔽。

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第2张图片

3. 正点原子探索者原理图模块选择

从正点原子的原理图中,选择4个按键,2个LED灯作为本次实验的对象,用4个按键来控制2个LED灯实现不同功能的开关LED灯的效果。

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第3张图片

下图所示是4个按键KEY对应的原理图,及相应的配置功能

名称 端口 引脚功能 特性 初始电平
KEY_UP PA0 Input mode Pull-down 下拉 N/A
KEY2 PE2 Input mode Pull-up 上拉 N/A
KEY1 PE3 Input mode Pull-up 上拉 N/A
KEY0 PE4 Input mode Pull-up 上拉 N/A
Buzzer PF8 Output Pushpull推挽输出, 初始低电平
LED1 PF9 Output Pushpull推挽输出, 初始低电平
LED2 PF10 Output Pushpull推挽输出, 初始低电平

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第4张图片

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第5张图片

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第6张图片

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第7张图片

4. STM32CubeMX配置过程

  1. 创建工程:选择STM32F407/417,MCU类型STM32F407ZGTx,封装Package选择LQFP144

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第8张图片

  1. 找到需要配置的端口PF8,鼠标右键写入自定义的名称

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第9张图片

  1. 写入Buzzer,作为自定义名称

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第10张图片

  1. 鼠标左键点击该端口,选择为GPIO_Output,作为输入引脚

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第11张图片

  1. 同理,按照上述操作,一次吸入名称LED1,LED2,并且将他们选为GPIO_Output

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第12张图片

  1. 点开左侧System Core选项,找到GPIO功能,按照下图说是方法依次配置输出和输入的GPIO端口

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第13张图片

  1. 根据原理图,设置按键的GPIO类型,由于KEY0,1,2都是上拉电阻,因此初始时为了保持开关断开,选择上拉电阻,KEY_UP则为下拉电阻

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第14张图片

  1. RCC模块配置:高速时钟选择外部晶振。

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第15张图片

  1. 调试口本例中选用ST-Link,则选择JTAG(4 PIN)

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第16张图片

  1. 时钟配置:在Input frequency出填写外部晶振8M,在HCLK处填写168MHz,即可自动计算时钟的分频和倍频系数

    image-20231226212731838

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第17张图片

  1. 选择CubeIDE进行编译和调试,如果选用Keil进行调试和编译,则选用MDK-ARM

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第18张图片

  1. 设置堆栈大小

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第19张图片

  1. 配置代码生成

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第20张图片

5. 代码实现

下面我们用STM32官方IDE(继承开发环境)–STM32CubeIDE来进行代码编写,编译和调试,它集成了STM32CubeMX配置工具和Eclipse集成开发环境,为开发人员提供了一个全面的工具套件来编写、编译和调试STM32微控制器的应用程序。2017年,为了取代被ARM公司Keil工具绑定,ST在当年收购Atollic公司,帮助其在原有的TrueStudio扩展到集编译、调试和仿真等于一体的集成开发环境,并完全面向用户免费,再配合其STM32CubeMX,可以达到从代码配置到调试等各个环节。

keyled.h
#include "main.h"

typedef enum {
	KEY_0 = 0,
	KEY_1,
	KEY_2,
	KEY_UP,
	KEY_NONE,
} KEYS;

KEYS ScanPressedKey(uint32_t timeout);

#define KEY_WAIT_ALWAYS		0

#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_RESET)
	#define Buzzer_OFF() 		HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_SET)
#endif


keyled.c
#include "keyled.h"

/**
 * Scans 4 keys in a polling fashion and returns the key value.
 * timeout = 0 (ms) - If timeout = 0, it scans until a key is pressed.
 */
KEYS ScanPressedKey(uint32_t timeout)
{
	KEYS key = KEY_NONE;
	uint32_t tickstart = HAL_GetTick(); /* Get the Current time  */
	const uint32_t binDelay = 20;  /* Delay time for Key shake off */
	while (1)
	{

#ifdef KEY0_Pin
		if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(binDelay);
			if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)
				return KEY_0;
		}
#endif
#ifdef KEY1_Pin
		if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(binDelay);
			if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET)
				return KEY_1;
		}
#endif

#ifdef KEY2_Pin
		if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(binDelay);
			if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET)
				return KEY_2;
		}
#endif
#ifdef KEY_UP_Pin
		if (HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET)
		{
			HAL_Delay(binDelay);
			if (HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET)
				return KEY_UP;
		}
#endif
		if (timeout != KEY_WAIT_ALWAYS)
		{
			if ((HAL_GetTick() - tickstart) > timeout)
				break;
		}

	}
	return key;
}

添加头文件路径

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第21张图片

添加C源文件路径

STM32 CubeMX GPIO 输入/输出按键点亮LED灯实战 (超详细配高清图,附源码)_第22张图片

main.c
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  KEYS curKey = ScanPressedKey(KEY_WAIT_ALWAYS);
	  switch(curKey)
	  {
	  case KEY_0:
		  LED1_Toggle();
		  break;
	  case KEY_1:
		  LED2_Toggle();
		  break;
	  case KEY_2:
		  LED1_Toggle();
		  LED2_Toggle();
		  break;
	  case KEY_UP:
		  Buzzer_Toggle();
		  break;
	  default:
		  break;
	  }
	  HAL_Delay(200);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

基于以上可以实现用轮询Polling的方式实时检测,按下相应的按键点亮LED灯和关闭LED灯的功能。

你可能感兴趣的:(STM32,CubeMX实战,stm32,单片机,嵌入式硬件)