STM32·HAL库开发(四)GPIO——案例:输入(按键、振动开关等)控制输出(LED、继电器等)

目录

【GPIO输入模式详解】

输入浮空(GPIO_Mode_IN_FLOATING)

输入上拉(GPIO_Mode_IPU)

输入下拉(GPIO_Mode_IPD)

模拟输入(GPIO_Mode_AIN)

【GPIO输出模式详解】

推挽输出(Push Pull Output,PP)

开漏输出(Open Drain Output,OD)

复用功能推挽/开漏输出( Alternate Function, AF)

【GPIO常用函数】

【STM32CubeMx GPIO配置】

【demo · GPIO点灯】


按键:输入        LED:输出

【GPIO输入模式详解】

输入浮空(GPIO_Mode_IN_FLOATING)

        输入引脚即不接高电平,也不接低电平,用于标准的通讯协议,比如IIC、USART的等,如果想用做按键检测等功能,需外部使用上拉或下拉电阻

输入上拉(GPIO_Mode_IPU)

        相当于输入浮空用来按键检测外加上拉电阻,只不过这个是内部上拉,省去了外部电路

输入下拉(GPIO_Mode_IPD)

        相当于输入浮空用来按键检测外加下拉电阻,只不过这个是内部下拉,省去了外部电路

模拟输入(GPIO_Mode_AIN)

        信号进入后不经过上拉电阻或者下拉电阻,关闭施密特触发器,经由另一线路把电压信号传送到片上外设模块。比如传送给ADC模块,由ADC采集电压信号。所以可以理解为模拟输入的信号是未经处理的信号

        读管脚上的信息时,设置为输入上拉(GPIO_Mode_IPU)

【GPIO输出模式详解】

        STM32的GPIO有8种输入输出模式:

        4种输入:上拉输入、下拉输入、浮空输入、模拟输入
        4种输出:开漏输出、推挽输出、开漏复用输出、推挽复用输出

推挽输出(Push Pull Output,PP)

        推挽输出的结构是由两个三极管或者MOS管受到互补信号的控制,两个管子始终保持一个处于截止,另一个处于导通的状态。
        推挽输出的最大特点是可以真正能真正的输出高电平和低电平,在两种电平下都具有驱动能力,可以输出强高低电平

开漏输出(Open Drain Output,OD)

        开漏输出无法真正输出高电平,即高电平没有驱动能力,需借助外部上拉电阻完成对外驱动

        因为输出电平完全由上拉电阻连接的电源电平决定。所以常用在需要进行电平转换的地方

复用功能推挽/开漏输出( Alternate Function, AF)

        GPIO引脚除了作为通用输入/输出引脚使用外,还可以作为片上外设( USART、 I2C、 SPI等)专用引脚,即一个引脚可以有多种用途,但同一时刻一个引脚只能使用复用功能中的一个。
当引脚设置为复用功能时,可选择复用推挽输出模式或复用开漏输出模式,在设置为复用开漏输出模式时,需要外接上拉电阻

【GPIO常用函数】

void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
功能: GPIO初始化
实例:HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:读取引脚的电平状态、函数返回值为0或1
实例:HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
功能:引脚写0或1 、 GPIO_PIN_RESET 或 GPIO_PIN_SET
实例:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0);

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
翻转引脚的电平状态   
实例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);    常用在LED上
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
功能:  中断回调函数,可以理解为中断函数具体要响应的动作。
实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);    
// 结构体 GPIO_InitTypeDef 定义

typedef struct
{
uint32_t Pin;
uint32_t Mode;
uint32_t Pull;
uint32_t Speed;
} GPIO_InitTypeDef;

【STM32CubeMx GPIO配置】

1)GPIO output level:只有当引脚设置为“GPIO_Output”时才需要设置

    High:GPIO输出初始化为高电平
    Low:GPIO输出初始化为低电平

 2)GPIO mode

    Output Push Pull:推挽输出,能输出高低电平,且高低电平都有驱动能力,对应标准库函数中的“GPIO_Mode_Out_PP”
    Output Open Drain:开漏输出,只能输出低电平,需要借助外部上拉电阻才能输出高电平,对应标准库函数中的“GPIO_Mode_Out_OD”
    Analog mode:模拟输入,ADC采样信号输入引脚的配置模式,对应标准库函数中的“GPIO_Mode_AIN”
    Alternate Function Push Pull:推挽式复用功能,对应标准库函数中的“GPIO_Mode_AF_PP”
    Input mode:输入模式,配合No pull-up/pull-down可形成GPIO_Mpde_IN_FLOATING、GPIO_Mode_IPD、GPIO_Mode_IPU等不同工作模式

