1. 51单片机如何实现按键的长按与短按功能,尝试过很多方法都不行,请高手多赐教,多谢了(想是简单,做是难)
这个真心不难,就是简单的c语言判定就行了,《C程序设计语言》,实在看不了就看谭总写的那本c语言。给你写过伪代码,
if(key=ReadKey())//读取按键,判断有无按键按下去,没按键按下,这里返回0值是不进入这个函数的
{
delay(x);//延时一段时间,写过循环就行了
if(!ReadKey())//在次读取按键值,实际上按下去按键是低电平(原理图一般都是这样做的)
{
return 已经松手了( 这里是高电平了返回0了)
2. 在51单片机中,按一下按键1,执行一个程序功能1,按按键2,执行程序功能2
#include<reg51.h>
#include<intrins.h>
unsigned char fun,led1=0xfe,led2=0x55;
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
void t0isr() interrupt 1
{
TH0=(65536-60000)/256;
TL0=(65536-60000)%256;
switch(fun)
{
case 1:P0=led1;led=_crol_(led1,1);break;
case 2:P0=led1;led=_cror_(led1,1);break;
case 3:P0=~led2;break;
default: break;
}
}
main()
{
TMOD=0x01;
TH0=(65536-60000)/256;
TL0=(65536-60000)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(key1==0)
{
while(key1==0);
fun=1;
}
if(key2==0)
{
while(key2==0);
fun=2;
}
if(key3==0)
{
while(key3==0);
fun=3;
}
}
}
3. 单片机按键按一次就加一
按键相对是个低速任务。你按的再快,一秒可以按十次吗?什么?你可以。。那你就是作弊了。因为哪怕你反应的过来。按键可不行。所以。这个本质你需要牢牢抓住。那么你可以选择一秒之内只检测几次按键。把几乎是连续在使用的机器时间碎片化。比如在一个碎片里只查一次按键。是的,你现在就是这么做的。只是循环太快。碎片太多。按键的抖动你都查到了。所以你需要的仅仅是慢下来。极限就是刚刚说的查10次。算算,这是一个100ms的定时。明白定时器的真正用途了吗?如果你实际这么实验了你会发现这的确有效。不会加个成百上千了。接下来你需要设置一个逻辑让按键检测只对下降沿起作用。最好的办法就是和前次的状态比较。如果上次的状态为高而此次状态为低。那么这就是个下降沿。于是你需要一个寄存器保存上一次的状态。并每次比较后更新。原来这寄存器是这么用的。。实际实验后发现这么干已经可以保证基本每次长按只会加1。但是短按似乎会丢失。那是因为。100ms实在是长了些。电平保持100ms有时是太难了。所以,你可以适当提高频率。比如提高10倍。以10ms为周期。基本能解决大多数问题。
4. 如何用单片机实现单击 + 双击 + 长按
这是三种键有效方法,可按下面思路设计供你参考;
1、单击有效,可以采用弹起有效。如选择上升沿有效。
2、双击有效,要采用在一定的定时时间内两次计数的方法,也就是先设定一个有效时间,在第一次键有效后在这个有效时间内键再次有效就可以认定最终有效,否则无效。
3、长按有效,也要采用计时的方法。也就是键有效后在一定的时间内连续检测有效性,如检测时间内连续保持有效可以认定最终有效,否则无效。
后两种方法要求设计一个专门的判断程序才能完成。
5. 单片机 一个按钮设置按一下加1 另一个按键按一下减1 求帮忙编写程序
#include<reg52>
#define uchar unsigned char
#define uint unsigned int
sbit K1 = P1^4;
sbit K2 = P1^5;
uchar data K1state;
uchar data K2state;
uint data num,ntmp;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x06f,0x77,0x7c,0x39,0x5e,0x79,0x71} ;
uchar data showIndex,indexTmp;
uchar data W[8];
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);//能使之延时接近1毫秒就成 无需精确
}
void main()
{
K1state = 0xFF;
K2state = 0xFF;
num = 0;
while(1)
{
delay(1);//每毫秒轮询一回
//移位法,延时防抖
K1state = (K1state<<1);
K2state = (K2state<<1);
if(K1) K1state++;
if(K2) K2state++;
//检查开关状态
if(K1state==0x80) num++;
if(K2state==0x80) num--;
for(indexTmp=0,ntmp = num;indexTmp<=7;indexTmp++)
{
W[indexTmp] = num%10;
num /=10;
}
P0 = (0x01<<showIndex);//位选
P2 = table[W[showIndex]];//段选
showIndex++;
if(showIndex>=8)
showIndex=0;
}
}
看了你的全图,修改后了,用Keil uVision 3或4都可以,编译后可以查看对应的汇编代码
程序稍大一点的,不会有人用汇编来给你蘑菇,汇编设计写编码太慢了,开发代价不值得
6. 单片机按键有几种方式
按键检测一般有:1、查询、2、扫描、3中断等方式。查询方式占用主循环资源,就是说主程序主要干检测按键的活儿,若增加其他程序容易出错。扫描方式效果最好,可以在性能和占用资源间平衡,中断方式,适用于响应速度极高的场景,但抗干扰较差。
7. 51单片机按键
#include<reg51.h>
#define uchar unsigned char
uchar num,time,limit=2;
sbit led1=P1^0;
sbit key1=P2^0;
bit flag=0;
void t0isr() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
time++;
if(time>=60)
{
TR0=0;
time=0;
flag=1;
}
}
void t1isr() interrupt 3
{
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
num++;
if(num>limit)
{
num=0;
led1=~led1;
}
}
main()
{
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
ET0=1;
ET1=1;
EA=1;
while(1)
{
if(key1==0)
{
time=0;
num=0;
TR1=1;
TR0=1;
flag=0;
while(key1==0);
if(flag==1)limit++;
}
}
}
8. 单片机按键短按和长按的程序
不能给你程序,只能给你思路。
设置定时器(建设100ms),在设置一个变量x,(100ms自加1)
在主循环中判断按键是否按下,并判断x的值大小;
假设 x每隔100ms加1
y是按键状态(为1表示按下,为0 表示未按)
z记录按键状态的(初始值0)
b 记录长安 a记录短按
eg:
if(!z)
{
if(y)
{
a=1;
z=1;
}
}
else if(x>10)// 1s
{
b=1;
}
9. 51单片机按位与
a=a&0xf0;也就相当于a=0;,它这样写是给P3^5清零或者置0的作用。
10. 51单片机独立按键中,按一下和一直按的区别
按一下松开这个LED一直亮:
if(key==0)
{
while(key==0);
led=0;
}
按一下松开就亮一下:
if(key==0)
{
led=0;
while(key==0);
led=1;
}