GPIO和PIN

文章目录

  • [1 GPIO和Pin](#1 GPIO和Pin)
    • [1.1 GPIO和Pin基础概念](#1.1 GPIO和Pin基础概念)
    • [1.2 GPIO输入模式](#1.2 GPIO输入模式)
    • [1.3 GPIO输出模式](#1.3 GPIO输出模式)
    • [1.4 GPIO的HAL库](#1.4 GPIO的HAL库)
      • [1.4.1 一些HAL库表示](#1.4.1 一些HAL库表示)
      • [1.4.2 HAL库常用GPIO函数](#1.4.2 HAL库常用GPIO函数)
      • [1.4.3 GPIO点亮led灯程序例子](#1.4.3 GPIO点亮led灯程序例子)

1 GPIO和Pin

1.1 GPIO和Pin基础概念

​ 单片机有很多的引脚,为了操控每一个引脚,我们对引脚进行分组,例如GPIOA,GPIOB,...,GPIOG等等(Group),这一个组就称为一个GPIO端口,一般一个端口包含十六个PIN引脚[0~15]。(一个引脚占2bits,而stm32是32位的,所以一组是16个)。GPIO引脚具有可复用和重映射的特点。

  • GPIO复用功能:即一个管脚可以有不同的功能,但是同一时间的同一管脚只能占有一个功能。
  • GPIO重映射功能:将复用引脚功能重定义到其他引脚,例如USART可能默认使用GPIOA2引脚,但是你可以重映射到GPIOD5使用。

GPIO硬件示意图:

1.2 GPIO输入模式

输入模式有四种,分别是浮空输入,上拉输入,下拉输入,模拟输入:

  1. 浮空输入:不接入上拉电阻或者下拉电阻,直接由触发器输入,该模式内部电路呈现高阻态,该模式必须有明确的电平输入。该模式利用施密特触发器的滞回特性,可以用于进行波形整形,用于抗干扰。如果该引脚悬空,读出的值不确定。同时也可以用来输入微弱的信号。

  2. 上拉输入:即用上拉电阻将输入拉到高电平。

  3. 下拉输入:即用下拉电阻将输入拉到低电平。

  4. 模拟输入:把电压信号直接传送到片上外设模块,如ADC,他和浮空输入的区别是它不经过TTL施密特触发器,是直接将模拟信号传输到外设模块上。

1.3 GPIO输出模式

  1. 推挽输出:即两个电平,0和1。推挽电路工作时,两只对称功率管轮流导通。所以导通损耗小,效率高。输出既可向负载灌电流,也可向负载抽取电流,提高了电路的负载能力和开关速度。
  2. 开漏输出:开漏输出没有高电平,他的两个电平分别是0电平和(1)高阻态(输出1高电平时,即是高阻态)。常常用于电平匹配或者形成"线与"逻辑关系。(电平匹配:例如单片机最高只能输出5v电压,但是输出的外设需要15v电压,这时候就需要使用开漏输出来提高输出电平)。
  3. 复用推挽输出:I/O端口被用做复用功能,即第二功能时的I/O引脚配置,设置为推挽模式。USART,PWM就是典型的复用推挽输出模式。
  4. 复用开漏输出:I/O端口被用做复用功能,即第二功能时的I/O引脚配置,设置为开漏模式。I2C可以使用复用开漏输出模式。

1.4 GPIO的HAL库

1.4.1 一些HAL库表示

c 复制代码
//在HAL库之中,端口的类型,和pin的类型分别是
GPIO_TypeDef				*group;			 //用GPIO_TypeDef的指针定义端口
uint16_t						pin;				//引脚用无符号整形uint16_t定义

//未使用宏定义的时候,例如表示GPIOA Pin12引脚。使用:
GPIOA 和 GPIO_PIN_12  //表示
  
//若在CubeMX中起了名字,即有宏定义,例如重命名为GreenLED,那么表示为:
GreenLED_GPIO_Port 和 GreenLED_Pin //表示
  
//电平状态用GPIO_PinState定义
GPIO_PinState 有两个,分别是GPIO_PIN_RESET和GPIO_PIN_SET

1.4.2 HAL库常用GPIO函数

c 复制代码
//根据GPIO_InitTypeDef结构体的参数初始化GPIO端口
void HAL_GPIO_Init (GPIO_TypeDef * GPIOx, GPIO_InitTypeDef * GPIO_Init);
//将GPIO端口的功能恢复到初始状态
void HAL_GPIO_DeInit (GPIO_TypeDef * GPIOx, uint32_t GPIO_Pin);

//读出GPIOx中输入寄存器的值
GPIO_PinState HAL_GPIO_ReadPin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);
//将数据写入GPIOx中输出寄存器
void HAL_GPIO_WritePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
//翻转某个引脚的电平状态
void HAL_GPIO_TogglePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);

//锁定GPIOx寄存器,锁定后将无法修改直到复位
HAL_StatusTypeDef HAL_GPIO_LockPin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);

1.4.3 GPIO点亮led灯程序例子

在CubeMX中使能相应的LED灯的引脚。

之后我们开始写程序

c 复制代码
//led.h文件
#ifndef __LED_H__
#define __LED_H__

#include "gpio.h"

#define ON 1
#define OFF 0

enum{
	red_led,
	blue_led,
	green_led,
	max_led,
};

extern int turn_led(int which, int status);
extern int blink_led(int which, int interval, int num);
#endif
c 复制代码
//led.c文件
#include "led.h"

typedef struct gpio_s{
	GPIO_TypeDef				*group;
	uint16_t						pin;
}gpio_t;

gpio_t leds[max_led]={
	{ RedLED_GPIO_Port, RedLED_Pin },
	{	BlueLED_GPIO_Port, BlueLED_Pin},
	{	GreenLED_GPIO_Port, GreenLED_Pin},
};

int turn_led(int which, int status)
{
	if (which >= max_led)
	{
		return -1;
	}
	
	GPIO_PinState				level;
	
	level = (status==OFF) ? GPIO_PIN_SET : GPIO_PIN_RESET;
	
	HAL_GPIO_WritePin(leds[which].group, leds[which].pin, level);
	
	return 0;
}

int blink_led(int which, int interval, int num)
{
  while(num--)
  {
		turn_led (which, ON);
		HAL_Delay(interval);
	
		turn_led (which, OFF);
		HAL_Delay(interval);
	}
	return 0;
}

之后在main函数中引入led.h头文件,之后调用led的函数就可以实现跑马灯,改变灯的状态等功能了。

相关推荐
沐欣工作室_lvyiyi19 分钟前
基于物联网的家庭版防疫面罩设计与实现(论文+源码)
人工智能·stm32·单片机·物联网·目标跟踪
9毫米的幻想34 分钟前
【Linux系统】—— 冯诺依曼体系结构与操作系统初理解
linux·运维·服务器·c语言·c++
USER_A0012 小时前
【C语言】第五期——函数
c语言
苏慕TRYACE3 小时前
RT-Thread+STM32L475VET6——USB鼠标模拟
stm32·单片机·嵌入式硬件·计算机外设·rt_thread
李白同学8 小时前
【C语言】结构体内存对齐问题
c语言·开发语言
楼台的春风9 小时前
【MCU驱动开发概述】
c语言·驱动开发·单片机·嵌入式硬件·mcu·自动驾驶·嵌入式
Moonnnn.9 小时前
51单片机学习——动态数码管显示
笔记·嵌入式硬件·学习·51单片机
LS_learner11 小时前
小智机器人CMakeLists编译文件解析
嵌入式硬件·机器人
小鸡岛保安11 小时前
学习笔记-8MQTT-韦东山
stm32·物联网
暗碳12 小时前
stm32 74hc238流水灯
stm32·单片机·嵌入式硬件