不得不说进程太慢了
感觉很慌 但是干什么事情又非常的从容
学的很慢学着学着发现 不止是要学新东西 那些 以前早该知道的东西也忘了好多
还有 一定一定要好好学习 扩展知识面 什么东西都一定要学精
因为知识的封锁真的真的很可怕 很可怕 所以一定多学习 多动手 要加油
终于可以看这个的重点了 按键
就好像遥控器 当按下换频道的键时候我们一直按会一直换
但是 当按下电源键的时候 即使一直按也只会开关一次而不会一直开关 知道松开之后再次按下 才会起作用
所以按键分为支持连续按和不支持连续按
首先支持连续按
注意此函数有响应优先级,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。
加油呀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(资源源于正点原子)