[讨论] 自写MSP430中断独立键盘,让大家也看看,有啥改进的

lingergz   2015-4-1 15:59 楼主
硬件上: 独立按键,按下,则I/O读到的电平为低电平 软件上:主要思想是, 配置I/0口为下降沿触发中断模式,下降沿 开启定时器计数,上升沿停止计数, 判断计数时间,高于500ms则为 短按,大于80小于500ms为 短按,其他为 键盘抖动,忽略掉 现在请大家看看有没有优化的空间, 同时请教下大家, 如果键盘变成 矩阵的,同样不用 延时消除抖动的方式,改怎么写代码?
  1. /***********************************************************************************
  2. * 函数名称:ConfigureClocks()
  3. *
  4. * 函数功能:时钟初始化函数,配置时钟为1 Mhz
  5. *
  6. * 输入参数:none
  7. *
  8. * 返回数据:none
  9. *
  10. ************************************************************************************/
  11. void ConfigureClocks()
  12. {
  13. if (CALBC1_1MHZ==0xFF || CALDCO_1MHZ==0xFF)
  14. {
  15. while(1); // If calibration constants erased
  16. // do not load, trap CPU!!
  17. }
  18. /* Configure Clocks */
  19. BCSCTL1 = CALBC1_1MHZ; // Set DCO
  20. DCOCTL = CALDCO_1MHZ; //
  21. }
  22. /***********************************************************************************
  23. * 函数名称: configureTimer_A()
  24. *
  25. * 函数功能: 定时器A初始化函数,配置为向上计数模式,即从 0 开始到 TACCR0 的值重复计数
  26. *
  27. * 输入参数:none
  28. *
  29. * 返回数据:none
  30. *
  31. ************************************************************************************/
  32. void configureTimer_A()
  33. {
  34. CCTL0 = CCIE; // CCR0 interrupt enabled
  35. TACTL = TASSEL_2 + MC_1; // SMCLK, contmode
  36. }
  37. /***********************************************************************************
  38. * 函数名称:ConfigureClocks()
  39. *
  40. * 函数功能:时钟初始化函数,配置时钟为1 Mhz
  41. *
  42. * 输入参数:none
  43. *
  44. * 返回数据:none
  45. *
  46. ************************************************************************************/
  47. void SysInit()
  48. {
  49. ConfigureClocks();
  50. configureTimer_A();
  51. ConfigureSwitches(); //配置P1的几个管脚为中断模式
  52. }
  53. /***********************************************************************************
  54. * 函数名称:void main(void)
  55. *
  56. * 函数功能:主函数,初始化系统,进入LPM4,等待中断唤醒后进入键盘处理函数
  57. *
  58. * 输入参数:none
  59. *
  60. * 返回数据:none
  61. *
  62. ************************************************************************************/
  63. void main(void)
  64. {
  65. WDTCTL = WDTPW + WDTHOLD; // Stop WDT
  66. SysInit();
  67. fall_eage=1;
  68. LPM4;
  69. while (1)
  70. {
  71. key_process();
  72. }
  73. }
  74. /***********************************************************************************
  75. * 函数名称:__interrupt void Timer_A (void)
  76. *
  77. * 函数功能:定时器 A中断函数,每10ms把对应的按键计数器加 1
  78. *
  79. * 输入参数:none
  80. *
  81. * 返回数据:none
  82. *
  83. ************************************************************************************/
  84. #pragma vector = TIMER0_A0_VECTOR
  85. __interrupt void Timer_A (void)
  86. {
  87. switch (key_status)
  88. {
  89. case Zero_key:
  90. {
  91. if(key_0_Tcnt<0xff)
  92. {
  93. key_0_Tcnt++;
  94. }
  95. else
  96. {
  97. key_0_Tcnt=0;
  98. }
  99. break;
  100. }
  101. case One_key:
  102. {
  103. if(key_1_Tcnt<0xff)
  104. {
  105. key_1_Tcnt++;
  106. }
  107. else
  108. {
  109. key_1_Tcnt=0;
  110. }
  111. break;
  112. }
  113. case Two_key:
  114. {
  115. if(key_2_Tcnt<0xff)
  116. {
  117. key_2_Tcnt++;
  118. }
  119. else
  120. {
  121. key_2_Tcnt=0;
  122. }
  123. break;
  124. }
  125. default:
  126. break;
  127. }
  128. }
  129. /***********************************************************************************
  130. * 函数名称:__interrupt void Port_1()
  131. *
  132. * 函数功能:P1端口中断函数,由于端口初始化为下降沿触发,因而在检测到 下降沿时
  133. * 开启T0计数,每次间隔时间为10ms
  134. *
  135. * 输入参数:none
  136. *
  137. * 返回数据:none
  138. *
  139. ************************************************************************************/
  140. #pragma vector=PORT1_VECTOR
  141. __interrupt void Port_1()
  142. {
  143. if (P1IFG&Zero) //
  144. {
  145. key_status = Zero_key ;
  146. P1IFG &= ~Zero;
  147. P1IES ^= Zero ; // Toggle interrupt edge
  148. if(fall_eage)
  149. {
  150. fall_eage=0;
  151. CCR0 = 10000; //开启定时器
  152. LPM4_EXIT;
  153. }
  154. else
  155. {
  156. fall_eage=1;
  157. CCR0 = 0; //关闭定时器
  158. }
  159. }
  160. if (P1IFG&One) //
  161. {
  162. key_status = One_key ;
  163. P1IFG &= ~One;
  164. P1IES ^= One ; //P1.3 Toggle interrupt edge
  165. if(fall_eage)
  166. {
  167. fall_eage=0;
  168. CCR0 = 10000;
  169. LPM4_EXIT;
  170. }
  171. else
  172. {
  173. fall_eage=1;
  174. CCR0 = 0;
  175. }
  176. }
  177. }
  178. /***********************************************************************************
  179. * 函数名称:void key_process()
  180. *
  181. * 函数功能:独立按键处理函数,可以处理长按 和 短按
  182. *
  183. * 输入参数:none
  184. *
  185. * 返回数据:none
  186. *
  187. ************************************************************************************/
  188. void key_process()
  189. {
  190. if(fall_eage)
  191. {
  192. if(key_0_Tcnt>8) //0 key short press
  193. {
  194. ;
  195. LPM4;
  196. ******
  197. }
  198. else //抖动
  199. {
  200. key_0_Tcnt =0;
  201. }
  202. if(key_1_Tcnt>50) //* key long press
  203. {
  204. ;
  205. LPM4;
  206. }
  207. else if(key_1_Tcnt>8) //* key short press
  208. {
  209. ;
  210. LPM4;
  211. }
  212. else //抖动
  213. {
  214. key_1_Tcnt =0;
  215. }
  216. }
  217. else
  218. {
  219. ;
  220. }
  221. }
本帖最后由 lingergz 于 2015-4-2 08:31 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复