标题:
判断按钮单、双、三击,开关相应的led,编译通过,逻辑却没反应,诚心请教指点,谢谢
[打印本页]
作者:
book4e
时间:
2013-9-4 09:08
标题:
判断按钮单、双、三击,开关相应的led,编译通过,逻辑却没反应,诚心请教指点,谢谢
#include<reg51.h> //使用的是stc12c4052ad
sbit led1 = P1^7; // LED1接P1.7脚
sbit led2 = P1^6; // LED2接P1.6脚
sbit led3 = P1^5; // LED3接P1.5脚
sbit led4 = P1^4; // LED4接P1.4脚
sbit button = P1^0; // 按钮接P1.0脚
void s(unsigned int a) 、// 延时函数
{
unsigned char i,j;
for(i=0;i<a;i++)
for(j=0;j<600;j++);
}
void main(void)
{
unsigned char key=0; //按钮状态判断变量
led1=led2=led3=led4=1; //led初始均为关闭
button=1; //按钮初始化为按下
while(1){
if(button==0){
key+=1; //单击key值为1
s(20);
if(button==0){
key+=1; //双击key值为2
s(20);
if(button==0){
key+=1; //三击key值为3
s(20);
if(button==0){
key+=1; //四击key值为4
s(20);
if(button==0){
key+=1; //长按key值为5
s(100);
while(button==0);
}
}
}
}
}
switch(key){ //根据key值开关相应引脚的led灯
case 1:
led1=~led1;
break;
case 2:
led2=~led2;
break;
case 3:
led3=~led3;
break;
case 4:
led4=~led4;
break;
default:
break;
}
}
}
作者:
admin
时间:
2013-9-4 12:25
你应该要做一下消抖处理
作者:
liuzhaoxin1020
时间:
2017-1-8 16:09
消抖处理一下
作者:
lids
时间:
2017-1-11 11:15
这样写可以做到按一次亮一个灯,按第5次,灯全灭
#include<reg52.h>
sbit led1 = P1^7; // LED1接P1.7脚
sbit led2 = P1^6; // LED2接P1.6脚
sbit led3 = P1^5; // LED3接P1.5脚
sbit led4 = P1^4; // LED4接P1.4脚
sbit button = P1^0; // 按钮接P1.0脚
void delay(unsigned char ms)// 延时函数
{
unsigned char i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void main(void)
{
unsigned char key=0; //按钮状态判断变量
//led1=led2=led3=led4=1; //led初始均为关闭
button=1; //按钮初始化为按下
while(1){
if(button==0)
{
delay(30);
if(button==0)
{
key++;
while(button==0);
}
}
switch(key){ //根据key值开关相应引脚的led灯
case 1:
led1=0;
break;
case 2:
led2=0;
break;
case 3:
led3=0;
break;
case 4:
led4=0;
break;
case 5:
led1=led2=led3=led4=1;
break;
default:
break;
}
}
}
作者:
lids
时间:
2017-1-11 11:24
//按1次亮1个灯,按4次4个灯全亮,按第5次,灯全灭,如此循环;仿真通过
#include<reg52.h>
sbit led1 = P1^7; // LED1接P1.7脚
sbit led2 = P1^6; // LED2接P1.6脚
sbit led3 = P1^5; // LED3接P1.5脚
sbit led4 = P1^4; // LED4接P1.4脚
sbit button = P1^0; // 按钮接P1.0脚
void delay(unsigned char ms)// 延时函数
{
unsigned char i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void main(void)
{
unsigned char key=0; //按钮状态判断变量
//led1=led2=led3=led4=1; //led初始均为关闭
button=1; //按钮初始化为按下
while(1){
if(button==0)
{
delay(30);
if(button==0)
{
key++;
while(button==0);
if(key==6)
{key=0;}
}
}
switch(key){ //根据key值开关相应引脚的led灯
case 1:
led1=0;
break;
case 2:
led2=0;
break;
case 3:
led3=0;
break;
case 4:
led4=0;
break;
case 5:
led1=led2=led3=led4=1;
break;
default:
break;
}
}
}
作者:
lids
时间:
2017-1-11 14:03
//按1次亮1个灯,按4次4个灯全亮,按第5次,灯全灭,如此循环
#include<reg52.h>
sbit led1 = P1^7; // LED1接P1.7脚
sbit led2 = P1^6; // LED2接P1.6脚
sbit led3 = P1^5; // LED3接P1.5脚
sbit led4 = P1^4; // LED4接P1.4脚
sbit button = P1^0; // 按钮接P1.0脚
void delay(unsigned char ms)// 延时函数
{
unsigned char i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void main(void)
{
unsigned char key=0; //按钮状态判断变量
//led1=led2=led3=led4=1; //led初始均为关闭
button=1; //按钮初始化为按下
while(1){
if(button==0)
{
delay(30);
if(button==0)
{
key+=1;
while(button==0);
if(key==6)
key=0;
}
}
switch(key){ //根据key值开关相应引脚的led灯
case 1:
led1=0;
break;
case 2:
led2=0;
break;
case 3:
led3=0;
break;
case 4:
led4=0;
break;
case 5:
led1=led2=led3=led4=1;
break;
default:
break;
}
}
}
作者:
sdbzwhh
时间:
2017-1-11 20:57
顶ing一个
作者:
光翟11
时间:
2017-1-12 15:54
单击,双击,长按
/***********************************************************************************************************
程序的功能:一个按键的单击,双击,长按。三种按键方式,然后做不同的处理。这里就以P1口LED灯变化作为测试。
单击:点亮P1口上第一个LED灯。(低电平点亮)
双击:点亮P1口上第二个LED灯。(低电平点亮)
长按:长按:点亮P1口上的8个LED灯。(低电平点亮)
使用方法:
硬件的连接:P2.0作为按键的输入,P1口作为LED显示,连接好后,直接复制粘贴生成HEX文件,烧写进C51就能用。
************************************************************************************************************/
#include<reg51.h>
#define N_key 0 //无键
#define S_key 1 //单键
#define D_key 2 //双键
#define L_key 3 //长键
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
sbit key_input = P2^0; // 按键输入口
unsigned char time_10ms_ok = 0;
unsigned char key = 0;
unsigned char key_driver(void)
{
static unsigned char key_state = key_state_0, key_time = 0;
unsigned char key_return = N_key;
bit key_press;
key_press = key_input; // 读按键I/O电平
switch (key_state)
{
case key_state_0: // 按键初始态
if (!key_press) key_state = key_state_1; // 键被按下,状态转换到按键消抖和确认状态
break;
case key_state_1: // 按键消抖与确认态
if (!key_press)
{
key_time = 0; //
key_state = key_state_2; // 按键仍然处于按下,消抖完成,状态转换到按下键时间的计时状态,但返回的还是无键事件
}
else
key_state = key_state_0; // 按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的。
break;
case key_state_2:
if(key_press)
{
key_return = S_key; // 此时按键释放,说明是产生一次短操作,回送S_key
key_state = key_state_0; // 转换到按键初始态
}
else if (++key_time >= 100) // 继续按下,计时加10ms(10ms为本函数循环执行间隔)
{
key_return = L_key; // 按下时间>1000ms,此按键为长按操作,返回长键事件
key_state = key_state_3; // 转换到等待按键释放状态
}
break;
case key_state_3: // 等待按键释放状态,此状态只返回无按键事件
if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态
break;
}
return key_return;
}
/*=============
中间层按键处理函数,调用低层函数一次,处理双击事件的判断,返回上层正确的无键、单键、双键、长键4个按键事件。
本函数由上层循环调用,间隔10ms
===============*/
unsigned char key_read(void)
{
static unsigned char key_m = key_state_0, key_time_1 = 0;
unsigned char key_return = N_key,key_temp;
key_temp = key_driver();
switch(key_m)
{
case key_state_0:
if (key_temp == S_key )
{
key_time_1 = 0; // 第1次单击,不返回,到下个状态判断后面是否出现双击
key_m = key_state_1;
}
else
key_return = key_temp; // 对于无键、长键,返回原事件
break;
case key_state_1:
if (key_temp == S_key) // 又一次单击(间隔肯定<500ms)
{
key_return = D_key; // 返回双击键事件,回初始状态
key_m = key_state_0;
}
else
{ // 这里500ms内肯定读到的都是无键事件,因为长键>1000ms,在1s前低层返回的都是无键
if(++key_time_1 >= 50)
{
key_return = S_key; // 500ms内没有再次出现单键事件,返回上一次的单键事件
key_m = key_state_0; // 返回初始状态
}
}
break;
}
return key_return;
}
void main()
{
P1 = 0xff; //IO口初始化
P2 = 0xff;
//定时器的初始化
TMOD = 0x01; //选择定时器的工作模式:定时器0,方式1
TH0 = (65535 - 10000)/256; //定时器的初值
TL0 = (65535 - 10000)%256;
EA = 1; //开打总中断使能
ET0 = 1; //打开定时器0 的使能
TR0 = 1; //打开定时器0 ,开始工作
while(1)
{
if(time_10ms_ok) //time_10ms_ok = 1,表示计时到了10MS。(10MS扫描一次按键)
{
time_10ms_ok = 0; //清除计时10MS标志
key = key_read(); //调用扫描按键程序,返回一个键值
if (key == L_key) //长按:点亮P1口上的8个LED灯。(低电平点亮)
{
P1 = 0x00;
}
else if(key == D_key)//双击:点亮P1口上第二个LED灯。(低电平点亮)
{
P1 = 0xfd;
}
else if(key == S_key)//单击:点亮P1口上第一个LED灯。(低电平点亮)
{
P1 = 0xfe;
}
}
}
}
void timer0(void) interrupt 1 //用的是定时器0, 这个“interrupt 1”中的“1”代表1号中断即是定时器0中断。如果是“0”就是外部中断0;“2“=外部中断1;”3“定时器1中断;”4“=串行口中断
{
TH0 = (65535 - 10000)/256;
TL0 = (65535 - 10000)%256; //定时器0的方式1,得在中断程序中重复初值。
time_10ms_ok = 1; //定时10MS 的标志
}
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1