打印

请教一个独立按键的问题

[复制链接]
5571|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xppx1987|  楼主 | 2012-12-5 14:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
按键端口的定义,如下所示:
sbit io_key_1 = P3^0 ;
sbit io_key_2 = P3^1 ;
sbit io_key_3 = P3^2 ;
sbit io_key_4 = P3^3 ;

根据按键硬件连接定义按键键值
#define KEY_VALUE_1 0x0e
#define KEY_VALUE_2 0x0d
#define KEY_VALUE_3 0x0b
#define KEY_VALUE_4 0x07
#define KEY_NULL 0x0f

按键的硬件驱动程序。
static uint8 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 ;
}

这是之前看的一篇**中的按键检测程序,由于实际中这四个按键分别接在不同的IO端口上如P00、P11、P22、P33上,那么该如何根据按键硬件连接定义修改按键键值呐?


相关帖子

沙发
ayb_ice| | 2012-12-5 14:48 | 只看该作者
想什么值都可以的,使用时对应即可

使用特权

评论回复
板凳
xppx1987|  楼主 | 2012-12-5 14:55 | 只看该作者
ayb_ice 发表于 2012-12-5 14:48
想什么值都可以的,使用时对应即可

那为什么只有一个按键有效呐?始终只有一个按键有用,其它的都没反应,但是如果像上面接在P30-P33上四个按键都有效!不解?求大侠赐教!

使用特权

评论回复
地板
zxb1717| | 2012-12-5 15:04 | 只看该作者
static uint8 KeyScan(void)
函数中没有个条件不是return了吗,当然只有一个有效了,也就是最先按下的那个有效

使用特权

评论回复
5
xuxikfg| | 2012-12-5 15:12 | 只看该作者
果断围观。。。

使用特权

评论回复
6
xppx1987|  楼主 | 2012-12-5 15:14 | 只看该作者
zxb1717 发表于 2012-12-5 15:04
static uint8 KeyScan(void)
函数中没有个条件不是return了吗,当然只有一个有效了,也就是最先按下的那个 ...

您好!是这样的,如果像上面端口是连接在P30-P34上,而且程序也像上面那样写,完全没有任何问题,四个按键功能都可以实现,但是现在若是接两个按键到P00和P11端口上的话,只是修改了端口定义,然后屏蔽掉剩余两个按键定义,最后发现只有一个按键功能有效,很是不解,希望大侠赐教!

使用特权

评论回复
7
xppx1987|  楼主 | 2012-12-5 15:16 | 只看该作者
xuxikfg 发表于 2012-12-5 15:12
果断围观。。。

求解啊:dizzy:

使用特权

评论回复
8
xppx1987|  楼主 | 2012-12-5 15:20 | 只看该作者
zxb1717 发表于 2012-12-5 15:04
static uint8 KeyScan(void)
函数中没有个条件不是return了吗,当然只有一个有效了,也就是最先按下的那个 ...

换了端口连接后,是不是按键键值的宏定义也要一起修改呢?

使用特权

评论回复
9
xppx1987|  楼主 | 2012-12-5 15:31 | 只看该作者
不解啊,各位大侠看哈到底是什么问题啊?

使用特权

评论回复
10
ayb_ice| | 2012-12-5 15:32 | 只看该作者
推荐使用以下方式


typedef U8 unsigned char;

#define BIT0        0x01
#define BIT1        0x02
#define BIT2        0x04
#define BIT3        0x08
#define BIT4        0x10
#define BIT5        0x20
#define BIT6        0x40
#define BIT7        0x80


static uint8 KeyScan(void)
{
        U8 k = 0;

        if(io_key_1 == 0){
                k |= BIT0;
        }
        if(io_key_2 == 0){
                k |= BIT1;
        }
        if(io_key_3 == 0){
                k |= BIT2;
        }
        if(io_key_4 == 0){
                k |= BIT3;
        }

        return k;
}

        使用时如下
        switch(key_number){
        case BIT0:
        case BIT1:
        case BIT3:
        case BIT4:
                ...
        case BIT0+BIT1:        // K1+K2
                ....
        }

使用特权

评论回复
11
xppx1987|  楼主 | 2012-12-5 16:00 | 只看该作者
本帖最后由 xppx1987 于 2012-12-5 16:43 编辑
ayb_ice 发表于 2012-12-5 15:32
推荐使用以下方式


