l09046162 发表于 2011-10-9 22:20:56

mark!!!以后看!!!!谢谢楼主分享!!!!

lihuyong 发表于 2011-10-9 22:59:58

马克了再细看

love_zjb 发表于 2011-10-9 23:01:27

mark

ljmdzyx 发表于 2011-10-10 00:17:33

手机马克

BG4RFF 发表于 2011-10-23 00:27:16

http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4747117&bbs_page_no=1&search_mode=3&search_text=BG4RFF&bbs_id=9999
原来我是罪魁祸首

henry 发表于 2011-10-23 00:40:58

mark

asj1989 发表于 2011-10-29 09:51:35

好东西很好用

zzjxfc 发表于 2011-10-30 21:28:08

很受教育,看来做什么都不能浮躁啊

ylei12 发表于 2011-10-30 22:05:18

马老师又开讲了,顶

yulongkui 发表于 2011-10-31 00:19:39

用过类似的思路写按键处理

mdj-fish 发表于 2011-10-31 07:23:28

思路写按键处理

wers_l 发表于 2011-10-31 08:18:13

小知识有学问,MARK

gameboy22 发表于 2011-10-31 09:34:29

这个要几号一下,发现状态机很好用哈~

summerrain19 发表于 2011-11-3 08:16:12

不知道有没有人用这个做多个按键,单击+长按+组合键写,我最近写了一个,感觉效果不是很好,按键多按几次有时会失效(只加入了单击+长按),实时效不好,还有一个问题,就是当返回按键的时候你的按键值取值的位置应该放在哪里比较好,当你返回长短按键时按键是释放的,我做的也是每10ms扫描一次,还有一个就是感觉代码比较繁琐!

ideadz 发表于 2011-11-3 08:52:01

谢谢马老师!学习了

jyjmaster 发表于 2011-11-3 09:15:51

谢谢。

jacky82512 发表于 2011-11-4 11:05:53

这个帖子还在火?

lsy_forever 发表于 2011-11-4 12:53:50

Mark~

chenxiangyy715 发表于 2011-11-4 13:05:20

mark

sunicecream 发表于 2011-11-4 15:45:25

很好很强大

Eangle 发表于 2011-11-13 14:27:36

挺实用的,先mark

6488904 发表于 2011-11-22 23:33:12

经典,谢谢马潮老师

kingboy100 发表于 2011-11-23 08:54:38

mark

redzhch 发表于 2011-11-29 14:02:10

mark。不仅内容很精彩,格式也是相当标准,学习。

hz77776666 发表于 2011-11-29 15:05:03

mark

xin_71 发表于 2011-12-4 11:20:51

新手,学习了

henry 发表于 2011-12-11 15:57:00

mark

fythsg 发表于 2011-12-11 18:33:32

技术外的观点也很有见地

wjshmily 发表于 2011-12-13 11:12:50

马老师的书最近在看,这个很不错!留下脚印

zhoushilang 发表于 2011-12-16 16:52:21

回复【楼主位】machao
-----------------------------------------------------------------------

最近正在学习按键使用和去抖动方面的知识,老师的资料很好,很有参考和学习价值谢谢老师。

yyt1372 发表于 2011-12-20 18:23:49

很精彩!

zhongjun 发表于 2011-12-24 13:34:57

回复【楼主位】machao
-----------------------------------------------------------------------

MArk

taocongrong 发表于 2011-12-25 10:50:59

太经典了,真是好东西,简介 稳定!

flyforyou85 发表于 2011-12-28 15:06:19

好好看看,谢谢马老师!

382383706 发表于 2011-12-28 22:58:20

mark

yhy630 发表于 2012-1-1 18:43:48

好好看看,谢谢马老师!

abcabc2356 发表于 2012-1-4 22:05:24

获取按键输入,有多种状态,马克

njchenmin 发表于 2012-1-5 07:05:59

不错,标记一下

BCE312 发表于 2012-1-17 00:54:09

思考、实践,转换成自己的东西! 加油

justSaar 发表于 2012-1-17 11:01:47

多功能按键设计 MARK

jjj2012 发表于 2012-1-24 21:47:55

马克

saymeok 发表于 2012-1-28 15:07:30

俺是初学者,很想知道马老师楼主位的程序是适合GCC还是ICC?

说来惭愧,俺改了一下,无论用ICC还是GCC运行,报错好多。

