根据按键按下时间长度,获取按键时间值

     本案例采用芯片基本定时器采用16分频16MHZ的系统时钟,得到频率为1MHZ,自动重装值为200,每一次数数周期为0.2ms。

     

1、获取按键时间值执行函数

unsigned char get_key_press_time(void)
{
    static u2 u2_key_scan_time=0;                        //按键值是轮询获取时间
    static u1 u1_key_pin_value = 0;                      //获取按键链接的管脚信号值 (0/1)
    static u2 u2_key_press_continu_time=0;               //按键被连续按下时间
    unsigned char u1_return_key_press_time = 0;          // 所需按键返回时间
    static u1 u1_key_press_state=KEY_STATE_RELEASE;      //按键状态—(抬起、按下、抖动、短按、3s、5s...)
    
    //1、3ms轮询查询一次,并获得按键管脚的信号值(0或1)
    u2Clock_1msInc(&u2_key_scan_time);                    //1ms累加一次,按键扫描时间
    if(u2_key_scan_time >= 3)                             //3ms扫描一次
    {
     u2_key_scan_time = 0;                                //按键扫描时间清0
         u1_key_pin_value = ((GPIOA->DIN) & 0x0002);      //获取PA1管脚输入寄存器的值(信号)——(SWI)管脚的按键值       
     }
    
    u2Clock_1msInc(&u2_key_press_continu_time);           //开始记录按键被按下时间 
    
 
 
    //3、判断按键状态,根据不同的按键状态返回按键时间
    switch(u1_key_press_state)                            //根据按键值判断按键状态
    {
        //如果按键状态是被抬起
        case KEY_STATE_RELEASE:
          if(!u1_key_pin_value)                                       
          {
             u2_key_press_continu_time = 0;              //按键被按下保持时间清0
             u1_key_press_state=KEY_STATE_RELEASE;       //按键状态为被抬起        
          }
         else 
         {
            u1_key_press_state=KEY_STATE_PRESSDOWN;       //按键状态为被按下 
          }
          
        break;
              
        //如果按键处于刚刚被按下状态
        case  KEY_STATE_PRESSDOWN:                //如果是低电平0,说明按键被按下 
          //如果被抬起
          if(!u1_key_pin_value)                   //从按键控制管脚输入数据寄存器中读到了值
            {  
               u2_key_press_continu_time = 0;     //按键被按下保持时间清0
               u1_key_press_state =KEY_STATE_RELEASE;
            }
            //如果按键一直按着
            else                                  //如果没有从按键控制管脚中读到值
            {   
              u2_key_press_continu_time = 0;      //先清0,为20ms消抖做准备
          u1_key_press_state = KEY_STATE_SHAKE;   //按键状态为按下抖动状态
      
            }
    break;
        
        //前20ms是属于抖动消抖阶段
    case KEY_STATE_SHAKE:                       //按键消抖,消抖时间20ms
          //如果按键在20ms前被抬起
          if(!u1_key_pin_value)                 //如果从按键控制管脚输入数据寄存器中读到值
            {
                
                  u1_key_press_state = KEY_STATE_RELEASE;  //按键按下状态为抬起RELEASE  
                
            }
          //如果是一直按着,时间经过20ms,到达短按阶段 
          
          else   //如果没有从按键控制管脚输入数据寄存器中读到值
            {    //按下消抖
                if(u2_key_press_continu_time > 20)  //1ms累加一次,记录按键被按下的时间长度
                {
                   u1_key_press_state = KEY_STATE_SHORT;   //按键状态为短按状态
                 }
            }
    break;
         
        //如果按键按下时间进入短按阶段
    case KEY_STATE_SHORT:                              //如果按键被按下状态是短按
            if(!u1_key_pin_value)                      //如果现在被按着
            {
                u2_key_press_continu_time = 0;         //按键被按下保持时间清0
        u1_key_press_state = KEY_STATE_RELEASE;        //按键被按下装下状态为按下
                u1_return_key_press_time = KEY_VALUE_SHORT;           
            }
            else                                           //如果被抬起了
            {
              if(u2_key_press_continu_time >= 3000)        //观察时间已经到了3s
              {
                u1_key_press_state = KEY_STATE_3S;         //按键被按下状态为按下保持3s状态
                u1_return_key_press_time = KEY_VALUE_3S;   //返回3s按键值
              }
            } 
    break;
        
        //如果按键进入按下保持3s阶段
    case KEY_STATE_3S:  
          if(!u1_key_pin_value)
          {
                u2_key_press_continu_time = 0;                //按键被按下保持时间清0                
        u1_key_press_state = KEY_STATE_RELEASE;              //按键按下状态为按下
                u1_return_key_press_time = KEY_VALUE_3S;     //返回5s按键值
                           
          }
          else
          {
            if(u2_key_press_continu_time >= 5000)
            {
                u1_key_press_state = KEY_STATE_5S;           //按键状态是按下保持5s
                u1_return_key_press_time = KEY_VALUE_5S;     //返回5s按键值
            }
          }       
    break;
    
        //如果按键进入按下保持5s阶段
    case KEY_STATE_5S: 
          
          //如果是按键松开
          if(!u1_key_pin_value)
          {
                u2_key_press_continu_time = 0;      //按键被按下保持时间清0                              //按键按下状态为按下 (这里按键到5s截至,如果按照5s赋值,就挑不出)
                u1_key_press_state = KEY_STATE_RELEASE;    
              
                u1_return_key_press_time = KEY_STATE_5S;     //返回5s按键值
          }
          else
          {
            if(u2_key_press_continu_time >= 8000)
            {
                u1_key_press_state = KEY_STATE_8S;           //按键状态是按下保持8s
                u1_return_key_press_time =KEY_STATE_8S;      //返回8s按键值
            }
          }
        break;
                                                  
    default:
        u2_key_press_continu_time = 0;                    //按键被按下保持时间清0 
        u1_key_press_state= KEY_STATE_RELEASE;            //按键按下状态为抬起
           
    break;
    } 

    return u1_return_key_press_time;          //最终返回按键按下保持时间(短、3、5、8)
    
}

