按键的实现原理:
上图是按键的实现电路图,当按键没有按下时,我们所定义的IO端口一直为高电平,一旦按键按下,电流往低处走,即IO端口没有电流流过,我们检测定义的按键端口的电压为0V,即为低电平的时候,即视为按键按下;但是我们在按下按键的过程中,电压不是骤降为0V的,中间电压的变化是抖动的,我们我们要确定按键是否真的按下,我们需要一个消抖的过程!
那么什么是消抖呢?
我们按下按键,等待电压稳定大概需要10ms左右,所以我们检测到低电平时,我们延时10ms再进行检测,如果还为低电平,则视为按键按下有效。
我们在程序设计的过程中,如果我们按下按键,不进行处理就直接进行任务操作,可能会执行多次任务,这样就与我们的实现效果不相符了;我们可以先检测按键的状态,如果确定按下,再检测到松开按键,再执行任务操作,这样我们就可以保证程序效果;
下面我们用程序来分析一下:
/***********************************************
* filename: key.c
* writer : geeknuo
* time : 2017-1-21
* version : 1.0
* effect : 按键实验
************************************************/
#include <ioCC2530.h>
//端口定义;
#define led P1_0
#define key P0_1
/***********************************************
* function name : delay_ms
* function : 延时函数,单位为毫秒
* prarmeter : n_ms 为延时时间,最大不超过65535
* returned value: 无
************************************************/
void delay_ms(unsigned int n_ms)
{
unsigned int i,j;
for(i = 0; i < n_ms; i++)
for(j = 0; j < 535; j++);
}
/***********************************************
* function name : LedInit
* function : 配置led相关寄存器并设置led初始状态
* prarmeter : 无
* returned value: 无
************************************************/
void LedInit(void)
{
P1DIR |= 0x01; //P1_0设置为输出模式
P1SEL &= ~0x01; //P1_0设置为通用IO
led = 1; //初始状态为熄灭;
}
/***********************************************
* function name : KeyInit
* function : 配置key相关寄存器
* prarmeter : 无
* returned value: 无
************************************************/
void KeyInit(void)
{
P0DIR &= ~0x02; //P1_0设置为输入模式
P0SEL &= ~0x02; //P1_0设置为通用IO
}
/***********************************************
* function name : main
* function : 初始化LED和KEY,当检测到按键按下并松开时,改变led状态
* prarmeter : 无
* returned value: 无
************************************************/
void main(void)
{
LedInit(); //初始化LED
KeyInit(); //初始化KEY
while(1)
{
if(key == 0) //检测到按键按下
{
delay_ms(10); //延时10ms,等待电压稳定
if(key == 0) //如果这时按键还是低电平,那么确定按键按下
{
while(key == 0); //一直等到按键松开
led = ~led; //改变led状态
}
}
}
}