OpenEdv-开源电子网

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

求C按键处理程序(连按,长按,短按)

[复制链接]

1

主题

17

帖子

0

精华

高级会员

Rank: 4

积分
590
金钱
590
注册时间
2015-9-26
在线时间
136 小时
发表于 2016-3-12 09:07:36 | 显示全部楼层 |阅读模式
10金钱
求C语言按键处理程序,包括(连按,长按,短按),向有写过的高手请教,谢谢!

最佳答案

查看完整内容[请看2#楼]

#include "timer.h" #include "led.h" #include "KEY.h" #include "BSP.h" u32 S1_PRES_TICK=0,S2_PRES_TICK=0,S3_PRES_TICK=0,\ D1_IN_PRES_TICK=0,D2_IN_PRES_TICK=0,\ D1_OUT_PRES_TICK=0,D2_OUT_PRES_TICK=0, TIM2_TICK=0, TIM3_TICK=0,\ S1_RLAX_TICK=0,S2_RLAX_TICK=0,S3_RLAX_TICK=0,\ D1_IN_RLAX_TICK=0,D2_IN_RLAX_TICK=0,\ D1_OUT_RLAX_TICK=0,D2_OUT_RLAX_TICK=0; u8 TimeDigit=0,LonP ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

164

主题

1230

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1477
金钱
1477
注册时间
2014-5-21
在线时间
342 小时
发表于 2016-3-12 09:07:37 | 显示全部楼层

无OS 方法1-->定时器检测1:

本帖最后由 cornrn 于 2016-3-12 09:21 编辑


#include "timer.h"
#include "led.h"
#include "KEY.h"
#include "BSP.h"

u32 S1_PRES_TICK=0,S2_PRES_TICK=0,S3_PRES_TICK=0,\
    D1_IN_PRES_TICK=0,D2_IN_PRES_TICK=0,\
                D1_OUT_PRES_TICK=0,D2_OUT_PRES_TICK=0, TIM2_TICK=0, TIM3_TICK=0,\
    S1_RLAX_TICK=0,S2_RLAX_TICK=0,S3_RLAX_TICK=0,\
    D1_IN_RLAX_TICK=0,D2_IN_RLAX_TICK=0,\
                D1_OUT_RLAX_TICK=0,D2_OUT_RLAX_TICK=0;
u8  TimeDigit=0,LonPrsS1Con=0,SrtPrsS1Con=0;
extern CLOCK clock;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//通用定时器2中断初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这里时钟选择为APB1的2倍,而APB1为36M>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//arr:自动重装值。>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//psc:时钟预分频数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这里使用的是定时器2!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void TIM2_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );

        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

        TIM_Cmd(TIM2, ENABLE);  //使能TIMx外设                                 
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//通用定时器3中断初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这里时钟选择为APB1的2倍,而APB1为36M>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//arr:自动重装值。>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//psc:时钟预分频数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这里使用的是定时器2!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void TIM3_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );

        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

        TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设                                 
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//通用定时器4中断初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这里时钟选择为APB1的2倍,而APB1为36M>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//arr:自动重装值。>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//psc:时钟预分频数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这里使用的是定时器2!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void TIM4_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能

        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE );

        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

        TIM_Cmd(TIM4, ENABLE);  //使能TIMx外设                                 
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//通用定时器2中断响应函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void TIM2_IRQHandler(void)   //TIM3中断
{
        if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                if(GetSystemFlag(SetTimeFlag)){
                        TIM2_TICK++;
                        /*↓↓下面这段实现调时间时候相应需要调整的位跳动方式显示*/
                        if((TIM2_TICK%2)==1){       
                  TM1637_Dis_Time(&clock,MAOHAO_NO);
                        }
                        else{
                                if(TimeDigit==0){
                                        TM1637_NixieTubeDisplayChar(24,0,MAOHAO_NO);  //显示空白
                                        TM1637_NixieTubeDisplayChar(24,1,MAOHAO_NO);  //显示空白
                                }
                                else{
                                        TM1637_NixieTubeDisplayChar(24,2,MAOHAO_NO);  //显示空白
                                        TM1637_NixieTubeDisplayChar(24,3,MAOHAO_NO);  //显示空白
                                }
                        }
                        ClrSystemFlag(Mode2Flag);
                        SetSystemFlag(ReInMode1Flag);
                        /*上面这段实现调时间时候相应需要调整的位跳动方式显示*/
                }
                else{
                        if(GetSystemFlag(Mode2Flag)){
//                                if(IfRedTsConForDis!=IfRedTsCon){
                                        IfRedTsConForDis=IfRedTsCon;
                                  TM1637_Dis_Num(IfRedTsConForDis);
//                                }
                                TIM2_TICK=0;
                                ClrSystemFlag(JUSTBOOTFlag);
                                SetSystemFlag(ReInMode1Flag);
                        }
                        else{
                                if(IfRedTsConForDis!=IfRedTsCon){
                                        IfRedTsConForDis=IfRedTsCon;
                                  TM1637_Dis_Num(IfRedTsConForDis);
                                        TIM2_TICK=0;
                                        ClrSystemFlag(JUSTBOOTFlag);
                                }
                                else{
                                        TIM2_TICK++;
                                        if((TIM2_TICK>10)||(GetSystemFlag(JUSTBOOTFlag))||(GetSystemFlag(ReInMode1Flag))){
            ClrSystemFlag(ReInMode1Flag);
                                                GetSystemClock(&clock);       
                                                TM1637_Dis_Time(&clock,MAOHAO_YES);
                                        }
                                }
                        }
                }
          TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM 中断源
        }
}       
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//通用定时器3中断响应函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void TIM3_IRQHandler(void)   //TIM3中断
{
        if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
                {
                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM 中断源
                         if(S1==1||S2==1||S3==1)
                        {
                                if(S1==1)S1_PRES_TICK++;
                                else if(S2==1)S2_PRES_TICK++;
                                else if(S3==1)S3_PRES_TICK++;
                                if(S1_PRES_TICK==800) //达到长按时间
                                {
                                  LonPrsS1Con++;
                                        if((LonPrsS1Con%2)==1){       
                                                SetSystemFlag(SetTimeFlag);                                       
                                        }
                                        else{
                                                SetSystemFlag(LonPrsS1Flag);        //置位S1长按标志       
                                        }       
                                        S1_PRES_TICK=0;
                                }
                        }
                        else if(S1==0&&S2==0&&S3==0)
                        {       
         if((S1_PRES_TICK)&&(S1_PRES_TICK<400))    SetSystemFlag(PrsS1Flag);       
         else        if(S2_PRES_TICK)   SetSystemFlag(PrsS2Flag);       
         else        if(S3_PRES_TICK)   SetSystemFlag(PrsS3Flag);       

                                 S1_PRES_TICK=0;S2_PRES_TICK=0;S3_PRES_TICK=0;
                                 S1_RLAX_TICK++;S2_RLAX_TICK++;S3_RLAX_TICK++;
                        }
                }
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//通用定时器4中断响应函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void TIM4_IRQHandler(void)   //TIM4中断
{
        if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
        //出去计数
        if(IfredConD1_PIN==0){
                        D1_OUT_PRES_TICK++;
                        D1_OUT_RLAX_TICK=0;
                }
                else{
                        D1_OUT_RLAX_TICK++;
                        if(D1_OUT_PRES_TICK){
                                if(IfredConD2_PIN==0){
                                        D2_OUT_PRES_TICK++;
                                }
                                else{
                                        if(D2_OUT_PRES_TICK){
                                                if(IfRedTsCon)IfRedTsCon--;               
                                                if(IfRedTsCon==9)   LED1=0;
                                                else if(IfRedTsCon==19)  LED2=0;
                                                else if(IfRedTsCon==29)  LED3=0;
                                                D1_OUT_PRES_TICK=0;       
                                        }
                                }
                  }
                        else{

                        }
                        if(D1_OUT_RLAX_TICK==100){
                                D1_OUT_PRES_TICK=0;
                                D2_OUT_PRES_TICK=0;
                        }
                }       
   //进入计数
                if(IfredConD2_PIN==0){
                        D2_IN_PRES_TICK++;
                        D2_IN_RLAX_TICK=0;
                }
                else{
                        D2_IN_RLAX_TICK++;
                        if(D2_IN_PRES_TICK){
                                if(IfredConD1_PIN==0){
                                        D1_IN_PRES_TICK++;
                                }
                                else{
                                        if(D1_IN_PRES_TICK){
                                                IfRedTsCon++;
            if(IfRedTsCon==10)  LED1=1;
                                          else if(IfRedTsCon==20)  LED2=1;
                                          else if(IfRedTsCon==30)  LED3=1;                                               
                                                D2_IN_PRES_TICK=0;       
                                        }
                                }
                  }
                        else{

                        }
                        if(D2_IN_RLAX_TICK==100){
                                D2_IN_PRES_TICK=0;
                                D1_IN_PRES_TICK=0;
                        }
                }               
          TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM 中断源
        }
}       





