GPIO
前言:学习一下STM32HAL库,顺便复习一下基础知识,文档看的是韦东山老师的HAL文档,直接看文档例程,然后在开发板上复现,使用的是正点原子精英板STM32F1。以此输出笔记记录。
基本结构:
工作模式
输出模式:推挽输出、开漏输出、复用推挽输出、复用开漏输出
1、推挽输出模式可以直接输出高电平,开漏输出模式需要外接上拉电阻才能输出高电平
2、GPIO引脚除了作为通用输入/输出引脚使用外,还可以作为片上外设(USART、IIC、SPI等)专用引脚,即一个引脚可以有多种用途,但同一时刻一个引脚只能使用复用功能中的一个。即可选择复用推挽输出模式或复用开漏输出模式。
输入模式:上拉输入、下拉输入、浮空输入、模拟输入
HAL库常用API函数
1、使能GPIO时钟:
__HAL_RCC_GPIOx_CLK_ENABLE()
注:GPIOx:表示GPIOA/B/C/D/E../H中某一组端口,具体看是哪个GPIO口
2、对GPIO的输出控制函数:
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
参数说明:
GPIOx:表示GPIOA/B/C/D/E../H中某一组端口;
GPIO_Pin:表示在某组端口中的某一个引脚;
PinState:表示对这个IO控制输出的状态, 是一个枚举类型,包含两个成员:GPIO_PIN_RESET、GPIO_PIN_SET。 因为低电平亮灯,所以定义ON对应GPIO_PIN_RESET, OFF对应GPIO_PIN_SET
3、对GPIO的读取函数:
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
返回值: 0 是低电平;1 是高电平
4、GPIO引脚初始化:
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
5、延时函数:
__weak void HAL_Delay(uint32_t Delay)
实验:
实验一:点亮LED灯
目的:理解 GPIO 作为输出,输出高低电平,实现点灯效果
软件设计思路:
- 1、选择LED对应的GPIO
- 2、使能GPIO对应的时钟
- 3、配置其为上拉输出模式
- 4、控制其输出或低来控制LED的亮与灭
driver_led.h
#ifndef __DRIVER_LED_H
#define __DRIVER_LED_H
#include "stm32f1xx_hal.h"
//引脚宏定义:LED引脚、端口
#define LED_GPIO_PIN GPIO_PIN_5
#define LED_GPIO_PORT GPIOE
#define LED_GPIO_CLK_EN() __HAL_RCC_GPIOE_CLK_ENABLE()
/***函数宏定义**/
//LED亮灭函数
#define ON GPIO_PIN_RESET
#define OFF GPIO_PIN_SET
#define LED(flag) HAL_GPIO_WritePin(LED_GPIO_PORT, LED_GPIO_PIN, flag);
//初始化函数
void LedGpioInit(void);
#endif /*__DRIVER_LED_H */
driver_led.c
#include "driver_led.h"
void LedGpioInit(void)
{
//定义GPIO的结构体变量
GPIO_InitTypeDef GPIO_InitStruct = {0};
//使能LED的GPIO 对应的时钟
LED_GPIO_CLK_EN();
GPIO_InitStruct.Pin = LED_GPIO_PIN; // 选择 LED 的引脚
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 设置为推挽输出模式
GPIO_InitStruct.Pull = GPIO_PULLUP; // 默认上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;// 引脚反转速度设置为快
//初始化引脚配置
HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
}
main.c
#include "main.h"
#include "driver_led.h"
int main(void)
{
// 初始化HAL库函数必须要调用此函数
HAL_Init();
SystemClock_Config();
//初始化LED
LedGpioInit();
while(1)
{
LED(ON);
HAL_Delay(1000);
LED(OFF);
HAL_Delay(1000);
}
}
实验二:按键轮询
目的:理解 GPIO 作为输入,读取电平变化,实现按键输入效果
- 1、按键初始化:GPIO端口时钟使能、GPIO引脚设置为输入
- 2、封装每个按键处理函数:读取按键GPIO状态,操作对应LED灯亮灭;
- 3、主函数轮询按键状态:一直检测是否有按键被按下
driver_key.h
#ifndef __DRIVER_KEY_H
#define __DRIVER_KEY_H
#include "stm32f1xx_hal.h"
//引脚宏定义:引脚、端口
#define KEY_GPIO_PIN GPIO_PIN_0
#define KEY_GPIO_PORT GPIOA
#define KEY_GPIO_CLK_EN() __HAL_RCC_GPIOA_CLK_ENABLE()
//引脚状态宏定义:
#define PUSH_DOWN GPIO_PIN_RESET
#define SPRING_UP GPIO_PIN_SET
/*按键状态读取函数宏定义*/
#define KEY HAL_GPIO_ReadPin(KEY_GPIO_PORT, KEY_GPIO_PIN)
void KeyInit(void);
#endif /*__DRIVER_KEY_H */
driver_key.c
#include "driver_key.h"
void KeyInit(void)
{
//定义GPIO的结构体变量
GPIO_InitTypeDef GPIO_InitStruct = {0};
//使能LED的GPIO 对应的时钟
KEY_GPIO_CLK_EN();
GPIO_InitStruct.Pin = KEY_GPIO_PIN; // 选择 LED 的引脚
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 设置为推挽输出模式
GPIO_InitStruct.Pull = GPIO_PULLUP; // 默认上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;// 引脚反转速度设置为快
//初始化引脚配置
HAL_GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);
}
main.c
#include "main.h"
#include "driver_led.h"
#include "driver_key.h"
int main(void)
{
//uint32_t sys_clk = 0;
// 初始化HAL库函数必须要调用此函数
HAL_Init();
SystemClock_Config();
//初始化
LedGpioInit();
KeyInit();
while(1)
{
if(KEY == PUSH_DOWN)
{
HAL_Delay(8);
if(KEY == PUSH_DOWN)
{
LED(ON);
}
}
}
}