saymeok 发表于 2012-1-29 16:58:18

AVR编译软件还真多,就是不通用,CodeVisionAVR,勤翻书有好处,第九章。

davidd 发表于 2012-1-29 17:27:46

mark

duduqiuhan 发表于 2012-2-17 11:29:21

不错,收益了!

fuzengyue 发表于 2012-2-17 12:07:54

mark

mysignal 发表于 2012-2-17 13:27:35

mm

xiaohong.zhang 发表于 2012-2-21 16:38:21

在这边看马潮的帖子 半年来真的学到好多东西

AASUN 发表于 2012-2-22 10:19:19

很好用!

coole 发表于 2012-2-22 12:54:55

mark

B214215850 发表于 2012-3-26 12:47:58

学习了!

Forever 发表于 2012-3-26 13:28:34

mark。不错的帖子

sweet_146 发表于 2012-3-27 16:41:33

markmark mark mark

wangqun 发表于 2012-3-28 14:25:57


很好用!mark

polun2011 发表于 2012-3-28 14:31:34

mark,,,,,,,,

size327948964 发表于 2012-4-1 13:58:57

学习一下

GZZXB 发表于 2012-4-6 08:23:34

学习了!

xyz2008 发表于 2012-4-6 09:35:22

http://www.ourdev.cn/forum.php?mod=viewthread&tid=4308630&highlight=%E6%8C%89%E9%94%AE
这个似乎比马老师的更经典,更有技巧

cumtgao 发表于 2012-4-6 15:30:12

受教了,同LS。

b260123292 发表于 2012-4-6 17:05:35

还好我一般都是需要短按与长按的事件,双击是一个需要取舍的事情。

mcujack 发表于 2012-4-13 14:05:32

看了帖子觉得很惭愧,原来自己最简单的东西都没做好

382383706 发表于 2012-4-17 13:54:06

有时间看看!

xuanke 发表于 2012-4-17 14:59:22

嗯,谢谢老师

fyy 发表于 2012-5-1 17:39:30

先Mark一下,稍后学习了

蔡锦源 发表于 2012-5-3 12:20:50

在某个空间看到了这篇文章,觉得写得很复杂,变量定义得太长不好理解,所以用STC89C52做了测试,可正常工作,和要求一样。
每10MS扫描一次用到了定时器2的16位自动重装方式。一共有4个状态。P2口接LED作为显示用
#include<reg52.h>
unsigned char delay=0;
sbit key=P3^5;
void init();
main()
{
unsigned char lp=0,time=0,num=0,flag=0,value=0;
init();
while(1){
if(delay){
delay=0;
switch(lp)
{
case 0:if(!key)lp++;else if(flag){if(++time>50){value=1;time=0,flag=0;}}break;
case 1:if(!key)lp++;else lp=0;break;
case 2:if(key){lp++;if(flag){value=2;flag=0;}else flag=1;}else if(++num>100){flag=0;value=4;lp++;}break;
case 3:if(key){lp=0;num=0;time=0;}break;
}
}
P2=~value;
}
}

void init()
{
EA=1;
RCAP2H=55536/256;
RCAP2L=55536%256;
TH2=RCAP2H;
TL2=RCAP2L;
ET2=1;//开启定时器2中断
TR2=1;//启动定时器

}
void timer()interrupt 5
{
TF2=0;
delay=1;
}

如果要实现和手机英文输入一致,则把4个状态改成如下:
case 0:if(!key)lp++;else if(flag){if(++time>50){time=0,flag=0;}}break;
case 1:if(!key)lp++;else lp=0;break;
case 2:if(key){lp++;if(flag)value=(value)%4+1; else {value=1;flag=1;}}else if(++num>100){flag=0;value=4;lp++;}break;
case 3:if(key){lp=0;num=0;time=0;}break;

yuandzyx 发表于 2012-5-25 22:46:09

马老师看了你的多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。 我个人感觉程序写得有点庞大。而且在通用应用中双击用得不多。单击和长按道是用得很频繁。下面示出我常用的一段精点按键函数供大家探讨一下。关于此按键的算法的出处也是从一个网站博客中看到的,具体地址不太清楚了。

yuandzyx 发表于 2012-5-25 23:06:22

程序如下:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Chip type         : ATmega8L
*****************************************************/
#include <mega8.h>

