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

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

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2015-10-23 10:54:26

实现目标:
1. 能实现非阻塞按键读取,比方那个键按下了,保存键值。
2. 能保存4次按键的值,如果按键太快了,超过4次按键,则后面的按键值会丢失。当然这个4次,可以自己定义。
3. 不涉及到长按键等状态检测。





贴代码吧

App_KeyNonblock.c

点击(此处)折叠或打开

  1. #include "App_KeyNonblock.h"


  2. #define KEY_RELEASE 1
  3. #define KEY_PRESS 0




  4. /**
  5.  * \brief:按键状态值,用来保存按键上一次和当前的按键状态值,利用两者对比就可以知道按键是否被按下。
  6.  */
  7. char p_key0_status = 0xff;
  8. char n_key0_status = 0xff;
  9. char p_key1_status = 0xff;
  10. char n_key1_status = 0xff;
  11. char p_key2_status = 0xff;
  12. char n_key2_status = 0xff;


  13. void key_inBuff(char keyValue);

  14. /**
  15.  * \brief: 该函数在10ms定时中断中被调用。除掉按键抖动。
  16.  *
  17.  */
  18. void keyScanIO(void)
  19. {
  20.     p_key0_status = n_key0_status;
  21.     n_key0_status = KEY0_IN;
  22.     p_key1_status = n_key1_status;
  23.     n_key1_status = KEY1_IN;
  24.     p_key2_status = n_key2_status;
  25.     n_key2_status = KEY2_IN;
  26.     
  27.     if((p_key0_status != KEY_PRESS) && (n_key0_status == KEY_PRESS)){
  28.         key_inBuff(KEY0_CODE);
  29.     }
  30.     
  31.     if((p_key1_status != KEY_PRESS) && (n_key1_status == KEY_PRESS)){
  32.         key_inBuff(KEY1_CODE);
  33.     }
  34.     
  35.     if((p_key2_status != KEY_PRESS) && (n_key2_status == KEY_PRESS)){
  36.         key_inBuff(KEY2_CODE);
  37.     }
  38. }



  39. /**
  40.  * 以下的代码很重要,实现按键的非阻塞功能。
  41. **/
  42. //#define KEYBUFFSIZE 4
  43. static char keyBuff[KEYBUFFSIZE] = {0};
  44. char key_indexW = 0;
  45. char key_indexR = 0;
  46. char key_count = 0;

  47. // 进入临界区的宏定义,可以根据不同的平台进行添加。
  48. #define DISABLE_INT()  xxx(添加具体的代码)
  49. #define ENABLE_INT()   xxx (添加具体)

  50. // 初始化函数:
  51. void key_paraInit(void)
  52. {
  53.     char i = 0;
  54.     
  55.     for(i =0; i< KEYBUFFSIZE; i++)
  56.         keyBuff[i] = 0;
  57.     
  58.     key_indexW = 0;
  59.     key_indexR = 0;
  60.     key_count = 0;
  61. }

  62. /**
  63.  * \brief: 写buffer,将键值存入BUFFER中
  64.  *
  65.  */
  66. void key_inBuff(char keyValue)
  67. {
  68.     if(key_count >= KEYBUFFSIZE)
  69.         return;

  70.     DISABLE_INT();
  71.     
  72.     key_count ++;
  73.     keyBuff[key_indexW] = keyValue;
  74.     
  75.     if(++key_indexW >= KEYBUFFSIZE)
  76.         key_indexW = 0;
  77.     
  78.     ENABLE_INT();
  79. }

  80. /*** \brief: 读Buffer, 将键值从buffer中读出  */

  81. char key_readBuff(void)
  82. {
  83.     char key =0;
  84.     
  85.     if(key_count == 0)
  86.         return 0;
  87.     
  88.     DISABLE_INT();
  89.     
  90.     key_count --;
  91.     
  92.     key = keyBuff[key_indexR];
  93.     if(++key_indexR >= KEYBUFFSIZE)
  94.         key_indexR = 0;
  95.     
  96.     ENABLE_INT();
  97.     
  98.     return key;
  99. }

App_KeyNonblock.h

点击(此处)折叠或打开

  1. #ifndef _KEYNONBLOCK_H_
  2. #define _KEYNONBLOCK_H_


  3. #include "key.h"


  4. #define KEY0_IN KEY0
  5. #define KEY1_IN KEY1
  6. #define KEY2_IN WK_UP

  7. #define KEY0_CODE 0x80
  8. #define KEY1_CODE 0x81
  9. #define KEY2_CODE 0x82


  10. #define KEYBUFFSIZE 4



  11. void keyScanIO(void);
  12. char key_readBuff(void);
  13. void key_paraInit(void);


  14. #endif

主函数中,只需要去读取buffer的函数就可以了。
这个是基于STM32平台的测试。

点击(此处)折叠或打开

  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "App_KeyNonblock.h"



  6. char keyValue = 0;
  7. uint8_t flag = 0;



  8. void SysTick_Init(void)
  9. {
  10.     if(SysTick_Config( SystemCoreClock / 100)) // 10ms
  11.     {
  12.         while(1);
  13.     }
  14.     
  15.     SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
  16. }



  17. void SysTick_Handler(void)
  18. {
  19.     flag = 1;
  20. }



  21.  int main(void)
  22.  {    
  23.     char i =0;
  24.     LED_Init();          
  25.     KEY_Init();
  26.     SysTick_Init();
  27.     uart_init(9600);
  28.     NVIC_Configuration();
  29.      
  30.     key_paraInit();
  31.      
  32.     while(1)
  33.     {
  34.         if(flag) // 10ms timer interrupt
  35.         {
  36.             flag =0;
  37.             keyScanIO();
  38.         }
  39.         

  40.         keyValue= key_readBuff(); /* read key value from buffer. */
  41.         if(keyValue != 0x00)
  42.         {
  43.             switch(keyValue)
  44.             {
  45.                 case KEY0_CODE:
  46.                     printf("key0 pressed now \r\n");
  47.                 break;
  48.                 
  49.                 case KEY1_CODE:
  50.                     printf("key1 pressed now \r\n");
  51.                 break;
  52.                 
  53.                 case KEY2_CODE:
  54.                     printf("key2 pressed now \r\n");
  55.                 break;
  56.                 
  57.                 default:
  58.                     break;
  59.             }
  60.             keyValue = 0x00;
  61.         }
  62.     }
  63. }

实现方法:
1. 构造了一个具有4BYTE的队列,当队列中保存的key值超过4个的时候,后面的数据将不会再保存到队列中,就等于将按键值丢失了。
2. 构造了两个类似于读和写的指针,这里只是类似于数组的下标,这里为什么不构造两个指针呢??因为对于单片机,资源比较小的嵌入式芯片来说,指针操作相对来说需要消耗大量的内存空间。


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