单片机实用按键模块,没有延时语句、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=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个按键独立
else key1=0; //清零。
}
}
//下面是处理: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;//复位
}
}
这是按键检测模块函数:要认真看才能够理解。
void key() //按键处理模块,需要放在10ms中断中运行!!!
/* 说明:1、按键单击,指按下100-1000ms内释放,加入时间限制是为了防止干扰。
2、按键长按,指按下3-10s内释放,加入时间限制是为了防止干扰。
3、函数运行后,按键值保存在key1、key2。用户直接调用key1、key2即可。
*/
{
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=0;
}
}
}
else //按键释放
{ kanggr[ i]=0; //中间变量1,与上面互锁
if(kgr[ i]>9 && kgr[ i]<99) //按键间隔100--1000毫秒才有效,防止电磁干扰。时间可以修改
key1=i+1; //单击,按键间隔100--1000毫秒,每次释放只写1次。一次只能够按一个按键,不允许同时按键。
else if(kgr[ i]>300 && kgr[ i]<1000) //按键间隔3000--10000毫秒才有效,防止电磁干扰。时间可以修改
key1=(i+1)*10;//长按,按键间隔3--10秒,每次释放只写1次。
else key1=0; //清零。
}
}
//下面是处理:key2是有按键按下就输出键值。
for(i=0;i<3;i++)
{ if(L_anj[ i]==0)
key2=i+1;//一次只能够按一个按键,不允许同时按键。
}
}
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|