彼高丽者,边夷贱类,不足待以仁义,不可责以常礼。古来以鱼鳖畜之,宜从阔略。若必欲绝其种类,恐兽穷则搏。
回复

使用道具 举报

164

主题

1230

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1477
金钱
1477
注册时间
2014-5-21
在线时间
342 小时
发表于 2016-3-12 09:16:26 | 显示全部楼层
一种基于ucos这类OS的,还有一种无OS操作的,我下面代码分享一下,根据实际要求自己修改
彼高丽者,边夷贱类,不足待以仁义,不可责以常礼。古来以鱼鳖畜之,宜从阔略。若必欲绝其种类,恐兽穷则搏。
回复

使用道具 举报

164

主题

1230

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1477
金钱
1477
注册时间
2014-5-21
在线时间
342 小时
发表于 2016-3-12 09:26:18 | 显示全部楼层
方法2-->基于UCOSIII的**最后修改日期: 2015年04月24日**描        述: 按键操作
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "key.h"
#include "stdio.h"
#include "stdlib.h"
#include "lcd.h"

/*
*********************************************************************************************************
                                                                                                                                                                私有宏定义
*********************************************************************************************************
*/
#define GetPwrStatus()                                                  (GPIOB->IDR & GPIO_Pin_10)
#define DISPLAY_INFO_KEY_STATUS()   (GPIOC->IDR & GPIO_Pin_5)
#define ECG_MARK_KEY_STATUS()       (GPIOB->IDR & GPIO_Pin_0)
#define START_RECORD_KEY_STATUS()   (GPIOB->IDR & GPIO_Pin_1)
#define POWER_CTL_KEY_STATUS()      (GPIOB->IDR & GPIO_Pin_10)

