【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的亮灭。

相关推荐
纳米软件5 小时前
IGBT模块测试项目集合——纳米软件
单片机·嵌入式硬件·模块测试
单片机系统设计10 小时前
基于STM32的智能台灯系统/智能书桌
stm32·单片机·嵌入式硬件·毕业设计·智能家居
F1331689295710 小时前
5030A 芯片 24V 转 5V 15A 大电流快充选型
网络·单片机·嵌入式硬件·物联网·汽车
恒锐丰小吕10 小时前
无锡黑锋 HF4004 低噪声电荷泵DC-DC转换器技术解析
嵌入式硬件·硬件工程
星一工作室10 小时前
STM32项目分享:基于单片机的智能宠物玩具的设计
stm32·单片机·嵌入式硬件
up向上up10 小时前
基于51单片机数字频率计仿真设计
单片机·嵌入式硬件·51单片机
SystickInt12 小时前
32 RTC实时时钟-独立定时器
stm32·单片机·嵌入式硬件
三佛科技-1873661339712 小时前
智能豆芽机单片机方案开发
单片机·嵌入式硬件
就是蠢啊12 小时前
51单片机——ADC数模转换实验
单片机·嵌入式硬件·51单片机
迅为电子13 小时前
释放多屏潜能:迅为RK3588开发板Android多屏同显开发完全指南
嵌入式硬件·rk3588开发板·多屏同显开发