STM32F103RCT6键盘实验

原理:

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
由图可得:

  • KEY0的IO口为PC5,按下后低电平,所以配置为上拉输入
  • KEY1的IO口为PA15,按下后低电平,所以配置为上拉输入
  • WK_UP的IO口为PA0,按下后高电平,所以配置为下拉输入
原因:
由于按键在没有外界输入的情况下输入端是悬空的,它的电平是未知的
所以上拉电阻就是为了保证无信号输入时输入端的电平为高电平,
同样还有下拉电阻它是为了保证无信号输入时输入端的电平为低电平。

GPIO口配置完成后,剩下读取函数:

unsigned char KeyScan()
{
		static unsigned char key_up = 1;   //按键按下标记按钮
		
		if((key_up == 1)&&(KEY0 == 0||KEY1 == 0||KEY_UP == 1))
		{
				delay_ms(10);//消抖延时
				key_up = 0;//按下确实按下,标记为0
				if(KEY0 == 0) return KEY0_PRESS;
				else if(KEY1 == 0) return KEY1_PRESS;
				else if(KEY_UP == 1) return KEY_UP_PRESS;
		}
		else if(KEY0 == 1&&KEY1 == 1&&KEY_UP == 0) //按键抬起
		{
				key_up = 1;//按键抬起标记为1
		}		
		return 0;
}

注意点:

1.使能时钟函数是APB2!!!!

 void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)

2.多多使用宏定义,很方便,很简洁,例如:

 #define KEY_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)   //直接读取KEY_UP
 #define LED1 PAout(8)    //直接操作LED1

主要代码:

main.c

******************************************************************************
* 文件名:按键实验
* 描  述: 按下KEY0,DS0变化,按下KEY1,DS1变化,按下WK_UP两个灯都变化
* 作  者:思索与猫
* 日  期: 19/4/4
* 备  注: 
*         
******************************************************************************
#include "stm32f10x.h"                  // Device header
#include<sys.h>
#include<led.h>
#include<key.h>
#include<delay.h>

int main()
{
		unsigned char key_value = 0;
		delay_init();
		LED_init();
		KEY_Init();
		while(1)
		{
				key_value = KeyScan();
				switch(key_value)
				{
					case KEY0_PRESS:LED0 = !LED0;break;       
					case KEY1_PRESS:LED1 = !LED1;break;
					case KEY_UP_PRESS:LED0 = !LED0;LED1 = !LED1;break;
					default:delay_ms(10);
				}
		}				
}

key.h

#ifndef __KEY_H
#define __KEY_H
#include<sys.h>

#define KEY0 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)
#define KEY1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)
#define KEY_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)

#define KEY0_PRESS 1
#define KEY1_PRESS 2
#define KEY_UP_PRESS 3


void KEY_Init(void);
unsigned char KeyScan(void);

#endif 

key.c

#include "stm32f10x.h"                  // Device header
#include<key.h>
#include<delay.h>

void KEY_Init()
{
		GPIO_InitTypeDef GPIO_InitStructure;
		
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);
	
		//KEY_UP
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;   //D就是DOWN,下拉输入
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
		GPIO_Init(GPIOA,&GPIO_InitStructure);
	
		//KEY_1
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //U就是UP,上拉输入
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
		GPIO_Init(GPIOC,&GPIO_InitStructure);
	
		//KEY_0
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //U就是UP,上拉输入
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
		GPIO_Init(GPIOA,&GPIO_InitStructure);
}

unsigned char KeyScan()
{
		static unsigned char key_up = 1;
		
		if((key_up == 1)&&(KEY0 == 0||KEY1 == 0||KEY_UP == 1))
		{
				delay_ms(10);
				key_up = 0;
				if(KEY0 == 0) return KEY0_PRESS;
				else if(KEY1 == 0) return KEY1_PRESS;
				else if(KEY_UP == 1) return KEY_UP_PRESS;
		}
		else if(KEY0 == 1&&KEY1 == 1&&KEY_UP == 0)
		{
				key_up = 1;
		}
		
		return 0;
}

led.h

#ifndef __LED_H
#define __LED_H
#include<sys.h>

#define LED1 PAout(8)
#define LED0 PDout(2)

void LED_init(void);

#endif

led.c

#include<led.h>
#include "stm32f10x.h"                  // Device header

void LED_init()
{
		GPIO_InitTypeDef GPIO_InitStructure;
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD,ENABLE);
		
		//ST_LINK使用SW,不使用JTAG,可以省出IO口
		//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
	
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
		GPIO_Init(GPIOA,&GPIO_InitStructure);
		GPIO_SetBits(GPIOA,GPIO_Pin_8);
		 
			
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
		GPIO_Init(GPIOD,&GPIO_InitStructure);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
}
  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值