CPU_INT08U StartADCFlag = 0;
OS_TICK  StartRecordTick = 0;

/*
*********************************************************************************************************
                                                                                                                                                                私有函数申明
*********************************************************************************************************
*/
static        CPU_INT08U QueryKeyCode(void);

/********************************************************************************************************
** 函数名称: KeyTask
** 功能描述: 按键任务,完成开机动作,按键扫描
** 输   入: parg:参数传递入口
** 输   出: 无
** 全局变量: 无                                          
********************************************************************************************************/
void KeyTask(void *parg)
{
        OS_ERR  err;

        CPU_INT08U key;

        APP_ARG *p_arg         =         (APP_ARG *)parg;

        static LCDDAT lcd;


        if(OSFlagPend(p_arg->pfgrp,(OS_FLAGS)SDCardLessFlag+NoSDCardFlag,100,OS_OPT_PEND_NON_BLOCKING + OS_OPT_PEND_FLAG_SET_ANY,NULL,&err))
        {
                lcd.pic = FlashDiyLCD;lcd.period = 0;
                CloseDev();
        }else {lcd.pic = SystemNormalLCD;lcd.period = 1;}
        OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);       
        OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
        CloseBlueLED();
        do{
                OSTimeDlyHMSM(0,0,0,100,OS_OPT_TIME_DLY,&err);
        }while(GetPwrStatus());

        while(1)
        {       
                key = QueryKeyCode();
                if(key != NoKey){

                        if(key==POWER_CTL_KEY){       
                                OSTimeDlyHMSM(0,0,PWR_KEY_TIME_DELAY,0,OS_OPT_TIME_DLY,&err);                        /*         关机延时                                        */
                        }else{
                                OSTimeDlyHMSM(0,0,0,KEY_TIME_DELAY,OS_OPT_TIME_DLY,&err);                                        /*         按键去抖延时                                */
                        }

                        if(key == QueryKeyCode())
                        {
                                lcd.period = 1;       
                                switch(key){

                                        case POWER_CTL_KEY:                                                                                                                                                                               
                                                if(StartADCFlag)StartADCFlag = 0;
                                                OSFlagPost(p_arg->pfgrp,PowerDownFlag,OS_OPT_POST_FLAG_SET,&err);
                                                CloseDev();CloseBlueLED();CloseYellowLED();
                                                lcd.pic = ShutDownFinishLCD;
                                                OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);       
                                                OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
                                                break;

                                        case START_RECORD_KEY:
                                                OSFlagPost(p_arg->pfgrp,StartRecordFlag,OS_OPT_POST_FLAG_SET,&err);
                                                OSFlagPend(p_arg->pfgrp,(OS_FLAGS)StartADCCnvFlag,0,OS_OPT_PEND_BLOCKING + OS_OPT_PEND_FLAG_SET_ALL,NULL,&err);

                                                if(!StartADCFlag){
                                                        OSTimeSet(0,&err);
                                                        StartADCFlag = 1;
                                                }
                                                lcd.pic = RecordingLCD;
                                                OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);       
                                                OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
                                                OSFlagPost(p_arg->pfgrp,RecordRunFlag,OS_OPT_POST_FLAG_SET,&err);       
                                                break;

                                        case ECG_MARK_KEY:
                                                if(OSFlagPend(p_arg->pfgrp,(OS_FLAGS)RecordRunFlag,0,OS_OPT_PEND_FLAG_SET_ALL+
                                                                                                                                OS_OPT_PEND_NON_BLOCKING,NULL,&err)){       
                                                        if(OS_ERR_NONE == err){
                                                                OSFlagPost(p_arg->pfgrp,(OS_FLAGS)ECGMarkFlag,OS_OPT_POST_FLAG_SET,&err);       
                                                                lcd.pic = EcgMarkLCD;       
                                                        }
                                                }else lcd.pic = SystemNormalLCD;
                                                OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);       
                                                OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
                                                break;

                                        case DISPLAY_INFO_KEY:
                                                if(OSFlagPend(p_arg->pfgrp,(OS_FLAGS)StartRecordFlag,0,OS_OPT_PEND_FLAG_SET_ALL+
                                                                                                                                OS_OPT_PEND_NON_BLOCKING,NULL,&err)){       
                                                        lcd.pic = DisplayInfoLCD;                                                                                       
                                                }else lcd.pic = SystemNormalLCD;                                                                                                                               
                                                OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);       
                                                OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
                                                break;

                                }
                                OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_DLY,&err);
                        }               
                }else  OSTimeDlyHMSM(0,0,0,100,OS_OPT_TIME_DLY,&err);
        }
}

