OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13985|回复: 7

一个按键两种功能的问题

[复制链接]

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-10-11
在线时间
0 小时
发表于 2011-12-26 07:46:41 | 显示全部楼层 |阅读模式

我做了一个一个按键两种功能的程序,就是一按短时间就亮小灯,长按就亮大灯的程序,但时序时候好困难,希望帮手看看!!!

#include<pic.h>
#include "ET18F11.h"
__CONFIG(0X3044);


#define uchar unsigned char
#define uint unsigned int
uint num,num1;
 bit duan_flag,chang_flag1;
 
void delay(uint n)
{
 uint i,j;
 for(i=n;i>0;i--)
 for(j=110;j>0;j--);
 


}

void init_com()
{
 OPTION=0X00;
 WPUA2=1;
 TRISA=0XFF;
 TRISC=0X00;
 ORTA=0X00;
 ORTC=0X00; //初始化必须置零。
    //TMR0=0X06;
    //T0IE=0;
    //T0IF=0;
    //OPTION=0X02;
    GIE=1;
    INTCON=0XC0;
    //PIE1=0X01;
    //TMR1H=(65536-50000)/256;
    //TMR1L=(65536-50000)%256;
    //T1CON=0X01;
}

   void  scankey()
   {
    if(RA2==0)
    {
     delay(10);
    num++;
     if(num<200)
    {
    duan_flag=1;
   
   
    if(num>200)
    {
    
        chang_flag1=1;
        duan_flag=0;
  
     
   
    }
   
   
   
   
   
    }
   
  }
  else if(RA2==1)
 
  {
   num=0;
   if(duan_flag==1)
   {
    duan_flag=1;
   
  
  
   }
 
 
 
 
 
  }
 
  }
  
void display()
{
 if(chang_flag1==1)
 {
  
  RC1=!RC1;
  chang_flag1=0;
  duan_flag=0;
 
 
 
 }
 if(duan_flag==1)
 {
  
     while(RA2==1)
     {
  RC6=!RC6;
  RC7=!RC7;
  duan_flag=0;
     chang_flag1=0;
     }
 
 
 }

 

 


}
  
  
  
  


   
  
  
  
  
  
  
  
 
 
 
 

 
   
   
                   
    

 
 
   void main()
   {
    init_com();
    while(1)
    {
    scankey();
    display();
  
 
  
  
   }
  
   }
  
  /* void interrupt timer0()
{
 if(TMR1IF=1)
 
    TMR1IF=0;
    
    TMR1H=(65536-50000)/256;
    TMR1L=(65536-50000)%256;
   
    num++;
 
   
  
  
   
  
 
 } */
   

 


 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2011-12-26 09:20:47 | 显示全部楼层
回复【楼主位】kyng:
---------------------------------
设计个局部静态变量,利用延时,并记录下进入的次数就可以判断是长按还是短按了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

42

主题

568

帖子

0

精华

高级会员

Rank: 4

积分
783
金钱
783
注册时间
2010-12-19
在线时间
5 小时
发表于 2011-12-26 10:36:55 | 显示全部楼层

在定时器中,设置好进入定时的时间,在中断中

/*********************************************************************************************************
** 函数名称: key_driver
** 功能描述: 按键状态机,可以实现消抖、短按、长按
**
** 输 入: 无
**
** 输 出: 无
**        
** 全局变量: 无

** 修改人: 程铭栋
** 日 期: 2011年10月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char key_driver(void) 

    static unsigned char key_state = key_state_0, key_time = 0; 
    unsigned char key_press, key_return = N_key; 

    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 >= 10)     // 继续按下,计时加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; 
}

/*********************************************************************************************************
** 函数名称: key_read
** 功能描述: 先根据key_driver的状态指示,再根据按键的状态,确定到底是不按、短按、双击、长按
**
** 输 入: key_driver
**
** 输 出: 无
**        
** 全局变量: 无

** 修改人: 程铭栋
** 日 期: 2011年10月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
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 >= 5) 
                 { 
                      key_return = S_key;      // 500ms内没有再次出现单键事件,返回上一次的单键事件 
                      key_m = key_state_0;     // 返回初始状态 
                 } 
             } 
             break; 
    }
    return key_return; 
}

一个上蹿下跳的猴子~~~
回复 支持 反对

使用道具 举报

42

主题

568

帖子

0

精华

高级会员

Rank: 4

积分
783
金钱
783
注册时间
2010-12-19
在线时间
5 小时
发表于 2011-12-26 10:53:15 | 显示全部楼层
下面是我STM32的源程序。
我的板子不是原子的MINISTM32板子,所以你需要修改下管脚配置。

9.按键(单击、双击、长按).rar

3.3 MB, 下载次数: 1957

一个上蹿下跳的猴子~~~
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-10-11
在线时间
0 小时
 楼主| 发表于 2011-12-26 18:02:39 | 显示全部楼层

我还是没有搞懂,最好在我原来的地方上改好!!!我用的是PIC的!!

回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-10-11
在线时间
0 小时
 楼主| 发表于 2011-12-26 18:11:01 | 显示全部楼层
为什么要静态变量???

回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2011-12-26 22:45:03 | 显示全部楼层
回复【6楼】kyng:
---------------------------------
自己想一下.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

42

主题

568

帖子

0

精华

高级会员

Rank: 4

积分
783
金钱
783
注册时间
2010-12-19
在线时间
5 小时
发表于 2011-12-27 08:54:49 | 显示全部楼层
回复【5楼】kyng:
---------------------------------
大哥,我都大部分注释了。

你认真的耐心的看下,应该很简单的。
一个上蹿下跳的猴子~~~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 11:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表