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的函数就可以实现跑马灯,改变灯的状态等功能了。

相关推荐
时光の尘12 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
-一杯为品-22 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
爱摸鱼的孔乙己1 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
嵌入式大圣2 小时前
单片机结合OpenCV
单片机·嵌入式硬件·opencv
IU宝2 小时前
C/C++内存管理
java·c语言·c++
qq_459730032 小时前
C 语言面向对象
c语言·开发语言
陌小呆^O^3 小时前
Cmakelist.txt之win-c-udp-client
c语言·开发语言·udp
日晨难再3 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
yufengxinpian4 小时前
集成了高性能ARM Cortex-M0+处理器的一款SimpleLink 2.4 GHz无线模块-RF-BM-2340B1
单片机·嵌入式硬件·音视频·智能硬件