综合模块之单击双击长按的综合

前言:本程序将在蓝桥杯单片机上实现单击双击和长按三者进行综合,只用一个定时器。其中对次数的处理可以换成其他具体的操作,代码可移植性强,易于理解。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();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值