stm32——按键(库函数版)

不得不说进程太慢了

感觉很慌 但是干什么事情又非常的从容

学的很慢学着学着发现 不止是要学新东西 那些 以前早该知道的东西也忘了好多

还有 一定一定要好好学习 扩展知识面 什么东西都一定要学精

因为知识的封锁真的真的很可怕 很可怕 所以一定多学习 多动手 要加油

终于可以看这个的重点了 按键

就好像遥控器 当按下换频道的键时候我们一直按会一直换

 但是 当按下电源键的时候 即使一直按也只会开关一次而不会一直开关 知道松开之后再次按下 才会起作用

所以按键分为支持连续按和不支持连续按

首先支持连续按  

注意此函数有响应优先级,KEY0>KEY1>KEY_UP!!

u8 key_Scan(u8 mode)
{
	if(KEY0 == 0 || KEY1 == 0|| WK_UP == 1)   //key按键按下
	{
		delay_ms(10);
		if(KEY0 == 0)             //    if(key 确实按下)
			return KEY0_PRES;     //   返回按键值
		else if(KEY1 == 0)                
			return KEY1_PRES;
		else if(WK_UP == 1)
			return WKUP_PRES;
	}
	else if(KEY1 == 1 && KEY0 == 1 && WK_UP == 0)
	    return 0;                       //没有按键按下 返回无效值
}

如果不支持连续按

注意此函数有响应优先级,KEY0>KEY1>KEY_UP!!

u8 key_Scan(u8 mode)
{
	static u8 key_up = 1; //按键松开标志
	if(key_up && (KEY0 == 0 || KEY1 == 0|| WK_UP == 1))
	{
		delay_ms(10);
		key_up = 0;
		if(KEY0 == 0)              //if(key确实按下)
			return KEY0_PRES;      // return 键值
		else if(KEY1 == 0)
			return KEY1_PRES;
		else if(WK_UP == 1)
			return WKUP_PRES;
	}
	else if(KEY1 == 1 && KEY0 == 1 && WK_UP == 0)
		key_up = 1;
	return 0;
}

当两个函数合并时

u8 key_Scan(u8 mode)
{
	static u8 key_up = 1; //按键松开标志
	if(mode)
		key_up = 1;
	if(key_up && (KEY0 == 0 || KEY1 == 0|| WK_UP == 1))
	{
		delay_ms(10);
		key_up = 0;
		if(KEY0 == 0)
			return KEY0_PRES;
		else if(KEY1 == 0)
			return KEY1_PRES;
		else if(WK_UP == 1)
			return WKUP_PRES;
	}
	else if(KEY1 == 1 && KEY0 == 1 && WK_UP == 0)
		key_up = 1;
	return 0;
}

所以key的相关函数其实已经差不多说完了

接下来就把 key.c /key,h/ main.c写一下(因为led和蜂鸣器之前已经写过了, 这就不在写了)

按键处理函数
返回按键值
mode:0,不支持连续按;1,支持连续按;
0,没有任何按键按下
1,KEY0按下
2,KEY1按下
3,KEY3按下 WK_UP
注意此函数有响应优先级,KEY0>KEY1>KEY_UP!!

 

#include "key.h"
#include "delay.h"

void key_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|	GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //设置成上拉输入
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	
	//初始化 WK_UP GPIOA.0 下拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}	

u8 key_Scan(u8 mode)
{
	static u8 key_up = 1; //按键松开标志
	if(mode)
		key_up = 1;
	if(key_up && (KEY0 == 0 || KEY1 == 0|| WK_UP == 1))
	{
		delay_ms(10);
		key_up = 0;
		if(KEY0 == 0)
			return KEY0_PRES;
		else if(KEY1 == 0)
			return KEY1_PRES;
		else if(WK_UP == 1)
			return WKUP_PRES;
	}
	else if(KEY1 == 1 && KEY0 == 1 && WK_UP == 0)
		key_up = 1;
	return 0;
}
#ifndef _KEY_H
#define _KEY_H

#include "sys.h"

#define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)
#define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3)
#define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)

#define KEY0_PRES 1    //key0 anxia
#define KEY1_PRES 2     //KEY1 ANXIA
#define WKUP_PRES 3    //KEY_UP anxia 

void key_Init(void);



#endif
#include "stm32f10x.h"
#include "led.h"
#include "beef.h"
#include "key.h"
#include "sys.h"
#include "delay.h"

int main(void)
{
	vu8 key = 0;
	delay_init();
	led_Init();
	beef_Init();
	key_Init();
	LED0 = 0;
	
	while(1)
	{
		key = key_Scan(1);
		if(key)
		{
			switch(key)
			{
				case WKUP_PRES: BEEP=!BEEP; break;
				case KEY1_PRES: LED1=!LED1; break;
				case KEY0_PRES: LED0=!LED0;LED1=!LED1; break;
			}
		}
		else 
			delay_ms(10);
	}	
}

其中有一点吧,main函数的那个vu8, 反正我第一眼看的时候不知道是怎么回事:
u8是无符号字符型,vu8是volatile unsigned char的类型,前者很容易理解,后者的话是为了防止编译器将你定义的变量自动优化掉,以防出现未知情况。一般普通变量都可不加volatile,但是在中断里面所需要执行的变量需要加volatile。

 

加油呀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

 

(资源源于正点原子)

 

你可能感兴趣的:(stm32)