aemlia 发表于 2014-3-28 19:47:03

【MCU实战经验】+利用stm32的systick进行键盘扫描

 之前参加电子比赛时,有用过stm32做主控制器。分享一下当时我用stm32做键盘扫描的程序,项目比较简单,望大神不鄙视。
具体思想是,通过设置systick的做一个计时器,可以设置MCU后台对键盘扫描的时间间隔。systick配置如下:
       
                                                     SysTick_CounterCmd(SysTick_Counter_Disable); 
                                                     SysTick_ITConfig(DISABLE);
                                                      SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);                                       
                                                      NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 3, 0);
                                                      SysTick_SetReload(720000);                                                                                         
                                                     SysTick_ITConfig(ENABLE);
                                                      SysTick_CounterCmd(SysTick_Counter_Enable);
程序设置为10ms中断,在systick中断里进行键盘扫描
按键代码如下:
/********************************************************************************
*文件名: keypad.c
*功能  : 键盘扫描及键值处理
*作者  : Aemlia
*日期  : 2012/3/18
*********************************************************************************/
 
#include "common.h"
 
 
u16 KeyStore=0;
u16 keyvalue=0xff;                                 //初始化按键值
static  u8 keyBackCheck=1;
       
 
/********************************************************************************
*函数名 : keyscan()
*功能   : 扫描键盘,判断是否有键按下
*输入   : 无
*输出   : 无
*返回   : 1或0
********************************************************************************/
u8 keyscan (void)
{   u16 keystate;
        GPIOA->ODR=0x00;
        keystate=GPIOC->IDR&0xf0;
        if(keystate!=0xf0)
        return 1;
        else 
        return 0;
       
}
 
/*******************************************************************************
*函数名: keyvaluecheck
*功能  : 判断键值
*输入  : 无
*输出  : 无
*返回  : KEYVALUE
*******************************************************************************/
u16 keyvaluecheck(void)
{  u16 KEYVALUE=0xff;
        GPIOA->ODR=0xfe;                                                    //第一行
        if(0==GET_GPIOC_P4)                {  KEYVALUE=0x00;        }
        else if(0==GET_GPIOC_P5)        {  KEYVALUE=0x01;        }
        else if(0==GET_GPIOC_P6)        {  KEYVALUE=0x02;}
        else if(0==GET_GPIOC_P7)        {  KEYVALUE=0x03; }
        GPIOA->ODR=0xfd;                                                                       //第二行
        if(0==GET_GPIOC_P4)                  KEYVALUE=0x04;
        else if(0==GET_GPIOC_P5)          KEYVALUE=0x05;
        else if(0==GET_GPIOC_P6)          KEYVALUE=0x06;
        else if(0==GET_GPIOC_P7)          KEYVALUE=0x07;
        GPIOA->ODR=0xfb;                                                                       //第三行
        if(0==GET_GPIOC_P4)                  KEYVALUE=0x08;
        else if(0==GET_GPIOC_P5)          KEYVALUE=0x09;
        else if(0==GET_GPIOC_P6)          KEYVALUE=0x0a;
        else if(0==GET_GPIOC_P7)          KEYVALUE=0x0b;
        GPIOA->ODR=0xf7;                                                                       //第四行
        if(0==GET_GPIOC_P4)                  KEYVALUE=0x0c;
        else if(0==GET_GPIOC_P5)          KEYVALUE=0x0d;
        else if(0==GET_GPIOC_P6)          KEYVALUE=0x0e;
        else if(0==GET_GPIOC_P7)          KEYVALUE=0x0f;
   return KEYVALUE;
       
}
/********************************************************************************
*函数名 : keycheck()
*功能   : 判断键值
*输入   : 无
*输出   : 无
*返回   : keyvalue
*说明   :状态机按键
*********************************************************************************/
void keycheck(void)
{  
   static enum STATE c_state=state0;
   switch (c_state)
   {
                   case state0 :                                         //判断是否有键按下
                            if(keyscan ())
                                           {c_state=state1;break;        }
                                        else 
                                           {c_state=state0;break; }
                case state1 :                                        //消抖
                            if(keyscan ())
                                           {c_state=state2;break;        }
                                        else 
                                           {c_state=state0;break; }
                case state2 :                                        //扫描键值
                            if(keyscan())
                                         { keyvalue=keyvaluecheck();
                                           c_state=state3;
                                               break;
                                                }
                                         else
                                           c_state=state0;
                case state3 :                                        //等待按键释放
                                       if(keyscan())
                              c_state=state3;
                                       else 
                                          c_state=state0;
                                        break;
                default     :    
                            c_state=state0;
                                        break;
    }
   return ;       
}
 
 
/*******************************************************************************
*函数名: keyprocess()
*功能  : 键值处理
*输入  : keyvalue
*输出  : 无
*说明  : 无
*******************************************************************************/
void keyprocess(u16* KEYVALUE)
{
        switch (*KEYVALUE)
        {
                case 0x00 : KeyOK();  break;
                case 0x01 : KeyUp();               break;
                case 0x02 : KeyDown();                          break;
                case 0x03 : KeyBack();             break;
                case 0x04 : chosenum(0);           break;
                case 0x05 : chosenum(1);           break;
                case 0x06 : chosenum(2);           break;
                case 0x07 : chosenum(3);           break;
                case 0x08 : chosenum(4);           break;
                case 0x09 : chosenum(5);           break;
                case 0x0a : chosenum(6);           break;
                case 0x0b : chosenum('k');         break;
                case 0x0c : chosenum(7);           break;
                case 0x0d : chosenum(8);           break;
                case 0x0e :        chosenum(9);           break;
                case 0x0f : if(g_u8inputAEnable) chosenum('.'); 
                          else   chosenum('M');  break;
        }
        *KEYVALUE=0xff;
}
 
