lingergz 发表于 2015-4-1 15:54:30

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

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



   硬件上: 独立按键,按下,则I/O读到的电平为低电平
   软件上:主要思想是,
                                  配置I/0口为下降沿触发中断模式,下降沿 开启定时器计数,上升沿停止计数,
                               判断计数时间,高于500ms则为 短按,大于80小于500ms为 短按,其他为 键盘抖动,忽略掉

现在请大家看看有没有优化的空间,
同时请教下大家, 如果键盘变成 矩阵的,同样不用 延时消除抖动的方式,改怎么写代码?
                                    




/***********************************************************************************
* 函数名称:ConfigureClocks()
*
* 函数功能:时钟初始化函数,配置时钟为1 Mhz
*            
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void ConfigureClocks()
{
    if (CALBC1_1MHZ==0xFF || CALDCO_1MHZ==0xFF)                                    
    {
      while(1);    // If calibration constants erased
                           // do not load, trap CPU!!
    }      
    /* Configure Clocks */
    BCSCTL1 = CALBC1_1MHZ;   // Set DCO
    DCOCTL = CALDCO_1MHZ;      //
}

/***********************************************************************************
* 函数名称: configureTimer_A()
*
* 函数功能: 定时器A初始化函数,配置为向上计数模式,即从 0 开始到 TACCR0 的值重复计数
*            
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void configureTimer_A()
{
    CCTL0 = CCIE;                           // CCR0 interrupt enabled
   
    TACTL = TASSEL_2 + MC_1;                  // SMCLK, contmode
}

/***********************************************************************************
* 函数名称:ConfigureClocks()
*
* 函数功能:时钟初始化函数,配置时钟为1 Mhz
*            
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void SysInit()
{
        ConfigureClocks();

    configureTimer_A();

    ConfigureSwitches();      //配置P1的几个管脚为中断模式
   
   
}

/***********************************************************************************
* 函数名称:void main(void)
*
* 函数功能:主函数,初始化系统,进入LPM4,等待中断唤醒后进入键盘处理函数
*            
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
      
    SysInit();
   
    fall_eage=1;
   
    LPM4;
   
    while (1)
    {           
      key_process();
   
    }
}



/***********************************************************************************
* 函数名称:__interrupt void Timer_A (void)
*
* 函数功能:定时器        A中断函数,每10ms把对应的按键计数器加 1
*            
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
    switch (key_status)
    {
            case Zero_key:
            {
                    if(key_0_Tcnt<0xff)
                  {
                          key_0_Tcnt++;
                       
                  }
                  else
                  {
                          key_0_Tcnt=0;
                  }
                    break;
            }
            case One_key:
            {
                   
                    if(key_1_Tcnt<0xff)
                  {
                          key_1_Tcnt++;
                       
                  }
                  else
                  {
                          key_1_Tcnt=0;
                  }
                    break;
            }
            case Two_key:
            {
                   
                    if(key_2_Tcnt<0xff)
                  {
                          key_2_Tcnt++;
                       
                  }
                  else
                  {
                          key_2_Tcnt=0;
                  }
                    break;
            }           
            default:
                    break;
                   
    }
   
}


/***********************************************************************************
* 函数名称:__interrupt void Port_1()
*
* 函数功能:P1端口中断函数,由于端口初始化为下降沿触发,因而在检测到 下降沿时
*         开启T0计数,每次间隔时间为10ms
*            
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
#pragma vector=PORT1_VECTOR
__interrupt void Port_1()
{
        if (P1IFG&Zero) //
    {
      key_status = Zero_key ;
      P1IFG &= ~Zero;      
      P1IES ^=Zero ;    // Toggle interrupt edge
      if(fall_eage)
          {
              fall_eage=0;
              CCR0 = 10000;   //开启定时器   
              LPM4_EXIT;            
          }
          else
          {
                fall_eage=1;
                CCR0 = 0;      //关闭定时器
                   
          }
    }
    if (P1IFG&One) //
    {
      key_status = One_key ;
      P1IFG &= ~One;      
      P1IES ^=One ;    //P1.3 Toggle interrupt edge
      if(fall_eage)
          {
              fall_eage=0;
              CCR0 = 10000;
              LPM4_EXIT;            
          }
          else
          {
                fall_eage=1;
                CCR0 = 0;   
                      
          }
    }
   
}


/***********************************************************************************
* 函数名称:void key_process()
*
* 函数功能:独立按键处理函数,可以处理长按 和 短按
*            
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void key_process()
{
       
        if(fall_eage)
    {
            if(key_0_Tcnt>8)       //0 key short press
                {
                       
                        ;
                        LPM4;
                        ******
                }
                else                  //抖动
                {
                        key_0_Tcnt =0;
                       
                }
               
                if(key_1_Tcnt>50)       //* key long press
                {
                        ;
                        LPM4;       
                }
                else if(key_1_Tcnt>8)   //* key short press
                {
                        ;
                        LPM4;
                       
                }
                else                  //抖动         
                {
                        key_1_Tcnt =0;
                }
               
               
        }
        else
        {
                ;
        }
}
               
               


hwh1328 发表于 2015-6-27 19:11:44

个人想法: 按键必须有延时去抖,如果只是单按键,又不担心定时器资源不够用,那可以用输入捕获方式来计算宽度(不过这只是理论,因为没法去抖); 矩阵定时器法觉得不行。

lingergz 发表于 2015-7-2 10:55:39

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

矩阵按键 怎么做呢
页: [1]
查看完整版本: 自写MSP430中断独立键盘,让大家也看看,有啥改进的