你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

FREERTOS下的按键处理方式讨论  

[复制链接]
netlhx 提问时间:2015-5-3 21:45 /
阅读主题, 点击返回1楼
收藏 3 评论24 发布时间:2015-5-3 21:45
24个回答
valetang-126879 回答时间:2017-3-3 14:20:27
按键这个看似简单的应用
suyong_yq 回答时间:2017-3-5 00:47:20
无帝老三 发表于 2017-2-22 13:56
您好,是不是状态机加定时器?
可不可以用任务延时代替定时器?

是状态机+定时器的做法。
不建议用任务延时代替定时器,因为任务延时会额外占用一个任务描述符。但是在操作系统环境下,用一个专门的任务监控状态机并且分发按键消息是非常有必要的。
阿陆 回答时间:2017-3-8 16:06:17
很不错,学到了,谢谢 楼主
秋水之下 回答时间:2017-5-27 15:10:38
suyong_yq 发表于 2017-3-5 00:47
是状态机+定时器的做法。
不建议用任务延时代替定时器,因为任务延时会额外占用一个任务描述符。但是在操 ...

这还有一个方法就是,用OS的软件定时器,对于还有误触发情况我们可以用STM32硬件按键滤波方法
---》STM32的定时器输入通道都有一个滤波单元,分别位于每个输入通路上(下图中的黄色框)和外部触发输入通路上(下图中的兰色框),它们的作用是滤除输入信号上的高频干扰。

http://www.eeworld.com.cn/mndz/2013/0922/article_19360.html

这个是香水城分享的
秋水之下 回答时间:2017-6-1 09:23:58
appllo 发表于 2015-12-18 11:12
消息队列肯定是更好的

方法很多,基于队列也很好。不过基于队列同时相应两个按键连击好像处理就麻烦点了。

