搜索
bottom↓
回复: 2

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

[复制链接]

出0入0汤圆

发表于 2015-4-1 15:54:30 | 显示全部楼层 |阅读模式
本帖最后由 lingergz 于 2015-4-2 08:32 编辑



   硬件上: 独立按键,按下,则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.                


复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。

出0入0汤圆

发表于 2015-6-27 19:11:44 | 显示全部楼层
个人想法: 按键必须有延时去抖,如果只是单按键,又不担心定时器资源不够用,那可以用输入捕获方式来计算宽度(不过这只是理论,因为没法去抖); 矩阵定时器法觉得不行。

出0入0汤圆

 楼主| 发表于 2015-7-2 10:55:39 | 显示全部楼层
hwh1328 发表于 2015-6-27 19:11
个人想法: 按键必须有延时去抖,如果只是单按键,又不担心定时器资源不够用,那可以用输入捕获方式来计算 ...

矩阵按键 怎么做呢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-9-21 09:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表