题目:
虽然用普通的延时函数能够实现按键长按与短按的判别,但是在实际的工程应用和项目开发中并不好用也不灵活。更多得是借助定时器的间隔定时来计算按键从按下到松开的时间间隔,然后通过判断该时间值来区分按键长按与短按的状态。
在新大陆国赛设备的黑色Zigbee模块上,按键SW1短按,切换D5灯的开关状态;按键SW1长按,切换D6灯的开关状态。
按键SW1--->P1_2 D5灯--->P1_3(高电平点亮) D6灯--->P1_4(高电平点亮)
思路:
<1> 定义一个变量F_key,标志按键状态。按键在按下状态时,值为1;按键在松开状态时,值为0。
<2> 定义一个变量count,计算按键处在按下状态的时间,也就是F_key为1时的时间。
<3> 在按键松开后,通过判断count的值来区分按键长按与短按状态。
<4> 每处理完一个按键状态,随即将count清0。
代码:
#include "iOCC2530.h"
#define D3 P1_0
#define D6 P1_4
#define sw1 P1_2
unsigned char F_key = 0; //按键状态
unsigned char count = 0; //定义计数标志位
//延时函数
void Delay(unsigned int t)
{
while(t--);
}
//初始化端口函数
void Init_port()
{
P1SEL &= ~0x1b;
P1DIR |= 0x1b;
P1 &= ~0x1b;
}
//初始化定时器
void Init_time1()
{
T1CC0L = 0xd4;
T1CC0H = 0x30; //16MHz时钟,128分频,定时0.1秒
T1CCTL0 |= 0x04;
T1IE = 1; //开启通道0的输出比较模式
EA = 1;
T1CTL = 0x0e; //分频系数是128,模模式
}
//定时器1服务函数
#pragma vector = T1_VECTOR
__interrupt void Scever_time1()
{
if(F_key == 1)//按键按下
{
count++; //开始计时
}
}
//按键扫描函数
void Scan_keys()
{
if(sw1 == 0)
{
Delay(200); //去抖动处理
if(sw1 == 0)
{
F_key = 1; //按下
while(sw1 == 0);//等待松开
F_key = 0; //松开
if(count > 5)//长按
{
D3 = ~D3;
}
else //短按
{
D6 = ~D6;
}
count = 0; //标志位清零
}
}
}
//主函数
void main()
{
Init_port(); //初始化端口
Init_time1(); //初始化定时器
while(1)
{
Scan_keys(); //按键扫描函数
}
}