Chinaunix首页 | 论坛 | 博客
  • 博客访问: 807679
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2015-12-11 10:57:45

在章节【嵌入式软件开发:非阻塞按键读取_2】中,实现了利用FIFO缓冲区来缓存按键值,在主函数里面进行循环扫描FIFO里面是否有键值。
这里也可以利用事件队列机制来实现。
当按键按下时,产生一个按键事件,包括短按键事件,长按键事件。

想想如何添加一个事件??(三要素)
(1)静态初始化: static event_t keyPressEvent = EVENT_INIT(keyScanEvent);
(2)按键事件发生时,将其加入到事件队列中
(2)实现事件处理函数: static void keyScanEvent(void *data);
这里参数data 可以用来传递读取到的键值,在回调函数中,可以通过判断键值来确定按键按下的状态。



列代码:(黄色也新增的代码。)

点击(此处)折叠或打开

  1. #include "App_LongShortKey.h"
  2. #include <stdio.h>

  3.  // 添加的代码
  4. #define KEY_EVENT_QUEUE_DEBUG

  5. #ifdef KEY_EVENT_QUEUE_DEBUG
  6. #include "eventQueue.h"

  7. // 初始化按键事件及处理函数
  8. static void keyScanEvent(void *data);
  9. static event_t keyPressEvent = EVENT_INIT(keyScanEvent);
  10. #endif


  11. #define KEY0_INPUT KEY1

  12. static char key0_Status = 0;
  13. static unsigned int key0_TimeS, key0_TimeL;


  14. /**
  15.  * \brief: 与FIFO相关的变量定义
  16.  */
  17. //#define KEYBUFFSIZE 4
  18. char keyBuff[KEYBUFFSIZE];
  19. char key_indexW = 0;
  20. char key_indexR = 0;
  21. char key_count = 0;

  22. #define ENA_INT() __enable_irq()
  23. #define DIS_INT() __disable_irq()
  24. //#define ENA_INT()
  25. //#define DIS_INT()

  26. /**
  27.  * \brief: 与FIFO相关操作的函数的定义
  28.  */
  29.  
  30. void key_paraInit(void)
  31. {
  32.     char i = 0;
  33.     
  34.     for(i =0; i< KEYBUFFSIZE; i++)
  35.         keyBuff[i] = 0;
  36.     
  37.     key_indexW = 0;
  38.     key_indexR = 0;
  39.     key_count = 0;
  40. }
  41.  
  42. void key_inBuff(char keyValue)
  43. {
  44.     if(key_count >= KEYBUFFSIZE)
  45.         return;
  46.     
  47.     DIS_INT();
  48.     
  49.     key_count ++;
  50.     
  51.     keyBuff[key_indexW] = keyValue;
  52.     
  53.     if(++ key_indexW == KEYBUFFSIZE)
  54.         key_indexW = 0;
  55.     
  56.     ENA_INT();
  57. }

  58. char key_readBuff(void)
  59. {
  60.     char key = 0;

  61.     if(key_count == 0)
  62.         return 0;
  63.     
  64.     DIS_INT();
  65.     
  66.     key_count --;
  67.     
  68.     key = keyBuff[key_indexR];
  69.     if( ++key_indexR == KEYBUFFSIZE)
  70.         key_indexR = 0;
  71.     
  72.     ENA_INT();
  73.     return key;
  74. }

  75. /**
  76.  * \brief:
  77.  */
  78. uint8_t keyCodeBuff[1];

  79. void keyScan(void)
  80. {

  81.     
  82.     if(key0_Status == KEY_SHORT_PRESS)
  83.         key0_TimeS ++;
  84.     else
  85.         key0_TimeS = 0;
  86.     
  87.     if(key0_Status == KEY_LONG_PRESS)
  88.         key0_TimeL ++;
  89.     else
  90.         key0_TimeL = 0;
  91.     
  92.     switch(key0_Status)
  93.     {
  94.         case KEY_NO_PRESS:
  95.             if(KEY0_INPUT == 0)
  96.                 key0_Status = KEY_SHORT_PRESS;
  97.         break;
  98.             
  99.         case KEY_SHORT_PRESS:
  100.             
  101.             if(KEY0_INPUT != 0) // 表示按键松开了
  102.             {
  103.                 // 保存按键
  104.                 //key_inBuff(KEY_SHORT_CODE + KEY0_CODE);
  105.                 
  106. #ifdef KEY_EVENT_QUEUE_DEBUG

  107.                 keyCodeBuff[0] = KEY_SHORT_CODE + KEY0_CODE;
  108.                 EventQueue_EnqueueWithData(&keyPressEvent, keyCodeBuff);
  109. #endif
  110.                 
  111.                 // 返回到按键未按下模式
  112.                 key0_Status = KEY_NO_PRESS;
  113.             }
  114.             else
  115.             {
  116.                 if(key0_TimeS >= 2000/10) // 2s detect
  117.                 {
  118.                     //key_inBuff(KEY_FIRST_LONG_CODE + KEY0_CODE);
  119. #ifdef KEY_EVENT_QUEUE_DEBUG
  120.                     
  121.                    keyCodeBuff[0] = KEY_FIRST_LONG_CODE + KEY0_CODE;
  122.                    EventQueue_EnqueueWithData(&keyPressEvent, keyCodeBuff);
  123. #endif

  124.                     
  125.                     key0_Status = KEY_LONG_PRESS;
  126.                 }
  127.             }
  128.         break;
  129.             
  130.         case KEY_LONG_PRESS:
  131.             
  132.             if(KEY0_INPUT != 0) // 表示按键松开了
  133.             {
  134.                 // 返回到按键未按下模式
  135.                 key0_Status = KEY_NO_PRESS;
  136.             }
  137.             else
  138.             {
  139.                 if(key0_TimeL >= 100/10) // 250ms
  140.                 {
  141.                     //key_inBuff(KEY_AFTER_LONG_CODE + KEY0_CODE);
  142. #ifdef KEY_EVENT_QUEUE_DEBUG
  143.                                         
  144.                     keyCodeBuff[0] = KEY_AFTER_LONG_CODE + KEY0_CODE;
  145.                     EventQueue_EnqueueWithData(&keyPressEvent, keyCodeBuff);
  146. #endif

  147.                     key0_TimeL = 0;
  148.                 }
  149.             }
  150.         break;
  151.     }
  152. }

  153. // key真正的处理函数 --> 添加的代码:根据键值判断按键的状态
  154. void keyScanEvent(void *data)
  155. {
  156.     uint8_t *keyCode = (uint8_t *)data;  // 通过指针传递进来按键值
  157.     uint8_t key = *keyCode;
  158.     
  159.     switch(key){
  160.         
  161.         case (KEY0_CODE + KEY_SHORT_CODE):
  162.             printf("key1 short press \r\n");
  163.         break;
  164.         
  165.         case (KEY0_CODE + KEY_FIRST_LONG_CODE):
  166.             printf("key1 long press \r\n");
  167.         break;
  168.         
  169.         case (KEY0_CODE + KEY_AFTER_LONG_CODE):
  170.             printf("key1 after long press \r\n");
  171.         break;
  172.         
  173.         default:
  174.             break;
  175.         
  176.     }
  177. }

主函数里,只需扫描按键,以及读取事件队列中是否有事件发生

点击(此处)折叠或打开

  1. int main(void)
  2. {    
  3.     //static int cnt = 0;
  4.     volatile static event_t* event;
  5.     board_init();
  6.      
  7.     while(1)
  8.     {
  9.         event = EventQueue_GetPendingEvent();
  10.         if (event)
  11.         {
  12.             event->execute(event->data);
  13.         }
  14.         
  15.         if(flag) // 10ms中断内,查询按键状态,用来消除按键抖动。
  16.         {
  17.             flag =0;
  18.             keyScan();
  19.         }
  20.     }
  21.  }





阅读(1542) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~