本帖最后由 hhh402 于 2021-6-13 12:55 编辑
单片机实用按键模块,没有延时语句、while()语句,资源占用小。可以直接复制使用与其他程序不冲突。
使用时只需要直接引用全局变量key1和key2就可以。举例:
1、k1按键按下LED1亮,再次按下LED1灭,
if(key1==1) //k1按键按下
{
key1=0;//必须软件清零!!!
LED1=~LED1;
}
2、k2按键按下LED1亮,K2长按LED1灭,
if(key1==2) //k2按键按下
{
key1=0;//必须软件清零!!!
LED1=0; //0开1关
}
if(key1==20) //k按键长按
{
key1=0;//必须软件清零!!!
LED1=1; //0开1关
}
3、k3按键按下LED1亮,K4按下LED1灭,
if(key1==3) //k3按键按下
{
key1=0;//必须软件清零!!!
LED1=0; //0开1关
}
if(key1==4) //k4按键按下
{
key1=0;//必须软件清零!!!
LED1=1; //0开1关
}
4、K3按下一次,数据m 增加1,长按k3两秒以上每隔500ms数据m 增加10;K4按下一次,数据m 减少1,长按k4两秒以上每隔500ms数据m 减少10;
if(key1==3) //k3按键按下
{
key1=0;//必须软件复位
m++; //数据m 增加1
}
if(key2==3) //k3按键按下两秒以上,注意key2不需要清零,key1必须清零!!!
{
if(ms1>2000&&ms1%500==0) m=m+10; //长按k3两秒以上每隔500ms数据m 增加10,ms1是毫秒变量,需要放在定时器1ms中断中自加,ms1++;
}
else ms1=0; //复位
if(key1==4) //k4按键按下
{
key1=0;//必须软件复位
m--; //数据m -1
}
if(key2==4) //k4按键按下两秒以上 ,注意key2不需要清零,key1必须清零!!!
{
if(ms2>2000&&ms2%500==0) m=m-10; //长按k4两秒以上每隔500ms,ms2是毫秒变量,需要放在定时器1ms中断中自加,ms2++;
}
else ms2=0;//复位
//下面是完整程序代码:
#include "stc8.h"
#include "intrins.h"
#define u8 unsigned char
#define u16 unsigned int
sbit k1=P0^0;//按键1,四个按键可以是任意I/O口。按键按下时k1=0,按键释放k1=1
sbit k2=P0^1;//按键2
sbit k1=P0^2;//按键3
sbit k1=P0^3;//按键4
sbit LED1=P1^0;//LED1
//u8 key1[4];//按键变量数组,4个按键互不影响,如果用key1,一次只能够按一个按键,不允许同时按键。
u8 key1;//按键变量1,输出按键单击,长按。每单击或长按一次只输出一次,由调用函数清零。//key1=1/2/3/4是对应的按键单击,key1=10、20、30、40是对应的按键长按。key1=0表示没有按键按下。
//key1主要用途是:判断某一个按键是单击还是长按.注意调用函数需要将key1清零!!!
//u8 key2[4];//按键变量数组,4个按键互不影响,如果用key2,一次只能够按一个按键,不允许同时按键。
u8 key2;//按键变量2,输出按键单击,每10ms输出一次,key1=1/2/3/4是对应的按键单击。
//key2主要用途是:长按按键时快速增加或减少数值。
u16 ms1,ms2;//毫秒计时
u16 m;//
void key() //按键处理模块,需要放在10ms中断中运行!!!
/* 说明:1、按键单击,指按下100-1000ms内释放,加入时间限制是为了防止干扰。
2、按键长按,指按下3-10s内释放,加入时间限制是为了防止干扰。
3、函数运行后,按键值保存在key1、key2。用户直接调用key1、key2即可。
*/
{
//静态变量,必须要static
u16 static kgr[4]; //必须要static,抗干扰时间数组
u8 static kanggr[4]; //中间变量1
u8 static anjtem[4]; //按键释放中间变量。
u8 i;
u8 L_anj[4];
L_anj[0]=k1;
L_anj[1]=k2;
L_anj[2]=k3;
L_anj[3]=k4;
for(i=0;i<3;i++) //4个按键处理,key1,
{
if(L_anj[ i]==0) //按键按下
{ if(kanggr[ i]==0) //中间变量1,与下面互锁
{ kgr[ i]=0; //抗干扰时间清零,每次按键只写1次。
kanggr[ i]=1; //中间变量1
anjtem[ i]=1; //按键释放中间变量。与下面互锁
}
if(anjtem[ i]==1)
{
kgr[ i]++;//10毫秒计时。
if(kgr[ i]>1000) //按键按下大于10秒,强制复位,防止误按。
{ anjtem[ i]=0; //按键释放中间变量。与上面互锁
kgr[ i]=0;
// key1[ i]=0;//数组,4个按键独立
}
}
}
else //按键释放
{ kanggr[ i]=0; //中间变量1,与上面互锁
if(kgr[ i]>9&&kgr[ i]<99) //按键间隔100--1000毫秒才有效,防止电磁干扰。时间可以修改
key1=i+1; //单击,按键间隔100--1000毫秒,每次释放只写1次。一次只能够按一个按键,不允许同时按键。
//key1[ i]=i+1;//数组,4个按键独立
else if(kgr[ i]>300&&kgr[ i]<1000) //按键间隔3000--10000毫秒才有效,防止电磁干扰。时间可以修改
key1=(i+1)*10;//长按,按键间隔3--10秒,每次释放只写1次。
//key1[ i]=(i+1)*10;//数组,4个按键独立
}
}
//下面是处理:key2是有按键按下就输出键值。
for(i=0;i<3;i++)
{ if(L_anj[ i]==0)
key2=i+1;//一次只能够按一个按键,不允许同时按键。
//key2[ i]=i+1;//数组,4个按键独立.
}
}
void timer0() interrupt 1 //计时器T0中断1ms。
{
//静态变量,必须要static
u8 static time=0; //毫秒变量。
time++;//毫秒计时。
if(time>9) //10ms运行一次按键处理函数,不需要防抖程序。
{
time=0;
key();//按键处理模块,需要放在10ms中断中运行!!!
}
//下面的语句不是按键模块需要的,可以删除。
ms1++;ms2++;//毫秒计时
}
void main()
{
//1毫秒@12.000MHz,下面是STC单片机定时器0代码,如果是别的单片机请根据手册修改
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初值,1毫秒@12.000MHz
TH0 = 0xD1; //设置定时初值,1毫秒@12.000MHz
TF0 = 0; //清除TF0标志
ET0 = 1; //使能定时器中断
EA = 1; //打开总中断
TR0 = 1; //定时器0开始计时
while(1)
{
//1、k1按键按下LED1亮,再次按下LED1灭,
if(key1==1) //k1按键按下
{
key1=0;//必须软件清零!!!
LED1=~LED1;
}
//2、k2按键按下LED1亮,K2长按LED1灭,
if(key1==2) //k2按键按下
{
key1=0;//必须软件清零!!!
LED1=0; //0开1关
}
if(key1==20) //k按键长按
{
key1=0;//必须软件清零!!!
LED1=1; //0开1关
}
//3、k3按键按下LED1亮,K4按下LED1灭,
if(key1==3) //k3按键按下
{
key1=0;//必须软件清零!!!
LED1=0; //0开1关
}
if(key1==4) //k4按键按下
{
key1=0;//必须软件清零!!!
LED1=1; //0开1关
}
//4、K3按下一次,数据m 增加1,长按k3两秒以上每隔500ms数据m 增加10;K4按下一次,数据m 减少1,长按k4两秒以上每隔500ms数据m 减少10;
//m的范围:0-60000
if(key1==3) //k3按键按下
{
key1=0;//必须软件清零!!!
if(m<60000) m++; //数据m 增加1
}
if(key2==3) //k3按键按下两秒以上,注意key2不需要清零,key1必须清零!!!
{
if(ms1>2000&&ms1%500==0)
{if(m<=59990) m=m+10;} //长按k3两秒以上每隔500ms数据m 增加10,ms1是毫秒变量,需要放在定时器1ms中断中自加,ms1++;
}
else ms1=0; //复位
if(key1==4) //k4按键按下
{
key1=0;//必须软件复位
if(m>0) m--; //数据m -1
}
if(key2==4) //k4按键按下两秒以上 ,注意key2不需要清零,key1必须清零!!!
{
if(ms2>2000&&ms2%500==0)
{if(m>9) m=m-10;} //长按k4两秒以上每隔500ms,ms2是毫秒变量,需要放在定时器1ms中断中自加,ms2++;
}
else ms2=0;//复位
}
}
|