2、基本定时器

//基本定时器处理程序
void BSTIM_IRQHandler(void)
{

//这里基本定时器采用16分频16MHZ的系统时钟,得到频率为1MHZ,自动重装值为200,每一次数数周期为0.2ms
    BSTIM32->ISR |= 0x1; //中断标志寄存器清零 (硬件置位,软件写 1 清零)
    tm_200us++;         //时间200微秒变量开始累加
    tm_1ms++;           //为了获得1毫秒基本定时器数数变量开始累加
    if (tm_1ms == 5)    //0.2ms*5=1ms
    {
        tm_1ms = 0;     //把为了获得1毫秒数数变量清0
        flag_1ms = 1;   //时间成功过去1ms
    }
    if (tm_200us == 100) //0.2ms*100=20ms
    {
        tm_200us = 0;   //把为了获得20毫秒数数变量清0 
        flag_20ms = 1;  //时间成功过去20ms
    }

    if (0 == tm_1ms)   //如果基本定时器没有开始数数
    {
        Time1ms_count++;   //启动备用1ms计数累加
    }
    
    if (( 0 ==  ADCComplete)&&(Time1ms_count > 200))   //时间过去40ms且ADC转换没有完成
    {
            FL_ADC_EnableSWConversion(ADC);            //使能ADC软件触发转换
            Time1ms_count = 0;                         //备用1ms计数累加变量清0
    }
    
    // FL_ADC_EnableSWConversion(ADC);  //使能ADC软件触发转换
}

3、时钟控制标志位

void clock_control(void)
{
    flag_20msseed = 0;      //过去20ms毫秒标识
    flag_1secseed = 0;      //过去1sec秒标识
    flag_minseed = 0;       //过去1min分钟标识
    flag_1msseed = 0;       //过去1ms毫秒标识
    
    if (flag_1ms)           //到达1毫秒
    {
        flag_1ms = 0;         //1ms变量清0
        flag_1msseed = 1;     //时间成功过去1毫秒
    }


    if (flag_20ms)             //到达20毫秒
    {
        flag_20ms = 0;         //将到达20毫秒标识清零
        flag_20msseed = 1;     //成功到达20毫秒标识为1
        tm_20ms++;
        if (tm_20ms >= 50)     //20*50=1000ms=1s
        {
            tm_20ms = 0;       //20ms变量清0
            flag_1secseed = 1; //成功过去1秒
        }
    }


    if (flag_1secseed)           //1秒
    {
        tm_1sec++;               
        if (tm_1sec >= 60)       //1s*60=60s=1min
        {
            tm_1sec = 0;         //1s变量清0
            flag_minseed = 1;    //成功过去1分钟
        }
    }
    
    flag_successed_copy = flag_1secseed; //1分钟拷贝一次成功返回1
}

4、1ms定时器

//1ms累加一次
void u2Clock_1msInc(u2 *v)
{
    if (flag_1msseed)    //基本定时器时间过去1ms
    {
        if (*v < 0xffff) //累加到ffff
        {
            (*v)++;
        }
    }
}

5、1s定时器

//1s累加一次
void u2Clock_SecInc(u2 *v)
{
    if (flag_1secseed)     //如果时间过去1s
    {
        if (*v < 0xffff)  //累加到ffff
        {
            (*v)++;
        }
    }
}

6、1min定时器

//1min累加一次
void u2Clock_MinInc(u2 *v)
{
    if (flag_minseed)      //基本定时器成功过去1分钟
    {
        if (*v < 0xffff)  //累加到ffff
        {
            (*v)++;
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值