打印

单片机按键状态机问题求解

[复制链接]
3581|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gxcmeluopeng|  楼主 | 2013-3-13 18:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
学习状态机遇到了问题,向论坛里的大牛求解,谢谢了!!!
#include<reg52.h>

#define uchar unsigned char
#define uint  unsigned int

#define KEY_VALUE_1              0xe0
#define KEY_VALUE_2              0xd0
#define KEY_VALUE_3              0xb0
#define KEY_VALUE_4              0x70
#define KEY_NULL                 0xf0

sbit io_key_1 = P3^4 ;
sbit io_key_2 = P3^5 ;
sbit io_key_3 = P3^6 ;
sbit io_key_4 = P3^7 ;

static uint KeyScan(void)
{
    if(io_key_1 == 0)return KEY_VALUE_1 ;
    if(io_key_2 == 0)return KEY_VALUE_2 ;
    if(io_key_3 == 0)return KEY_VALUE_3 ;
    if(io_key_4 == 0)return KEY_VALUE_4 ;
    return KEY_NULL ;
}
void KeyInit(void)
{
    io_key_1 = 1 ;
    io_key_2 = 1 ;
    io_key_3 = 1 ;
    io_key_4 = 1 ;            
}

#define KEY_LONG_PERIOD        100
#define KEY_CONTINUE_PERIOD    25

#define KEY_DOWN                0x08
#define KEY_LONG                0x04
#define KEY_CONTINUE            0x02
#define KEY_UP                  0x01

#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

unsigned char timer0_10ms_flag;

void GetKey(uint *pKeyValue)
{
    static uint s_u8KeyState = KEY_STATE_INIT ;
    static uint s_u8KeyTimeCount = 0 ;
    static uint s_u8LastKey = KEY_NULL ; //保存按键释放时候的键值
    uint KeyTemp = KEY_NULL;
    KeyTemp = KeyScan() ;        //获取键值
    switch(s_u8KeyState)
    {
        case KEY_STATE_INIT :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        s_u8KeyState = KEY_STATE_WOBBLE ;
                    }
                }
        break ;
        case KEY_STATE_WOBBLE :      //消抖
                {
                    s_u8KeyState = KEY_STATE_PRESS ;   
                }
        break ;
        case KEY_STATE_PRESS :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        s_u8LastKey = KeyTemp ; //保存键值,以便在释放按键状态返回键值
                        KeyTemp |= KEY_DOWN ; //按键按下
                        s_u8KeyState = KEY_STATE_LONG ;
                    }
                    else
                    {
                        s_u8KeyState = KEY_STATE_INIT ;
                    }
                }
        break ;
        case KEY_STATE_LONG :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)
                        {
                            s_u8KeyTimeCount = 0 ;
                            KeyTemp |= KEY_LONG ; //长按键事件发生
                            s_u8KeyState = KEY_STATE_CONTINUE ;
                        }
                    }
                    else
                    {
                        s_u8KeyState = KEY_STATE_RELEASE ;
                    }
                }
        break ;
        case KEY_STATE_CONTINUE :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        if(++s_u8KeyTimeCount > KEY_CONTINUE_PERIOD)
                        {
                            s_u8KeyTimeCount = 0 ;
                            KeyTemp |= KEY_CONTINUE ;
                        }
                    }
                    else
                    {
                        s_u8KeyState = KEY_STATE_RELEASE ;
                    }
                }
        break ;
        case KEY_STATE_RELEASE :
                {
                    s_u8LastKey |= KEY_UP ;
                    KeyTemp = s_u8LastKey ;
                    s_u8KeyState = KEY_STATE_INIT ;
                }
        break ;
        default : break ;
    }
    *pKeyValue= KeyTemp ; //返回键值   
}

void init()
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        EA=1;
        ET0=1;
        TR0=1;       
}

void timer0() interrupt 1
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        timer0_10ms_flag=1;
}
void mian()
{
        uint KeyValue=KEY_NULL;
        init();
        KeyInit();
        while(1)
        {
             Timer0MainLoop();
             KeyMainLoop(&KeyValue);
       
       
                if(KeyValue == (KEY_VALUE_1 | KEY_DOWN)) P1 = ~1 ;
       
             if(KeyValue == (KEY_VALUE_1 | KEY_LONG)) P1 = ~2 ;
       
             if(KeyValue == (KEY_VALUE_1 | KEY_CONTINUE)) { P1 ^= 0xf0;}
       
              if(KeyValue == (KEY_VALUE_1 | KEY_UP)) P1 = 0xa5 ;

        }
}
下面的两个函数怎么来的
Timer0MainLoop();
KeyMainLoop(&KeyValue);
具体的内容是什么??
向大牛求解。

       

相关帖子

沙发
一路向南| | 2013-3-14 20:56 | 只看该作者
这个程序是那位叫红金龙吸味的人写的,我用过他的这个程序。很好。。。

使用特权

评论回复
板凳
woshiaokeman| | 2013-7-4 22:52 | 只看该作者
帮顶起,我也疑惑!

使用特权

评论回复
地板
woshiaokeman| | 2013-7-9 20:46 | 只看该作者
5
outstanding| | 2013-7-20 15:17 | 只看该作者
这个代码写的不错。。

使用特权

评论回复
6
zhj2015| | 2015-7-18 20:38 | 只看该作者
我也在纠结这个问题

使用特权

评论回复
7
gjbb163| | 2015-11-6 11:35 | 只看该作者
Timer0MainLoop();这个函数可能是忘记写了吧,
KeyMainLoop(&KeyValue);,&是取地址,这个函数的形参是指针形式的,就是将键值的地址取出来,在函数内将扫描的按键值直接写入地址中,这是地址操作,

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

5

帖子

1

粉丝