#define KEY_MODE 0x08    // 模式按键PB3
#define KEY_ADD 0x10      // 加   PB4
#define KEY_SUB 0x20       // 减   PB5
unsigned char Trg=0;
unsigned char Cont=0;
//按键扫描处理程序
void KeyProcess(void)
{
//PORTC=0x07;在主程序初始化段设置PC口低三位上拉电阻有效 DDRC=0x00;设置PC口输入模式
unsigned char ReadData=~PINC;       //读PC口并将数据取反
Trg=ReadData&(ReadData^Cont);   //判断是否点动即单击
Cont=ReadData;                           //判断是否长按

if(Trg&KEY_ADD)                           //加键单击时Dis_Vale加1
{
   if(Dis_Vale<=65535)
   Dis_Vale++;
    }

   if(Trg&KEY_SUB)                        //减键单击时Dis_Vale减1
   {
   if(Dis_Vale>=1)
   Dis_Vale--;
   }                                          
   
}
以上只举例说明了单击的情况,其实长按键程序依据上面按键的工作原理分析也很容易得出。
此程序的优势在于实时性很好,程序没有延迟的地方。

yuandzyx 发表于 2012-5-25 23:09:53

下面是我用一个MEGA8+AD420做的一个信号发生器的程序,里面也有用到按键函数部份。
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
Project :
Version :
Date    : 2011-6-12
Author:
Company :
Comments:
Chip type         : ATmega8L
Program type      : Application
Clock frequency   : 4.000000 MHz
Memory model      : Small
External RAM size   : 0
Data Stack size   : 256
*****************************************************/
#include <mega8.h>
#include <delay.h>
#include <lcd.h>
#include <spi.h>
#asm
.equ __lcd_port=0x12 ; PORTD数据寄存器地址
#endasm

#define KEY_MODE 0x08    // 模式按键PB3
#define KEY_ADD 0x10   // 加   PB4
#define KEY_SUB 0x20   // 减   PB5

unsigned char Trg=0;
unsigned char Cont=0;
char str={'0','1','2','3','4','5','6','7','8','9'};
int dis_buff={0,0,0,0,0,0};
int dis_buff2={0,0,0,0,0,0};
int dis_buff3={0,0,0,0,0,0};
int dis_bufft={0,0,0};
unsigned int Dis_Vale=800;
unsigned char T_vale=0;
unsigned char T_valeb=0;
bit KEY_MODE_ST=1;
unsigned char Dis_outmv_Date=1;

unsigned long BuffDate=0;
unsigned long BuffDate1=0;    //N次采样数累加暂存地址空间
bit ZhuanHuanOKBZ=0;          //N次采样OK标志值
unsigned char ADC_BZ=0;       //ADC转换状态标志
int ZhuanHuanCS=0;            //具体采样的次数
unsigned int OKdata=0;          //转换OK的输入信号值
unsigned int OKdata1=0;          //转换OK的输入信号值
int DateLV=2937;            //ADC量程系数5V等于5000FLUCK表实测Vref 2.937 V
int DateXZ=0;

//手动给定数值显示
void PrintLCD_int(unsigned int adc)               
{
char i,ii;
for (i=0;i<=5;i++)
{
dis_buff=adc % 10;
adc /= 10;
}
//换成字符形式方便于LCD显示
for (ii=0;ii<=4;ii++)
{
lcd_gotoxy(ii+10,0);   //去LCD第二行第0列显示百位数
lcd_putchar(str]);
      
}
}

//手动给定值显示函数
void PrintLCD_short(unsigned char ad)
{
char i1;
   for (i1=0;i1<=1;i1++)
{
dis_bufft=ad % 10;
ad /= 10;
}
//换成字符形式方便于LCD显示
lcd_gotoxy(2,0);   
lcd_putchar(str]);
lcd_putchar('.');
lcd_putchar(str]);
}

//ADC 转换中断服务程序
interruptvoid adc_m8(void)
{
    unsigned int adc_data;
    adc_data=ADCW;                               //读取ADC置换结果
    BuffDate1=(unsigned long)adc_data+BuffDate1; //第一步 将过采样数据进行累加
    ++ZhuanHuanCS;   
    if(ZhuanHuanCS>=255)                         //判断N次的采样
    {
   ZhuanHuanCS=0;
   BuffDate=BuffDate1;
   BuffDate1=0;
   ZhuanHuanOKBZ=1;
   ADC_BZ++;   
    }
}

