基于STM32-按键输入与八种IO口模式

按键检测使用到 GPIO 外设的基本输入功能, 按键机械触点断开、闭合时,由于触点的弹性作用,按键开关不会马上稳定接通或一下子断开,使用按键时会产生图 中的带波纹信号,需要用软件消抖处理滤波,不方便输入检测。


这里再讲下八种IO口模式:

1.模拟输入
 
我认为模拟输入最重要的一点就是。他不经过输入数据寄存器,所以我们无法通过读取输入数据寄存器来获取模拟输入的值,我认为这一点也是非常好理解的,由于输入数据寄存器中存放的不是0就是1。而模拟输入信号不符合这一要求,所以自然不能放进输入数据寄存器。该输入模式,使我们能够获得外部的模拟信号。
2.浮空输入
 
该输入状态。我的理解是。它的输入全然由外部决定,我认为在数据通信中应该能够使用该模式。应为在数据通信中。我们直观的理解就是线路两端连接着发送端和接收断。他们都须要准确获取对方的信号电平,不须要外界的干预。

所以我认为这样的情况适合浮空输入。比方我们熟悉的I2C通信。

3上拉输入
 
上拉输入就是在输入电路上使用了上拉电阻。这样的模式的优点在于我们什么都不输入时,由于内部上拉电阻的原因,我们的处理器会认为我们输入了高电平。这就避免了不确定的输入。

这在要求输入电平仅仅要高低两种电平的情况下是非常实用的。

4下拉输入
和上拉输入相似,只是下拉输入时,在外部没有输入时,我们的处理器会认为我们输入了低电平。
5开漏输出
 
开漏输出,输出端相当于三极管的集电极。所以适合与做电流驱动的应用。要得到高电平。须要上拉电阻才干够。

6推挽输出

 推挽输出使用了推挽电路,结合推挽电路的特性。它是由两个MOSFET组成,一个导通的同一时候,另外一个截至,两个MOSFET分别连接高低电平,所以哪一个导通就会输出相应的电平。推挽电路速度快,输出能力强,直接输出高电平或者低电平。
 能够输出高,低电平,连接数字器件; 推挽结构通常是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候还有一个截止。

7复用开漏和复用推挽
 
我们知道这仅仅是对GPIO的复用而已。

使普通的GPIO具有了别的功能。


程序如下:

#ifndef _KEY_H
#define _KEY_H
#include "stm32f10x.h"
#include "sys.h"
u8 Key_Scan(u8 mode);

//#define KEY1   (!!(GPIOE->IDR & 0x0010))
//#define KEY2   (!!(GPIOE->IDR & 0x0008))
//#define KEY3   (!!(GPIOE->IDR & 0x0004))
//#define KEY_UP (!!(GPIOA->IDR & 0x0001))

#define KEY1 	PEin(4)
#define KEY2	PEin(3)
#define KEY3 	PEin(2)
#define KEY_UP PAin(0)

void Key_Init(void);
#endif


#include "key.h"
#include "delay.h"
/*
函数功能:按键初始化
硬件连接:
		KEY_UP -> PA.0
		KEY1   -> PE.4
		KEY2   -> PE.3
		KEY3   -> PE.2
*/

void Key_Init(void)
{
	//时钟使能
	RCC->APB2ENR |=1<<6;	//GPIOE
	RCC->APB2ENR |=1<<2;	//GPIOA
	
	//端口配置
	GPIOE->CRL &=0xFFF000FF;	//PE2-4
	GPIOE->CRL |=0x00088800;
	
	GPIOE->ODR |=7<<2;
	
	GPIOA->CRL &=0xFFFFFFF0;	//PA.0
	GPIOA->CRL |=0x00000008;
	//GPIOE->ODR|=7<<2; //PE2~4 上拉
}
/*
函数功能:按键扫描
说		明:u8 mode 0不支持长按,1支持长按
*/
u8 Key_Scan(u8 mode)
{
	static u8 key_flag=1;//按键标志
	if(mode)  key_flag=1;
	if(key_flag&&(KEY1==0 || KEY2==0 || KEY3==0 || KEY_UP==1))
	{
		delay_MS(5);	//消抖过程
		key_flag=0;
		if(KEY1==0)	return 1;
		else if(KEY2==0)	return 2;
		else if(KEY3==0)	return 3;
		else if(KEY_UP==1)	return 4;
	}
	else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY_UP==0)
		key_flag=1;
	return 0;
}


#include "led.h"
#include "delay.h"
#include "key.h"
int main(void)
{
	u8 key_value;
	Led_Init();	
	Delay_Init(72);
	Beep_Init();
	Key_Init();
	while(1)
	{	
		key_value=Key_Scan(0);//这里不支持长按
		switch(key_value)
		{
			//四个按键分别控制LED‘的亮灭
			case 1:LED1=!LED1;break;
			case 2:LED2=!LED2;break;
			case 3:LED3=!LED3;break;
			case 4:LED4=!LED4;break;
		}
	}
}



  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于STM32的4x4矩阵按键的代码例程: ``` #include "stm32f10x.h" void GPIO_Configuration(void); void Delay(__IO uint32_t nCount); int main(void) { GPIO_Configuration(); while (1) { if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) { // 第一行第一列按键按下 Delay(1000); // 防止按键抖动 if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) { // 处理按键按下事件 // ... } } else if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0) { // 第一行第二列按键按下 Delay(1000); if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0) { // 处理按键按下事件 // ... } } // 其他行列按键同理 } } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } void Delay(__IO uint32_t nCount) { for (; nCount != 0; nCount--); } ``` 在此代码中,GPIO_Configuration函数配置了GPIOA的第0~3位为输入上拉模式,第4~7位为推挽输出模式,用于控制4x4矩阵按键的行列信号。然后在主函数中,通过读取GPIOA的输入状态来检测按键是否按下,如果按下则处理按键按下事件。需要注意的是,在检测按键状态时需要加上一段延时代码以防止按键抖动。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值