2173|0

230

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

自写MSP430中断独立键盘,让大家也看看,有啥改进的 [复制链接]

本帖最后由 lingergz 于 2015-4-2 08:31 编辑

硬件上: 独立按键,按下,则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.    
  36.     TACTL = TASSEL_2 + MC_1;                  // SMCLK, contmode
  37. }

  38. /***********************************************************************************
  39. * 函数名称:ConfigureClocks()
  40. *
  41. * 函数功能:时钟初始化函数,配置时钟为1 Mhz
  42. *              
  43. * 输入参数:none
  44. *
  45. * 返回数据:none
  46. *
  47. ************************************************************************************/
  48. void SysInit()
  49. {
  50.         ConfigureClocks();
  51.   
  52.     configureTimer_A();
  53.   
  54.     ConfigureSwitches();      //配置P1的几个管脚为中断模式
  55.    
  56.    
  57. }

  58. /***********************************************************************************
  59. * 函数名称:void main(void)
  60. *
  61. * 函数功能:主函数,初始化系统,进入LPM4,等待中断唤醒后进入键盘处理函数
  62. *              
  63. * 输入参数:none
  64. *
  65. * 返回数据:none
  66. *
  67. ************************************************************************************/
  68. void main(void)  
  69. {
  70.     WDTCTL = WDTPW + WDTHOLD; // Stop WDT  
  71.         
  72.     SysInit();
  73.    
  74.     fall_eage=1;
  75.    
  76.     LPM4;
  77.    
  78.     while (1)
  79.     {            
  80.         key_process();
  81.    
  82.     }
  83. }



  84. /***********************************************************************************
  85. * 函数名称:__interrupt void Timer_A (void)
  86. *
  87. * 函数功能:定时器        A中断函数,每10ms把对应的按键计数器加 1
  88. *              
  89. * 输入参数:none
  90. *
  91. * 返回数据:none
  92. *
  93. ************************************************************************************/
  94. #pragma vector = TIMER0_A0_VECTOR
  95. __interrupt void Timer_A (void)
  96. {
  97.     switch (key_status)
  98.     {
  99.             case Zero_key:
  100.             {
  101.                     if(key_0_Tcnt<0xff)
  102.                     {
  103.                             key_0_Tcnt++;
  104.                         
  105.                     }
  106.                     else
  107.                     {
  108.                             key_0_Tcnt=0;
  109.                     }
  110.                     break;
  111.             }
  112.             case One_key:
  113.             {
  114.                     
  115.                     if(key_1_Tcnt<0xff)
  116.                     {
  117.                             key_1_Tcnt++;
  118.                         
  119.                     }
  120.                     else
  121.                     {
  122.                             key_1_Tcnt=0;
  123.                     }
  124.                     break;
  125.             }
  126.             case Two_key:
  127.             {
  128.                     
  129.                     if(key_2_Tcnt<0xff)
  130.                     {
  131.                             key_2_Tcnt++;
  132.                         
  133.                     }
  134.                     else
  135.                     {
  136.                             key_2_Tcnt=0;
  137.                     }
  138.                     break;
  139.             }            
  140.             default:
  141.                     break;
  142.                     
  143.     }
  144.    
  145. }


  146. /***********************************************************************************
  147. * 函数名称:__interrupt void Port_1()
  148. *
  149. * 函数功能:P1端口中断函数,由于端口初始化为下降沿触发,因而在检测到 下降沿时
  150. *           开启T0计数,每次间隔时间为10ms
  151. *              
  152. * 输入参数:none
  153. *
  154. * 返回数据:none
  155. *
  156. ************************************************************************************/
  157. #pragma vector=PORT1_VECTOR
  158. __interrupt void Port_1()
  159. {
  160.         if (P1IFG&Zero) //
  161.     {
  162.         key_status = Zero_key ;
  163.         P1IFG &= ~Zero;        
  164.         P1IES ^=  Zero ;    // 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.     if (P1IFG&One) //
  179.     {
  180.         key_status = One_key ;
  181.         P1IFG &= ~One;        
  182.         P1IES ^=  One ;    //P1.3 Toggle interrupt edge
  183.         if(fall_eage)
  184.             {
  185.               fall_eage=0;
  186.               CCR0 = 10000;
  187.               LPM4_EXIT;            
  188.             }
  189.             else
  190.             {
  191.                 fall_eage=1;
  192.                 CCR0 = 0;     
  193.                      
  194.             }
  195.     }
  196.    
  197. }


  198. /***********************************************************************************
  199. * 函数名称:void key_process()
  200. *
  201. * 函数功能:独立按键处理函数,可以处理长按 和 短按
  202. *              
  203. * 输入参数:none
  204. *
  205. * 返回数据:none
  206. *
  207. ************************************************************************************/
  208. void key_process()
  209. {
  210.         
  211.         if(fall_eage)
  212.     {
  213.             if(key_0_Tcnt>8)       //0 key short press
  214.                 {
  215.                         
  216.                         ;
  217.                         LPM4;
  218.                         ******
  219.                 }
  220.                 else                    //抖动
  221.                 {
  222.                         key_0_Tcnt =0;
  223.                         
  224.                 }
  225.                
  226.                 if(key_1_Tcnt>50)       //* key long press
  227.                 {
  228.                         ;
  229.                         LPM4;        
  230.                 }
  231.                 else if(key_1_Tcnt>8)   //* key short press
  232.                 {
  233.                         ;
  234.                         LPM4;
  235.                         
  236.                 }
  237.                 else                    //抖动         
  238.                 {
  239.                         key_1_Tcnt =0;
  240.                 }
  241.                
  242.                
  243.         }
  244.         else
  245.         {
  246.                 ;
  247.         }
  248. }
  249.                
  250.                


复制代码


 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表