/********************************************************************************************************
** 函数名称: QueryKeyCode
** 功能描述: 查询键码
** 输   入: 无   
** 输   出: 无
** 返    回: 查询后的键码
********************************************************************************************************/
static CPU_INT08U QueryKeyCode(void)
{
        CPU_INT08U keycode = 0;

        if(DISPLAY_INFO_KEY_STATUS())keycode |= DISPLAY_INFO_KEY;
        if(ECG_MARK_KEY_STATUS())keycode |= ECG_MARK_KEY;
        if(START_RECORD_KEY_STATUS() )keycode |= START_RECORD_KEY;
        if(POWER_CTL_KEY_STATUS())keycode |= POWER_CTL_KEY;
        return keycode;
}

/********************************************************************************************************
** 函数名称: KeyIRQn
** 功能描述: 按键中断处理函数
** 输   入: 无   
** 输   出: 无
** 返    回: 无
********************************************************************************************************/
void KeyIRQn(void)
{
        if((EXTI->PR & EXTI_Line0))        EXTI->PR = EXTI_Line0;
        if((EXTI->PR & EXTI_Line1))        EXTI->PR = EXTI_Line1;
        if((EXTI->PR & EXTI_Line5))        EXTI->PR = EXTI_Line5;
        if((EXTI->PR & EXTI_Line10))EXTI->PR = EXTI_Line10;

}


/****************************** (C) COPYRIGHT SmartHealth *****END OF FILE******************************/

彼高丽者,边夷贱类,不足待以仁义,不可责以常礼。古来以鱼鳖畜之,宜从阔略。若必欲绝其种类,恐兽穷则搏。
回复

使用道具 举报

1

主题

17

帖子

0

精华

高级会员

Rank: 4

积分
590
金钱
590
注册时间
2015-9-26
在线时间
136 小时
 楼主| 发表于 2016-3-12 09:29:47 | 显示全部楼层
没有原理图,还真一时看不明白
回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-12 09:33:01 | 显示全部楼层
做过,就不列程序了,原理也非常简单。

首先,定义一个函数,让它每隔2ms(时间自定)被调用一次

定义一个计数器,
如果检测到引脚为0(按下),则计数器加一;
如果检测到引脚为1(抬起),则计数器清零;

然后你就可以根据计数器的值来判断是否长按了,
如果在清零之前,计数器>=10(消抖),则说明短按了

在弄一个变量记录上次被确认按下事件发生时刻,
如果这次按下事件发生的时刻和上次距离很短,则说明连按了。


/*
这只是简单地列举几种应用场景,
其实采用这种思想还可以做更复杂的应用,
比如按下检测、抬起检测、抖动检测、单击、双击等等
*/
坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

1

主题

17

帖子

0

精华

高级会员

Rank: 4

积分
590
金钱
590
注册时间
2015-9-26
在线时间
136 小时
 楼主| 发表于 2016-3-12 09:40:55 | 显示全部楼层
就是要有实例,自己调了,费时不说,也一时调不好,有寄存器操作的更好了。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 16:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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