//第一路输出电流AD采样数据显示
void PrintLCD_intAD0(unsigned int adc)               
{
char i;
adc=(unsigned int)(20000/2000)*adc;    //2V对应20mA转换函数
for (i=0;i<=4;i++)                        
{
dis_buff2=adc % 10;
adc/= 10;
}
//换成字符形式方便于LCD显示
lcd_gotoxy(9,1);   //去LCD第二行第0列显示百位数
lcd_putchar(str]);
lcd_putchar(str]);
lcd_putchar('.');
lcd_putchar(str]);
lcd_putchar(str]);
lcd_putchar(str]);   
}
//第二路输出电压AD采样数据显示
void PrintLCD_intAD1(unsigned int adc)               
{
char i;
adc=adc*2;         //将采样的数据放大2倍。因为硬件上通过放大器将采样信号衰减2倍
for (i=0;i<=3;i++)
{
dis_buff3=adc % 10;
adc /= 10;
}
//换成字符形式方便于LCD显示
lcd_gotoxy(2,1);   //去LCD第二行第0列显示百位数
lcd_putchar(str]);
lcd_putchar('.');
lcd_putchar(str]);
lcd_putchar(str]);
lcd_putchar(str]);   
}

//按键扫描处理程序
void KeyProcess(void)
{
//PORTC=0x07;在主程序初始化段设置PC口低三位上拉电阻有效 DDRC=0x00;设置PC口输入模式
unsigned char ReadData=~PINC; //读PC口并将数据取反
Trg=ReadData&(ReadData^Cont); //判断是否点动
Cont=ReadData;                //判断是否长按
if(Trg&KEY_MODE)
{
   KEY_MODE_ST=~KEY_MODE_ST;
   lcd_gotoxy(15,0);   //去LCD第二行第0列显示百位数
   if(KEY_MODE_ST)
   lcd_putchar('+');
   else
   lcd_putchar('-');
}
if(Trg&KEY_ADD)
{
   if(KEY_MODE_ST)
    {
   if(Dis_Vale<=64223)
   {
   Dis_Vale=Dis_Vale+1305;
   Dis_outmv_Date++ ;
   }
    }
    else
    {
   if(Dis_Vale>=1312)
   {
   Dis_Vale=Dis_Vale-1305;
   Dis_outmv_Date--;
   }
    }
}   
   if(Trg&KEY_SUB)
   {
   if(KEY_MODE_ST)
    {
   if(Dis_Vale<=65534)
   Dis_Vale=Dis_Vale+2;
   }
    else
    {
   if(Dis_Vale>=2)
   Dis_Vale=Dis_Vale-2;
   }
    }   
}

//SPI主机初始化函数
void SPI_MasterInitY(void)
{
DDRB=0x2C;   //SPI接口SCK PB7设置成输出,SPI接口MOSI PB5设置成输出,SPI接口SS PB4设置成输出。其它设置成输入                     
PORTB=0x00;   
SPCR=0b01010001; //SPI控制寄存器SPCR的第6位SPE设置成1 第4位MAST主从选择设置成1为主方式 第0位为1表示SCK分频系数为什16
}                                 
//SPI主机发送数据函数
void SPI_MasterTransmitY(unsigned char T_Data)
{
SPDR=T_Data;         // 向SPI数据寄存器SPDR赋需要传送的值
while(!(SPSR&0x80))//判断SPI发送数据有没有结束如果结束SPSR状态寄存器的第7位SPIF则为1否则则等待
{};
}

void SPI_TransmitY(unsigned int TrData)
{
unsigned char a,b;
a=TrData/256;
b=TrData%256;
PORTB&=0xFB;            //将SPI接口SS PB4置0完成16位数据传
SPI_MasterTransmitY(a); //先传输高8位
SPI_MasterTransmitY(b); //再传输低8位从而组成AD420所需的16位数据
PORTB|=0x04;
}
               
void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
PORTB=0x43; //设置PB6,PB1,PB0上拉电阻有效 且为输入模式
DDRB=0x00;
PORTC=0xFC;
DDRC=0x00;
PORTD=0x00;
DDRD=0xFF;   //设置PD口为液晶显示器输出接口
// Timer/Counter 0 initialization
TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
ADMUX=0b00000000;
ADCSRA=0b11101110;

