前言:本程序将在蓝桥杯单片机上实现单击双击和长按三者进行综合,只用一个定时器。其中对次数的处理可以换成其他具体的操作,代码可移植性强,易于理解。led灯只作调试展示用,可以删去。
功能
数码管显示:
在八位数码管的左边两位为短按次数,中间两位为长按次数,右边两位为双击次数,中间用-隔开。
LED灯功能:
当处于按键周期内(400ms),L1亮起;按键周期结束,L1熄灭。
当S4处于按下状态,L8亮起;当S4处于未按下状态,L8熄灭。
按键功能:
将J5接至矩阵键盘
S4按下时间小于200ms为短按,每次识别到短按,短按次数+1;
S4按下时间大于200ms为长按,每次识别到长按,长按次数+1;
S4在按键周期内按下两次为双击,每次识别到双击,双击次数+1;
S4在按键周期内按下超过两次,不作任何回应。
其他要求:
按键周期为400ms,按键周期结束即开始判断长按短按双击。
视频展示:
长按短按双击实现
基本思路
在按键周期内统计短按的次数,周期结束后马上判断,判断完后马上清零。
代码
其他底层可以参考我之前写过的文章,不再赘述:蓝桥杯单片机测试程序
主程序:
#include <STC15F2K60S2.H>
#include "delay.h"
#include "inithc138.h"
#define de 5
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf
};
unsigned char keycount = 0;//长按读秒
bit keystat = 0;//按键状态
unsigned int count = 0;//按键周期读秒
unsigned char duanan = 0;//短按次数
unsigned char danji = 0;//单击次数
unsigned char changan = 0;//长按次数
unsigned char shuangji = 0;//双击次数
bit flag = 0;
unsigned char ledstat = 0xff;
void shownum(){
showsmg(1,Seg_Table[danji / 10]);
showsmg(2,Seg_Table[danji % 10]);
showsmg(3,Seg_Table[16]);
showsmg(4,Seg_Table[changan / 10]);
showsmg(5,Seg_Table[changan % 10]);
showsmg(6,Seg_Table[16]);
showsmg(7,Seg_Table[shuangji / 10]);
showsmg(8,Seg_Table[shuangji % 10]);
}
void Timer0_Isr(void) interrupt 1
{
if(keystat){
keycount++;
}
if(flag){
count++;
}
if(count == 80){
flag = 0;
}
}
void Timer0_Init(void) //5毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xA0; //设置定时初始值
TH0 = 0x15; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
void led();
void scankey(){
P33 = 0;P32 = 1;P44 = 1;P42 = 1;
if(P44 == 0){
Delay(de);
if(P44 == 0){flag = 1;}
while(P44 == 0){
ledstat = ledstat & ~0x80;
led();
keystat = 1;
shownum();
}
ledstat = ledstat | 0x80;
keystat = 0;
if(keycount < 40){//短按
duanan++;
}else if(keycount >= 40){//长按
duanan = 0;
changan++;
}
keycount = 0;
}
if(flag == 0){//按键周期结束
if(duanan == 1){
danji++;
}
if(duanan == 2){
shuangji++;
}
duanan = 0;
count = 0;
}
led();
}
void led(){
if(flag){
ledstat = ledstat & 0xfe;
outputp0(4,ledstat);
}else{
ledstat = ledstat | 0x01;
outputp0(4,0xff);
}
}
void main(){
Timer0_Init();
initsys();
while(1){
shownum();
scankey();
led();
}
}