Key.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "Key.h"
  2. /*本文件的函数,主要实现矩阵键盘的功能。矩阵键盘使用PA0到PA7引脚,其中,PA0到PA3固定为推挽输出,PA4到PA7固定为
  3. 下拉输入。即,无键按下时,对应PA4到PA7为0,有键按下时,PA4到PA7中,对应的引脚为高。
  4. 此程序有一点要注意:要用到的IO口,必须是PX0-PX7,,不能是其他连续的数字。。如果非要改。。如:已经没有连续的0-7的IO口,需要在几个地方修改,请注意!!
  5. 此程序带有松手检测。。。。*/
  6. void GPIO_ConfigurationKey ( void ) //初始化矩阵键盘要使用的GPIO口。
  7. {
  8. #if key16_def
  9. GPIO_InitTypeDef GPIOStru;
  10. RCC_APB2PeriphClockCmd ( KEY16_RCC_CONFIG, ENABLE );
  11. GPIOStru.GPIO_Mode = GPIO_Mode_Out_PP; //定义PA0到PA3为推挽输出。
  12. GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
  13. GPIOStru.GPIO_Pin = KEY16_OUTPIN_CONFIG;
  14. GPIO_Init ( KEY16_PORT_CONFIG, &GPIOStru );
  15. GPIOStru.GPIO_Mode = GPIO_Mode_IPD; //定义PA4到PA7为下拉输入。
  16. GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
  17. GPIOStru.GPIO_Pin = KEY16_INPIN_CONFIG;
  18. GPIO_Init ( KEY16_PORT_CONFIG, &GPIOStru );
  19. #endif
  20. }
  21. unsigned short ScanKey ( void ) //实现矩阵键盘。返回值为,各按键的键值,此键值由用户自己定义。
  22. {
  23. unsigned short KeyVal = 0x0000; //keyVal为最后返回的键值。
  24. GPIO_Write ( KEY16_PORT_CONFIG, ( KEY16_PORT_CONFIG->ODR & 0xfff0 | 0xf ) ); //先让PA0到PA3全部输出高。
  25. if ( ( KEY16_PORT_CONFIG->IDR & 0x00f0 ) == 0x0000 ) //如果,PA4到PA7全为0,则,没有键按下。此时,返回值为-1.
  26. return KeyVal;
  27. GPIO_Write ( KEY16_PORT_CONFIG, ( KEY16_PORT_CONFIG->ODR & 0xfff0 | 0x1 ) ); //让PA3到PA0输出二进制的0001.
  28. KeyVal |= ( ( KEY16_PORT_CONFIG->IDR & 0x00f0 ) >> 4 ) << 0;
  29. GPIO_Write ( KEY16_PORT_CONFIG, ( KEY16_PORT_CONFIG->ODR & 0xfff0 | 0x2 ) ); //让PA3到PA0输出二进制的0010.
  30. KeyVal |= ( ( KEY16_PORT_CONFIG->IDR & 0x00f0 ) >> 4 ) << 4;
  31. GPIO_Write ( KEY16_PORT_CONFIG, ( KEY16_PORT_CONFIG->ODR & 0xfff0 | 0x4 ) ); //让PA3到PA0输出二进制的0100.
  32. KeyVal |= ( ( KEY16_PORT_CONFIG->IDR & 0x00f0 ) >> 4 ) << 8;
  33. GPIO_Write ( KEY16_PORT_CONFIG, ( KEY16_PORT_CONFIG->ODR & 0xfff0 | 0x8 ) ); //让PA3到PA0输出二进制的1000.
  34. KeyVal |= ( ( KEY16_PORT_CONFIG->IDR & 0x00f0 ) >> 4 ) << 12;
  35. return KeyVal;
  36. }
  37. /*tea5767
  38. K11: up+
  39. K12: down-
  40. */
  41. /*ds1302
  42. K13: 开机时间复位
  43. K14: 菜单
  44. K15: up+
  45. K16: down-
  46. */
  47. pKey Keys[16] =
  48. {
  49. {0x00, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  50. {0x01, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  51. {0x02, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  52. {0x03, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  53. {0x04, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  54. {0x05, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  55. {0x06, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  56. {0x07, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  57. {0x08, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  58. {0x09, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  59. {0x0A, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  60. {0x0B, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  61. {0x0C, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  62. {0x0D, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  63. {0x0E, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG},
  64. {0x0F, KEY_UP_FLAG, 0, 0, 0, NO_KEY_FLAG}
  65. };
  66. //每40ms,进入一次
  67. /*
  68. 判断点:
  69. 1.down: 400
  70. down<120, == 无效,去抖动
  71. 120<=down<400, == 进入2.继续判断
  72. 2.down: 400 + up:400
  73. up<400, == 进入3.继续判断
  74. up>400, == 短按
  75. 3.down: 400 + up:400 + down: 400
  76. down>1200, == 长按
  77. down<400, == 单击++
  78. */
  79. void KeyHander ( void )
  80. {
  81. #if key16_def
  82. unsigned short KeyVal = 0;
  83. unsigned char i;
  84. KeyVal = ScanKey();
  85. for ( i = 0; i < 16; i++ )
  86. {
  87. Keys[i].State = KeyVal & ( 1 << Keys[i].ID ) ? KEY_DOWN_FLAG : KEY_UP_FLAG;
  88. if ( Keys[i].State == KEY_DOWN_FLAG )
  89. {
  90. Keys[i].DnTime++;
  91. //超过1.2s,长按
  92. if ( ( Keys[i].DnTime > LONG_KEY_DOWN ) && ( Keys[i].Res != LONG_KEY_FLAG ) )
  93. {
  94. Keys[i].Res = LONG_KEY_FLAG;
  95. Keys[i].HitNum = 0;
  96. }
  97. if ( Keys[i].UpTime > 0 )
  98. {
  99. Keys[i].UpTime = 0;
  100. }
  101. }
  102. else if ( Keys[i].State == KEY_UP_FLAG )
  103. {
  104. Keys[i].UpTime ++;
  105. if ( Keys[i].UpTime < CANCEL_KEY_UP )
  106. {
  107. //松开0-320ms
  108. if ( Keys[i].DnTime > 0 )
  109. {
  110. //根据按下时间,判断:
  111. if ( Keys[i].DnTime < CANCEL_KEY_DOWN ) //1.抖动
  112. {
  113. Keys[i].Res = NO_KEY_FLAG;
  114. }
  115. else if ( Keys[i].DnTime < SHORT_KEY_DOWN ) //2.单击++
  116. {
  117. Keys[i].HitNum ++;
  118. }
  119. Keys[i].DnTime = 0;
  120. }
  121. }
  122. else if ( Keys[i].UpTime < ( CANCEL_KEY_UP + HANDLE_KEY_TIME ) )
  123. {
  124. //松开320-440ms,判断
  125. if ( Keys[i].HitNum > 0 ) //3.判断
  126. {
  127. if ( Keys[i].HitNum == 1 ) Keys[i].Res = ONE_HITS_KEY_FLAG;
  128. else if ( Keys[i].HitNum == 2 ) Keys[i].Res = TWO_HITS_KEY_FLAG;
  129. else if ( Keys[i].HitNum == 3 ) Keys[i].Res = THREE_HITS_KEY_FLAG;
  130. Keys[i].HitNum = 0;
  131. }
  132. }
  133. else if ( Keys[i].Res != NO_KEY_FLAG )
  134. {
  135. //松开400ms,状态变为, 无按键
  136. Keys[i].Res = NO_KEY_FLAG;
  137. }
  138. }
  139. }
  140. #endif
  141. }