ACSR=0x80;
SFIOR=0x00;
lcd_init(16);       //LCD显示器的初始化
SPI_MasterInitY();//SPI通讯初始化
lcd_gotoxy(15,0);
if(KEY_MODE_ST)
lcd_putchar('+');
else
lcd_putchar('-');
#asm("sei") //开中断
while (1)
      {
      lcd_gotoxy(0,0);
      lcd_putsf("U:"); // display the message
      lcd_gotoxy(5,0);
      lcd_putsf("00V");
      lcd_gotoxy(0,1);
      lcd_putsf("o:");
      lcd_gotoxy(7,1);
      lcd_putsf("V");
      lcd_gotoxy(14,1);
      lcd_putsf("mA");                  
      if(T_valeb>=20)
      {
       KeyProcess();
       PrintLCD_int(Dis_Vale);
       PrintLCD_short(Dis_outmv_Date);
       SPI_TransmitY(Dis_Vale);
       }
      if(T_vale>=25)
      {
      T_vale=0;
      DDRD=DDRD|0b00001000;
      PORTD.3=~PORTD.3;
      }
       T_vale++;
      T_valeb++;
      
      if(ZhuanHuanOKBZ)
       {
      #asm("cli") //开中断
       ADCSRA=ADCSRA&0b01111111;       //停ADC转换
       ZhuanHuanOKBZ=0;                //清除标志位
       BuffDate=BuffDate/16;         //第二步将N次采样的累积数据右移4位
       BuffDate=BuffDate*DateLV/16384; //第三步还原14位数据精度的输入值
       if(ADC_BZ==1)
       {
         //AD转换非线性修正
         if(BuffDate>=10)
         DateXZ=4;
         else DateXZ=0;
         if(BuffDate>=150)
         DateXZ=5;
         if(BuffDate>=300)
         DateXZ=6;
         if(BuffDate>=600)
         DateXZ=7;
         if(BuffDate>=750)
         DateXZ=8;
         if(BuffDate>=2100)
         DateXZ=9;
         if(BuffDate>=2250)
         DateXZ=10;
         if(BuffDate>=2350)
         DateXZ=11;
         BuffDate=BuffDate+DateXZ;
         OKdata=(unsigned int)BuffDate;
         PrintLCD_intAD0(OKdata);      //调用adc_to_disbuffer函数将unsigned int数据类型转换成字符形式方便于LCD显示
         ADMUX=0b00000001;//采样ADC1
         
         
      }
      if(ADC_BZ==3)
      {
         //AD转换非线性修正
         if(BuffDate>=10)
         DateXZ=3;
         else DateXZ=0;
         if(BuffDate>=60)
         DateXZ=4;
         if(BuffDate>=250)
         DateXZ=6;
         if(BuffDate>=700)
         DateXZ=7;
         if(BuffDate>=1150)
         DateXZ=8;
         if(BuffDate>=1750)
         DateXZ=9;
         if(BuffDate>=2150)
         DateXZ=10;
         if(BuffDate>=2350)
         DateXZ=11;
          BuffDate=BuffDate+DateXZ;
         OKdata1=(unsigned int)BuffDate;
         PrintLCD_intAD1(OKdata1);    //调用adc_to_disbuffer函数将unsigned int数据类型转换成字符形式方便于LCD显示//调用adc_to_disbuffer函数将unsigned int数据类型转换成字符形式方便于LCD显示
         ADMUX=0b00000000;//采样ADC0
      
      
      }
      if(ADC_BZ>=4)
      ADC_BZ=0;
      
      ADCSRA=0b11101110;      //启动ADC转换
         #asm("sei") //开中断
         
      }
         
         
      };
}

yuandzyx 发表于 2012-5-25 23:11:41

写得不好的地方还请高手多多指正。

55646184@qq.com 发表于 2012-6-1 17:41:34

厉害,楼上的思路很不错,学习消化下

tzsteel 发表于 2012-6-4 19:25:31

试了一下蛮OK的,可惜只有一个按键,不知咋样改成多个按键的?

gvgvfghv 发表于 2012-6-4 20:57:27

原来我以前编写的按键检测方法叫做状态机啊

137703056 发表于 2012-6-4 23:22:25

回头去实验一下…

绿茶山人 发表于 2012-6-5 11:21:40

实际上,现在的全国大学生电子设计大赛也变成是一个浮躁的产物,学校和学生都指望它能贴金,对于真正培养和锻炼人的目的和作用,实际上只是挂在前面遮羞布了。
----------------------------------------------------------------------------------------------------------------------------------
马潮老师这话说得很实在。我们学校的电子大赛就全部是老师做的,和老师关系好的学生去挂一个名。太让人心寒了!

