key_process.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /**
  2. http://electronix.ru/forum/index.php?showtopic=93624&view=findpost&p=964475
  3. Примерно лет шесть делаю так:
  4. */
  5. // в .h-файле:
  6. // кол-во времени до события "длинное нажатие"
  7. #define TIMER_COUNT 250
  8. // кол-во кнопок
  9. #define KEY_COUNT 4
  10. // время автоинкремента
  11. #define TIMER_SCROLL 20
  12. // состояние кнопки
  13. enum {KN_DOWN =0, KN_UP =1, KN_PRESS=2 };
  14. // тип функции кнопки
  15. typedef byte(KeyFunc)(void);
  16. // структура хранящая набор переменных для каждой кнопки
  17. typedef struct key_struct__
  18. {
  19. byte state; // состояние кнопки
  20. byte mask; // маска клавиши
  21. byte pins; // буфер значений с клавиши
  22. byte count; // счетчик нажатий
  23. KeyFunc * exec_down;
  24. KeyFunc * exec_up;
  25. KeyFunc * exec_pres;
  26. }key_struct;
  27. // в .c-файле:
  28. //*****************************************************************************
  29. // Драйвер кнопок
  30. // назначение кнопок
  31. // 1- MiNUS 2-PLUS 3- Select 4- Enter
  32. //*****************************************************************************
  33. //=============================================================================
  34. // состояния кнопок
  35. static key_struct key_mass [KEY_COUNT] = {
  36. //state mask pins count exec_down exec_up exec_pres
  37. {KN_UP, PIN_KEY_MINUS, 0xFF,0x00, kn_empty, kn_minus_up ,kn_minus_up }
  38. ,{KN_UP, PIN_KEY_PLUS, 0xFF,0x00, kn_empty, kn_plus_up ,kn_plus_up }
  39. ,{KN_UP, PIN_KEY_SELECT, 0xFF,0x00, kn_empty, kn_select_up ,kn_empty }
  40. ,{KN_UP, PIN_KEY_ENTER, 0xFF,0x00, kn_empty, kn_empty ,kn_enter_press }
  41. };
  42. //=============================================================================
  43. ISR(TIMER1_COMPA_vect)
  44. {
  45. #define Sta key->state
  46. #define Pin key->pins
  47. #define Cnt key->count
  48. #define Msk key->mask
  49. #define Down key->exec_down
  50. #define Up key->exec_up
  51. #define Pres key->exec_pres
  52. key_struct * key = key_mass;
  53. for(byte i=0; i< KEY_COUNT ; i++)
  54. {
  55. Pin *=2; // * or <<
  56. if(KEY_PIN & Msk) Pin |= 0x01;
  57. if(Sta == KN_UP)
  58. {
  59. if(!Pin) // начало счета - нажатие
  60. {
  61. Down();
  62. Sta = KN_DOWN;
  63. Cnt = 0x00;
  64. }
  65. }
  66. else // down or press
  67. {
  68. if(Pin==0xFF) // отпустили
  69. {
  70. if(Sta == KN_DOWN) Up();
  71. Sta = KN_UP;
  72. }
  73. else// удерживаем
  74. {
  75. if(Cnt <= TIMER_COUNT) ++Cnt;
  76. if(Cnt == TIMER_COUNT) // длительное удержание - попадаем один раз!!
  77. {
  78. if(Pres()) Cnt = TIMER_COUNT - TIMER_SCROLL;
  79. else Sta = KN_PRESS;
  80. }
  81. }
  82. }
  83. key++;
  84. }
  85. }
  86. /**
  87. Таймер в CTC-режиме на порядка 5....15 мсек
  88. */