换了您这种方法还是只有一个按键有效,现把自己按您说的方式修改的程序贴出来,看到底哪儿出错了?
//端口定义
#define io_key_1 RB0
#define io_key_2 RA1

#define BIT0        0x01
#define BIT1        0x02
//定义长按键的TICK 数,以及连发间隔的TICK 数
#define KEY_LONG_PERIOD 20
#define KEY_CONTINUE_PERIOD 5
//定义按键返回值状态(按下,长按,连发,释放)
#define KEY_DOWN 0x80
#define KEY_LONG 0x40
#define KEY_CONTINUE 0x20
#define KEY_UP 0x10
//定义按键状态
#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
//键值读取函数
static uchar KeyScan(void)
{
        uchar k=0;
        if(io_key_1 == 0)
        {
                k|=BIT0;
        }
        if(io_key_2 == 0)
        {
                k|=BIT1;
        }
        return k;
}
//按键操作函数
void GetKey(uchar *pKeyValue)
{
        static uchar s_u8KeyState=KEY_STATE_INIT;
        static uchar s_u8KeyTimeCount=0;
        static uchar s_u8LastKey=KEY_NULL; //保存按键释放时候的键值
        uchar KeyTemp=0;
        KeyTemp=KeyScan(); //获取键值
        switch(s_u8KeyState)
        {
                case KEY_STATE_INIT :
                {
                        if(KeyTemp!=0)
                        {
                                s_u8KeyState=KEY_STATE_WOBBLE ;
                        }
                }
                break ;
                case KEY_STATE_WOBBLE: //消抖
                {
                        s_u8KeyState=KEY_STATE_PRESS ;
                }
                break ;
                case KEY_STATE_PRESS :
                {
                        if(KeyTemp!=0)
                        {
                                s_u8LastKey=KeyTemp ; //保存键值,以便在释放按键状态返回键值
                                KeyTemp|=KEY_DOWN ; //按键按下
                                s_u8KeyState=KEY_STATE_LONG ;
                        }
                        else
                        {
                                s_u8KeyState=KEY_STATE_INIT ;
                        }
                }
                break ;
                case KEY_STATE_LONG :
                {
                        if(KeyTemp!=0)
                        {
                                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(KeyTemp!=0)
                        {
                                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 main()///////////函数主程序
{
        float i,j;
        while(1)
       {
        if(time10ms_ok==1)
        {
                  time10ms_ok=0;
                  GetKey(&KeyValue);
                  if(KeyValue==(BIT0|KEY_DOWN))
                  {
                            j++;
                   }
                   if(KeyValue==(BIT1|KEY_DOWN))
                  {
                          i++;
                  }

        }
        }
}

使用特权

评论回复
12
wangyy608| | 2012-12-5 16:29 | 只看该作者
如果1楼的程序能正常,那只需要重新定义端口,按键就能正常工作

使用特权

评论回复
13
xppx1987|  楼主 | 2012-12-5 16:45 | 只看该作者
wangyy608 发表于 2012-12-5 16:29
如果1楼的程序能正常,那只需要重新定义端口,按键就能正常工作

程序能正常运行啊,我移植过来后也重新定义了端口啊,但是却只有一个按键能够正常工作。什么原因呢?

使用特权

评论回复
14
ZG11211| | 2012-12-5 17:40 | 只看该作者
l主要是楼主没有理解程序的含义,当按键按下以后,按键执行程序会返回一个状态给端口,而且贴出来的程序也不全,返回值如何处理也没说,只能猜测是返回到P3口,作为一个互动机制,如果楼主非要移动按键口,那么就要看这个返回值转移到哪里了,为了达到原机设计,估计要改动一部分程序才行

使用特权

评论回复
15
wangyy608| | 2012-12-5 17:49 | 只看该作者
端口有没有初始化。。。

使用特权

评论回复
16
xppx1987|  楼主 | 2012-12-5 18:36 | 只看该作者
搞定!

使用特权

评论回复
17
lirunze| | 2012-12-5 19:07 | 只看该作者
路过一下啊

使用特权

评论回复
18
hdl551890| | 2012-12-6 09:30 | 只看该作者
有必要怎么复杂?

使用特权

评论回复
19
jiabin1024| | 2012-12-6 10:09 | 只看该作者
楼主用的PIC单片机,在使用数字端口功能时一定要根据应用配置好的,这个跟51有点不同。

使用特权

评论回复
20
21IC之星| | 2012-12-6 10:33 | 只看该作者

使用特权

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

本版积分规则

5

主题

153

帖子

2

粉丝