3)GPIO Pull-up/Pul-down

    No pull-up/pull-down:无内部上拉或下拉
    Pull-up:内部上拉,默认高电平
    Pull-down:内部下拉,默认低电平

4)Maximum output speed

    Low:低速,对应标准库函数中的“GPIO_Speed_2MHz”
    Medium:中速,对应标准库函数中的“GPIO_Speed_10MHz”
    High:高速,对应标准库函数中的“GPIO_Speed_50MHz”

5)User Label:用户标签,可以按照需要给引脚命名

【demo · GPIO点灯】

 

 

 

关于.h的引用问题:         

         ●     main.h中引入stm32f1xx_hal.h(CubeMx会自动生成)
         ●     main.c中引入用户所有自建的.h文件
         ●     每个用户自建的.h文件仅需引用main.h
         ●     用户自建.c文件引用对应自身的.h
         ●     用户自建.c文件中所有函数都应该在对应.h文件中声明
​         ●     共享变量定义在.c中,并在对应的.h中使用extern声明(extern时不可赋值)
                共享的宏定义一般直接定义在.h中
                需要引用该共享变量的.c文件需引用该.h文件


         ●     若在.c中需要用另一个.c的函数,可使用extern声明,或在.c中引用目标.c文件的.h文件

                如:在a.c中需要用b.c的函数led(),则a.c中写入:#include<b.h>
                       或者:在a.c前面声明extern void led(); 后面再调用led()

         ●     若在.c中需要用另一个.c的变量(定义在.c中而不是.h),可使用extern声明

                如:在a.c中需要用b.c的变量int m,则在a.c前面声明extern int m; 后面再使用m

/* main.h */
#ifndef __MAIN_H
#define __MAIN_H

#include "stm32f1xx_hal.h"


#define LED_Pin GPIO_PIN_13
#define LED_GPIO_Port GPIOC
#define KEY_Pin GPIO_PIN_1
#define KEY_GPIO_Port GPIOA

#define KEY_OFF 0
#define KEY_ON  1

#endif /* __MAIN_H */
/* key.h */
#ifndef __KEY_H__
#define __KEY_H__

#include "main.h"
uint8_t key(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);

#endif /*__ KEY_H__ */
/* led.h */
#ifndef __LED_H__
#define __LED_H__

#include "main.h"
void led(uint8_t KEY_FLAG);

#endif /*__ LED_H__ */
/* key.c */

#include "key.h"

uint8_t key(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
		uint8_t KEY_FLAG = KEY_OFF;
		if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin)==GPIO_PIN_RESET)  //判断KEY引脚是否为低电平
		{
			HAL_Delay(20); //延时20ms
		}
		if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin)==GPIO_PIN_RESET)  //再次判断KEY引脚是否为低电平
		{
			KEY_FLAG = KEY_ON;
		}
		while(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin)==GPIO_PIN_RESET); //等待按键松开
		return KEY_FLAG;
}
/* led.c */

#include "led.h"

void led(uint8_t KEY_FLAG)
{
	if(KEY_FLAG == KEY_ON)
		{
			HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);  
		}
}
/* main.c */

#include "main.h"
#include "gpio.h"

#include "key.h"
#include "led.h"

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  while (1)
  {
		if(key(KEY_GPIO_Port,KEY_Pin)==KEY_ON)	led(KEY_ON);
    /* USER CODE END WHILE */

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

 

扩展说明:

① 按键模块可以直接替换为振动模块、触摸模块等(本质和按键一样,都是人为施加信号时,模块信号引脚输出低电平),程序中仅需根据实际情况调整消抖的延迟时间

② LED可替换为继电器模块,下图所用的继电器规格为DC 5V,Low level trigger
     注意:JQC继电器需要开漏模式(若发现继电器不能正常动作,切换一下开漏/推挽模式试试)

继电器:

        继电器上二极管的作用:续流
        【工程师必备】为什么继电器需要反向并联一个二极管_哔哩哔哩_bilibili
        

【三极管代替继电器】

百度安全验证

https://bbs.youkuaiyun.com/topics/392935388

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值