一路向南 发表于 2013-2-8 20:31:37

4x4矩阵按键求助贴

本帖最后由 一路向南 于 2013-2-8 20:35 编辑

关注马老师的板块有一段时间了,自己也试着用状态机写了一个4x4矩阵按键的程序,调试了好久没成功,无奈来坛子求助,获得更好的解决方法。
上程序:#include <reg52.h>
#include "MacroAndConst.h"
#include "Timer.h"
#include "Key.h"

#define KEYBOARD        P2

sbit C1 = KEYBOARD^0;
sbit C2 = KEYBOARD^1;
sbit C3 = KEYBOARD^2;
sbit C4 = KEYBOARD^3;

sbit R1 = KEYBOARD^7;
sbit R2 = KEYBOARD^6;
sbit R3 = KEYBOARD^5;
sbit R4 = KEYBOARD^4;



/**********************用户操作区宏定义****************************/


//---------------------按键阀值宏定义-----------------------------
#define KEY_LONG_PRIOD                                100
#define KEY_CONTINUE_PRIOD                        50

                                       

//---------------------按键状态定义-------------------------------
#define KEY_STATE_INIT                        0
#define KEY_STATE_WOBBLE                1
#define KEY_STATE_PRESS                        2
#define KEY_STATE_LONG                        3
#define KEY_STATE_CONTINUE                4
#define KEY_STATE_RELEASE                5




/************************按键初始化*******************************/
void Keyboard_Init(void)
{
        C1 = 1;
        C2 = 1;
        C3 = 1;
        C4 = 1;
        R1 = 1;
        R2 = 1;
        R3 = 1;
        R4 = 1;
}

/**********************底层按键驱动**************************/
uint8 Keyboard_Scan(void)
{
        C1 = 0;
                if (R1 == 0)                return KEY_VALUE_1;
                if (R2 == 0)                return KEY_VALUE_2;
                if (R3 == 0)                return KEY_VALUE_3;
                if (R4 == 0)                return KEY_VALUE_4;
        C2 = 0;
                if (R1 == 0)                return KEY_VALUE_5;
                if (R2 == 0)                return KEY_VALUE_6;
                if (R3 == 0)                return KEY_VALUE_7;
                if (R4 == 0)                return KEY_VALUE_8;
        C3 = 0;
                if (R1 == 0)                return KEY_VALUE_9;
                if (R2 == 0)                return KEY_VALUE_10;
                if (R3 == 0)                return KEY_VALUE_11;
                if (R3 == 0)                return KEY_VALUE_12;
        C4 = 0;
                if (R1 == 0)                return KEY_VALUE_13;
                if (R2 == 0)                return KEY_VALUE_14;
                if (R3 == 0)                return KEY_VALUE_15;
                if (R4 == 0)                return KEY_VALUE_16;
               
                return KEY_NULL;                       
}

uint8 Get_Key()
{
        static uint8 key_state = KEY_STATE_INIT;
        static uint8 key_time_count = 0,KeyValue,last_key;
        uint8 key_temp;


        key_temp = Keyboard_Scan();
        switch (key_state)
        {
                case KEY_STATE_INIT:
                        if (key_temp != KEY_NULL)
                        {
                                key_state = KEY_STATE_WOBBLE;
                        }
                break;
                case KEY_STATE_WOBBLE:
                        key_state = KEY_STATE_PRESS;
                break;
                case KEY_STATE_PRESS:
                        if (key_temp != KEY_NULL)       
                        {
                                last_key = key_temp;                //保存键值,
                                KeyValue= KEY_DOWN;       
                                key_state = KEY_STATE_LONG;
                        }        
                        else
                        {
                                key_state = KEY_STATE_INIT;
                        }
                        break;
                case KEY_STATE_LONG:
                        if (key_temp != KEY_NULL)
                        {
                                if (++key_time_count >= KEY_LONG_PRIOD)
                                {
                                        key_time_count = 0;
                                        KeyValue = KEY_LONG;                //长按事件发生
                                        key_state = KEY_STATE_CONTINUE;
                                }
                        }
                        else
                        {
                                key_state = KEY_STATE_RELEASE;
                        }
                        break;
                case KEY_STATE_CONTINUE:
                        if (key_temp != KEY_NULL)
                        {
                                if (++key_time_count >= KEY_CONTINUE_PRIOD)
                                {
                                        key_time_count = 0;
                                        KeyValue= KEY_CONTINUE;
                                }
                        }
                        else
                        {
                                key_state = KEY_STATE_RELEASE;
                        }
                break;
                case KEY_STATE_RELEASE:
                {
                        KeyValue = KEY_UP;
                        key_temp = last_key;
                        key_state = KEY_STATE_INIT;
                }
                break;
                default : break;
        }
   return KeyValue;        //返回键值
}
页: [1]
查看完整版本: 4x4矩阵按键求助贴