问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32CubeMX学习笔记:GPIO接口使用详解

创作时间:
作者:
@小白创作中心

STM32CubeMX学习笔记:GPIO接口使用详解

引用
1
来源
1.
https://m.eeworld.com.cn/ic_article/482/691012.html

本文是一篇关于STM32CubeMX软件使用的学习笔记,主要介绍了如何使用该软件进行GPIO接口的配置和代码生成。文章内容包括新建工程、GPIO输出和输入的配置步骤、HAL库与标准库代码的比较以及注意事项等。文章结构清晰,内容详实,配有具体的操作步骤和代码示例,适合有一定基础的嵌入式开发人员学习参考。

一、新建工程

  1. 打开 STM32CubeMX 软件,点击“新建工程”

  1. 选择 MCU 和封装

  2. 配置时钟

RCC 设置,选择 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)

选择 Clock Configuration,配置系统时钟 SYSCLK 为 72MHz

修改 HCLK 的值为 72 后,输入回车,软件会自动修改所有配置

  1. 配置调试模式

非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器

SYS 设置,选择 Debug 为 Serial Wire

二、GPIO输出

2.1 参数配置

在 System Core 中选择 GPIO 设置。

在右边图中找到 LED 灯对应引脚,选择 GPIO_Output。

在GPIO output level 中选择 Low 输出低电平点亮,可以添加自定义标签(这样生成代码也会根据标签设置引脚的宏定义)。

2.2 生成代码

输入项目名和项目路径

选择应用的 IDE 开发环境 MDK-ARM V5

点击 GENERATE CODE 生成代码

2.3 HAL库与标准库代码比较

STM32CubeMX 使用 HAL 库生成的代码:

#define LED_G_Pin GPIO_PIN_0  
#define LED_G_GPIO_Port GPIOB  
#define LED_B_Pin GPIO_PIN_1  
#define LED_B_GPIO_Port GPIOB  

/**  
* @brief GPIO Initialization Function  
* @param None  
* @retval None  
*/  
static void MX_GPIO_Init(void)  
{  
/*定义一个GPIO_InitTypeDef类型的结构体*/  
GPIO_InitTypeDef GPIO_InitStruct = {0};  

/* GPIO Ports Clock Enable */ /*开启LED相关的GPIO外设时钟*/  
__HAL_RCC_GPIOB_CLK_ENABLE();  
__HAL_RCC_GPIOA_CLK_ENABLE();  

/*Configure GPIO pin Output Level */ /* 关闭所有led灯 */  
HAL_GPIO_WritePin(GPIOB, LED_G_Pin|LED_B_Pin, GPIO_PIN_SET);  

/*Configure GPIO pins : LED_G_Pin LED_B_Pin */  
GPIO_InitStruct.Pin = LED_G_Pin|LED_B_Pin;  
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  
GPIO_InitStruct.Pull = GPIO_NOPULL;  
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);  
}  

HAL_GPIO_WritePin(GPIOB, LED_G_Pin|LED_B_Pin, GPIO_PIN_SET); // 输出高电平  
HAL_GPIO_WritePin(GPIOB, LED_G_Pin|LED_B_Pin, GPIO_PIN_RESET); // 输出低电平  
HAL_GPIO_TogglePin(GPIOB, LED_G_Pin); // 反转  

使用 STM32 标准库的代码:

// R-红色  
#define LED1_GPIO_PORT GPIOA /* GPIO端口 */  
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */  
#define LED1_GPIO_PIN GPIO_Pin_8 /* 连接到SCL时钟线的GPIO */  

// G-绿色  
#define LED2_GPIO_PORT GPIOB /* GPIO端口 */  
#define LED2_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */  
#define LED2_GPIO_PIN GPIO_Pin_0 /* 连接到SCL时钟线的GPIO */  

/**  
* @brief 初始化控制LED的IO  
* @param 无  
* @retval 无  
*/  
void LED_GPIO_Config(void)  
{  
/*定义一个GPIO_InitTypeDef类型的结构体*/  
GPIO_InitTypeDef GPIO_InitStructure;  

/*开启LED相关的GPIO外设时钟*/  
RCC_APB2PeriphClockCmd( LED1_GPIO_CLK | LED2_GPIO_CLK, ENABLE);  

/*选择要控制的GPIO引脚*/  
GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;  
/*设置引脚模式为通用推挽输出*/  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
/*设置引脚速率为50MHz */  
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
/*调用库函数,初始化GPIO*/  
GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);  

/*选择要控制的GPIO引脚*/  
GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN;  
/*调用库函数,初始化GPIO*/  
GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);  

/* 关闭所有led灯 */  
GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);  
GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);  
}  

GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN); // 输出高电平  
GPIO_ResetBits(LED1_GPIO_PORT, LED1_GPIO_PIN); // 输出低电平  

__HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); 对应 RCC_APB2PeriphClockCmd( LED1_GPIO_CLK | LED2_GPIO_CLK, ENABLE);  
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 对应 GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);  
HAL_GPIO_WritePin(GPIOB, LED_G_Pin|LED_B_Pin, GPIO_PIN_SET); 对应 GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);  

三、GPIO输入

3.1 参数配置

在 System Core 中选择 GPIO 设置。

在右边图中找到按键对应引脚,选择 GPIO_Input。

3.2 生成代码

输入项目名和项目路径

选择应用的 IDE 开发环境 MDK-ARM V5

每个外设生成独立的 ’.c/.h’ 文件

不勾:所有初始化代码都生成在 main.c

勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。

点击 GENERATE CODE 生成代码

3.3 HAL库与标准库代码比较

STM32CubeMX 使用 HAL 库生成的代码:

#define KEY2_Pin GPIO_PIN_13  
#define KEY2_GPIO_Port GPIOC  
#define KEY1_Pin GPIO_PIN_0  
#define KEY1_GPIO_Port GPIOA  

/**
 * @brief GPIO Initialization Function
 * @param None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();

 /*Configure GPIO pin : KEY2_Pin */
 GPIO_InitStruct.Pin = KEY2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(KEY2_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pin : KEY1_Pin */
 GPIO_InitStruct.Pin = KEY1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
}

HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin); // 读取按键状态

使用 STM32 标准库的代码:

#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA  
#define KEY1_GPIO_PORT GPIOA  
#define KEY1_GPIO_PIN GPIO_Pin_0  
#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC  
#define KEY2_GPIO_PORT GPIOC  
#define KEY2_GPIO_PIN GPIO_Pin_13  

/**  
* @brief 配置按键用到的I/O口  
* @param 无  
* @retval 无  
*/  
void Key_GPIO_Config(void)  
{  
GPIO_InitTypeDef GPIO_InitStructure;  

/*开启按键端口的时钟*/  
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);  

//选择按键的引脚  
GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;  
// 设置按键的引脚为浮空输入  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
//使用结构体初始化按键  
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);  

//选择按键的引脚  
GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;  
//设置按键的引脚为浮空输入  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
//使用结构体初始化按键  
GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);  
}  

GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN);  

__HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); 对应 RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);  
HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct); 对应 GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);  
HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin); 对应 GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN);  

四、注意事项

用户代码要加在 USER CODE BEGIN N 和 USER CODE END N 之间,否则下次使用 STM32CubeMX 重新生成代码后,会被删除。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号