/****************************************************************************
* 名称:KeyUp()
* 功能:按键选择上一项
* 入口参数:无
* 出口参数:无
* 说明:
****************************************************************************/
void KeyUp(void)
{
 
 
}
 
 
/****************************************************************************
* 名称:KeyDown()
* 功能:按键选择下一项
* 入口参数:无
* 出口参数:无
* 说明:用
****************************************************************************/
void KeyDown(void)
{
 
 
               

 
 
/****************************************************************************
* 名称:Key_OK()
* 功能:按键选择确定
* 入口参数:无
* 出口参数:无
* 说明:
****************************************************************************/
void KeyOK(void)
{  
       
}
 
 
 
 
/****************************************************************************
* 名称:KeyBackRoot()
* 功能:按键选择返回
* 入口参数:无
* 出口参数:无
* 说明:
****************************************************************************/
void KeyBackRoot(void)
{
       
}
 
 
 
/****************************************************************************
* 名称:KeyBack()
* 功能:按键选择返回
* 入口参数:无
* 出口参数:无
* 说明:
****************************************************************************/
void KeyBack(void)
{
       
}
 
/****************************************************************************
* 名称:RoutineProcess()
* 功能:例行程序 
* 入口参数:无
* 出口参数:无
* 说明:无
****************************************************************************/
void RoutineProcess(void)
{
  keycheck();       
}
中断里运行RoutineProcess()函数,进行键盘扫描,主程序则运行keyprocess()函数,进行按键值处理。
由于水平有限,代码可能有不完善之处,希望大神给予指正。
 
 

aemlia 发表于 2014-3-28 19:48:38

RE:【MCU实战经验】+利用stm32的systick进行键盘扫描

键盘为4*4键盘。自己先顶一下!:lol:lol:lol

蝶舞娇阳 发表于 2014-3-29 09:25:47

回复:【MCU实战经验】+利用stm32的systick进行键盘扫描

用systick与通用定时器有什么区别呢?看不出优势在哪,请指教

aemlia 发表于 2014-4-1 13:06:03

回复:【MCU实战经验】+利用stm32的systick进行键盘扫描

回复第 3 楼 于2014-03-29 09:25:47发表:
用systick与通用定时器有什么区别呢?看不出优势在哪,请指教
 
抱歉,才看到。其实systick和通用的定时器的在计数方面功能是一样的,我在这里用systick,是因为systic配置起来相对简单,再者,systick一般用于os的定时,所以这里我也借鉴了这个。
初学stm32,说的有不对的地方,望指正。
 
页: [1]
查看完整版本: 【MCU实战经验】+利用stm32的systick进行键盘扫描