【STM32】GPIO输入

1 GPIO输出

1.1 按键简介

按键:常见的输入设备,按下导通,松手断开

按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动

1.2 传感器模块简介

传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出

分别是光敏电阻传感器(光线越强,光敏电阻的阻值就越小)

热敏电阻传感器(温度越强,热敏电阻的阻值就越小)

对射式红外传感器(红外越强,红外接收管的阻值就越小)

反射式红外传感器

滤波电容:保持电路稳定

硬件电路

一般是这种(下接模式)

第一张图,当K1按下,PA0被下拉到GND,此时读取PAO口的电压就是低电平;

当K1松开,PA0被悬空,引脚的电压不确定,此时必须要求PA0是上拉输入,否则会出现引脚电压不稳定的错误现象。

第二张图多了一个上拉电阻。当按键按下时,PA0被下拉到GND,此时读取PAO口的电压就是低电平;

当按键松开时,引脚由于上拉作用,自然保持高电平。

这种接法下,PA0需要配置成上拉输入或者浮空输入

所以上面这两种接法,按键按下是低电平,松手是高电平。

上接模式

第三张图,PA0通过按键接到3.3V,要求PA0必须配置成下拉输入的模式。

当按键按下时,引脚为高电平;松手时,引脚为低电平。(一般单片机可能没有下拉输入模式)

第四张图,PA0需要配置成下拉输入或者浮空输入

下面这两种接法,按键按下是高电平,松手是低电平。

传感器模块

DO是数字输出;AO是模拟输出(ADC模拟转换器)。

C语言数据类型

|--------------------|--------|---------------------------|-------------------|---------------|
| 关键字 | 位数 | 表示范围 | stdint****关键字 | ST****关键字 |
| char | 8 | -128 ~ 127 | int8_t | s8 |
| unsigned char | 8 | 0 ~ 255 | uint8_t | u8 |
| short | 16 | -32768 ~ 32767 | int16_t | s16 |
| unsigned short | 16 | 0 ~ 65535 | uint16_t | u16 |
| int | 32 | -2147483648 ~ 2147483647 | int32_t | s32 |
| unsigned int | 32 | 0 ~ 4294967295 | uint32_t | u32 |
| long | 32 | -2147483648 ~ 2147483647 | | |
| unsigned long | 32 | 0 ~ 4294967295 | | |
| long long | 64 | -(2^64)/2 ~ (2^64)/2-1 | int64_t | |
| unsigned long long | 64 | 0 ~ (2^64)-1 | uint64_t | |
| float | 32 | -3.4e38 ~ 3.4e38 | | |
| double | 64 | -1.7e308 ~ 1.7e308 | | |

2 GPIO输入之按键控制LED灯

2.1 接线图

低电平点亮

2.2 封装模块

新建文件夹HardWare,模块化代码

先封装GPIO。LED.c,记得加上LED.h

cpp 复制代码
#include "stm32f10x.h"                  // Device header

// LED初始化函数
void LED_Init(void)
{
	// 1使用RCC开启GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 2使用GPIO_Init函数初始化GPIO[推挽输出50MHz]
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;			
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	// 推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 3初始化熄灭
	GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);
}

// 点亮LED1函数
void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}

// 熄灭LED1函数
void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
}


// 点亮LED2函数
void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}

// 熄灭LED2函数
void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_2);
}

// LED1反转
void LED1_Turn(void)
{
	// 读取当前端口输出状态,如果输出是0,就置1;否则置0
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_1);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	}
}

// LED2反转
void LED2_Turn(void)
{
	// 读取当前端口输出状态,如果输出是0,就置1;否则置0
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_2);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);
	}
}

再封装按键。KEY.c,记得加上KEY.h

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"

// 按键初始化函数
// 上拉输入模式
void KEY_Init(void)
{
	// 1使用RCC开启GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	// 2使用GPIO_Init函数初始化GPIO[推挽输出50MHz]
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;			// 上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;			
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		// 其实没有
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

// 读取按键的值
uint8_t KEY_GetNum(void)
{
	uint8_t KeyNum = 0;
	// 1号端口
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
	{
		// 刚按下,有抖动
		Delay_ms(20);
		// 检查按键松手
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
		{
			Delay_ms(20);
			KeyNum = 1;
		}
	}
	
	// 11号端口
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
	{
		// 刚按下,有抖动
		Delay_ms(20);
		// 检查按键松手
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
		{
			Delay_ms(20);
			KeyNum = 2;
		}
	}
	return KeyNum;
}

2.3 主函数

测试代码,主函数

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"

uint8_t keyNum;

int main()
{
	LED_Init();
	KEY_Init();
	
	while (1)
	{
		keyNum = KEY_GetNum();
		// 按键1按下,点亮LED1
		if (keyNum == 1)
		{
			LED1_Turn();
		}
		// 按键2按下,熄灭LED1
		if (keyNum == 2)
		{
			LED2_Turn();
		}
	}
}

代码结构图

我的按键11不起作用,不能控制GPIOA_Pin_2的亮灭。

相关推荐
PegasusYu4 分钟前
STM32校准读取激光测距传感器VL53L0X距离数据
stm32·测距·stm32cubeide·激光测距·vl53l0x·飞行时间·stm32g031f8
代码游侠20 分钟前
学习笔记——嵌入式与51单片机学习
单片机·嵌入式硬件·学习·51单片机
zy1353806757323 分钟前
12V输入5V/2A输出升降压芯片AH4002
科技·单片机·物联网·fpga开发·硬件工程·智能电视
代码游侠29 分钟前
学习笔记——嵌入式系统与51单片机核心
笔记·单片机·嵌入式硬件·学习·51单片机
一枝小雨35 分钟前
【OTA专题】15 实现App后台无感下载固件
stm32·单片机·嵌入式·ota·bootloader
小郭团队1 小时前
教育公平的探索
大数据·人工智能·嵌入式硬件·算法·硬件架构
lemoncat81 小时前
PCB线圈电感设计器推荐
嵌入式硬件·pcb
TEC_INO1 小时前
STM32_10:SPI
stm32·单片机·嵌入式硬件
polarislove02141 小时前
10.3[ADC]采样时间和转换时间-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
创思通信1 小时前
STM32L151RCT6 BC20 采集温湿度DHT11 采集GPS定位 和ADC发送到最新版本ONENET物联网开放平台
stm32·嵌入式硬件·物联网