scp5591 发表于 2012-6-13 00:15:35

MARK !
{:smile:}

shouqiang_zhang 发表于 2012-6-13 06:18:10

mark, thanks a lot.

paradisespace 发表于 2012-6-14 16:19:57

向马老师看起!学习思想,消化成自己的,哈哈   真心感谢!

ouyj_0210 发表于 2012-6-14 17:54:13

学习啊学习了

有缘于你 发表于 2012-6-15 20:14:33

貌似程序有同类的两个错误吧,长按和双击都有问题。。

zzb1987 发表于 2012-6-20 14:39:29

mark 模仿了

功夫熊猫 发表于 2012-6-20 16:18:19

这种才是真正能运用到产品上的程序
以前按照其它51教材上按键处理办法
结果在产品上体验不好 一直怀疑是按键质量不好
现在想想真是惭愧 怪自己没认真研究和学习
感谢马老师的分享和指导!

海边狮子 发表于 2012-6-20 21:37:06

差距太大了{:cry:}{:cry:}

xuepeng 发表于 2012-6-24 16:13:53

学习了,一个按键有这么大学问,佩服

shzxy9865 发表于 2012-6-29 08:49:58

mark~~~~~~~~~~~

hls 发表于 2012-6-29 14:36:29

嗯,马老师分析的很好,学习了啊

dingshidong214 发表于 2012-7-4 22:53:04

绝对好贴mark

abclcl 发表于 2012-7-16 10:43:07

哪位大侠帮我看看这个程序啊,根据马老师书里的状态机按键程序写的,要求按键控制LED亮灭,编译没错误,就是运行不出来
#include<reg52.h>

sbit LED = P2^0;       //定义LED在P2.0脚上
char g_bSystemTime1Ms = 0 ;            
bit time_ok=0;        // 10MS系统时标

#define key_input P0^0// 按键输入口
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2

char read_key(void)
{
static char key_state=0 ;
char key_press, key_return = 0;
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_return = 1; // 按键仍按下,按键确认输出为“1”
            key_state = key_state_2;//状态转换到键释放态
         }
         else
            key_state = key_state_0;//按键已抬起,是抖动,转换到按键初始态
            break;
   case key_state_2:                                  //等待释放状态
      if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态
      break;
}
return key_return;
}
void main()
{
TMOD &= 0xf0 ;
TMOD |= 0x01 ;      //定时器0工作方式1
TH0=0xfc ;   //定时器初始值
TL0=0x66 ;
TR0= 1 ;
ET0= 1 ;
EA = 1 ;
while(1)
{
   if(time_ok==1)
    {
          time_ok=0;
          if(read_key()==1)LED = ~LED;             
   
    }       
}
}
void Time0Isr(void) interrupt 1
{
   TH0=0xfc ;      //定时器重新置始值
   TL0=0x66 ;
       if(++g_bSystemTime1Ms>=10)//1MS转换10MS
          {
                   g_bSystemTime1Ms=0;
                time_ok =1;                // 10MS系统时标
      }   
}

wuqiushan741826 发表于 2012-7-18 14:57:39

key_time 为局部变量,好像不对吧,哈哈

abclcl 发表于 2012-7-21 16:10:10

如果是多个独立按键呢,程序怎么写啊

FUESTCK 发表于 2012-7-21 23:53:01

不错 很有帮助

bwang 发表于 2012-9-13 09:19:41

记号一下,很实用.

myhonour 发表于 2012-9-13 14:12:41

必须顶,绝对好东东

ad00r 发表于 2012-9-13 23:25:47

非常好

随风过15 发表于 2012-9-15 08:43:11

来学习了   很不错

cuikai12345 发表于 2012-9-15 09:32:16

不错学习学习

mypc16888 发表于 2012-9-17 08:59:10

不错,好好学习学习

lcmdw 发表于 2012-10-15 11:11:02

mark{:smile:}

oyingzi007 发表于 2012-10-15 13:59:36

{:lol:}{:lol:}受教了。

wenming 发表于 2012-10-15 14:04:28

支持一下

kunnsd 发表于 2012-10-15 14:19:47

谢谢马老师!
页: 1 2 [3] 4 5
查看完整版本: 题目:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。