下面是我开一个按键扫描任务里面发送标志到标志组,其他任务检查标志组就可以。
  1. void KeyTask(void *parg)
  2. {
  3.         OS_ERR  err;
  4.         CPU_INT08U key;
  5.         APP_ARG *p_arg         =         (APP_ARG *)parg;
  6.         static LCDDAT lcd;
  7.         
  8.         if(OSFlagPend(p_arg->pfgrp,(OS_FLAGS)SDCardLessFlag+NoSDCardFlag,100,OS_OPT_PEND_NON_BLOCKING + OS_OPT_PEND_FLAG_SET_ANY,NULL,&err))
  9.         {
  10.                 lcd.pic = FlashDiyLCD;lcd.period = 0;
  11.                 SysPower(CLOSE);        
  12.         }else {
  13.         lcd.pic = SystemNormalLCD;lcd.period = 1;
  14.         }

  15.         OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);        
  16.         OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
  17.         LED_B(CLOSE);
  18.         do{OSTimeDlyHMSM(0,0,0,100,OS_OPT_TIME_DLY,&err);}
  19.         while(GetKEYStatus(POWER));

  20.         while(1)
  21.         {        
  22.                 key = QueryKeyCode();
  23.                 if(key != NoKey){

  24.                         if(key==POWER_CTL_KEY){        
  25.                                 //OSTimeDlyHMSM(0,0,PWR_KEY_TIME_DELAY,0,OS_OPT_TIME_DLY,&err);                        /*         关机延时                                        */
  26.                                 OSFlagPost(p_arg->pfgrp,BeepRunFlag,OS_OPT_POST_FLAG_SET,&err);//打开蜂鸣器
  27.                                 OSTimeDlyHMSM(0,0,0,300,OS_OPT_TIME_DLY,&err);
  28.                                 OSFlagPost(p_arg->pfgrp,BeepRunFlag,OS_OPT_POST_FLAG_CLR,&err);//关闭蜂鸣器
  29.                                 OSTimeDlyHMSM(0,0,0,300,OS_OPT_TIME_DLY,&err);        
  30.                                 OSFlagPost(p_arg->pfgrp,BeepRunFlag,OS_OPT_POST_FLAG_SET,&err);//打开蜂鸣器
  31.                                 OSTimeDlyHMSM(0,0,0,300,OS_OPT_TIME_DLY,&err);
  32.                                 OSFlagPost(p_arg->pfgrp,BeepRunFlag,OS_OPT_POST_FLAG_CLR,&err);//关闭蜂鸣器
  33.                                 GPIO_ResetBits(GPIOC, GPIO_Pin_2);//不叫        
  34.                                 
  35.                         }else{
  36.                                 OSTimeDlyHMSM(0,0,0,KEY_TIME_DELAY,OS_OPT_TIME_DLY,&err);                                        /*         按键去抖延时                                */
  37.                         }
  38.                
  39.                         if(key == QueryKeyCode())
  40.                         {
  41.                                 lcd.period = 1;        
  42.                                 switch(key){
  43.         
  44.                                         case POWER_CTL_KEY:                                                                                                                                                                                
  45.                                                 if(StartADCFlag)StartADCFlag = 0;
  46.                                                 OSFlagPost(p_arg->pfgrp,PowerDownFlag,OS_OPT_POST_FLAG_SET,&err);
  47.                                                 SysPower(CLOSE);        LED_B(CLOSE);LED_G(CLOSE);
  48.                                                 lcd.pic = ShutDownFinishLCD;
  49.                                                 OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);        
  50.                                                 OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
  51.                                                 break;
  52.                                        
  53.                                         case START_RECORD_KEY:
  54.                                                 OSFlagPost(p_arg->pfgrp,StartRecordFlag,OS_OPT_POST_FLAG_SET,&err);
  55.                                                 //OSFlagPend(p_arg->pfgrp,(OS_FLAGS)StartADCCnvFlag,0,OS_OPT_PEND_BLOCKING + OS_OPT_PEND_FLAG_SET_ALL,NULL,&err);
  56.                                                 lcd.pic = RecordingLCD;
  57.                                                 OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);        
  58.                                                 OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
  59.                                                 OSFlagPost(p_arg->pfgrp,RecordRunFlag,OS_OPT_POST_FLAG_SET,&err);        
  60.                                                 break;
  61.                                                 
  62.                                         case ECG_MARK_KEY:
  63.                                                 if(OSFlagPend(p_arg->pfgrp,(OS_FLAGS)RecordRunFlag,0,OS_OPT_PEND_FLAG_SET_ALL+
  64.                                                                                                                                 OS_OPT_PEND_NON_BLOCKING,NULL,&err)){        
  65.                                                         if(OS_ERR_NONE == err){
  66.                                                                 OSFlagPost(p_arg->pfgrp,(OS_FLAGS)ECGMarkFlag,OS_OPT_POST_FLAG_SET,&err);        
  67.                                                                 lcd.pic = EcgMarkLCD;        
  68.                                                         }
  69.                                                 }else lcd.pic = SystemNormalLCD;
  70.                                                 OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);        
  71.                                                 OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
  72.                                                 break;
  73.                                                 
  74.                                         case DISPLAY_INFO_KEY:
  75.                                                 if(OSFlagPend(p_arg->pfgrp,(OS_FLAGS)StartRecordFlag,0,OS_OPT_PEND_FLAG_SET_ALL+
  76.                                                                                                                                 OS_OPT_PEND_NON_BLOCKING,NULL,&err)){        
  77.                                                         lcd.pic = DisplayInfoLCD;                                                                                       
  78.                                                 }else lcd.pic = SystemNormalLCD;                                                                                                                                
  79.                                                 OSQPost(p_arg->pLCDQ,(void *)&lcd,sizeof(lcd),OS_OPT_POST_FIFO,&err);        
  80.                                                 OSTimeDlyResume(p_arg->LCDTaskTCB,&err);
  81.                                                 break;
  82.                                                 
  83.                                 }
  84.                                 OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_DLY,&err);
  85.                         }               
  86.                 }else  OSTimeDlyHMSM(0,0,0,100,OS_OPT_TIME_DLY,&err);
  87.                
  88.         }
  89. }
复制代码

123

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版