搜索
bottom↓
回复: 0

请教马潮老师:矩阵键盘+线翻转+状态机 调试问题

[复制链接]

出0入0汤圆

发表于 2012-3-2 16:21:06 | 显示全部楼层 |阅读模式
请教马潮老师以及各位大侠:

之前看马潮老师有关矩阵键盘的状态机方法的讲解,刚好有个设计中有涉及到矩阵键盘(3*3矩阵,实际用到7个按键),只不过还需要识别按键的长短按,我就把马老师的程序改了改,结果在调试的时候按键没有反应!硬件应该是没有问题的,我用延时消抖的方式已经能够识别7个按键了,只是长短按键的识别不好设计,我才改用状态机,并用定时器定时扫描的方式来设计,可能我的代码有问题吧,下面贴上代码,还请各位大侠指教!!!

/*********************************************************/
/* 读取当前键值:线反转法                                */
/*********************************************************/

unsigned char MatrixKeyRead_LineReverse(void)
{
unsigned char keycodeC = 0;
unsigned char keycodeR = 0;

DDRD &= 0x03;//这里是为了不影响串口RXD和TXD的设置

DDRD |= 0x1c;// PD7~PD5输入,PD4~PD2输出

PORTD &= 0x03;//同样是为了不影响串口RXD和TXD的设置

PORTD |= 0xe0;// PD7~PD5内部上拉,PD4~PD2输出低电平

keycodeC = PIND & 0xe0;

DDRD &= 0x03;

DDRD |= 0xe0;// PD7~PD5输出,PD4~PD2输入

PORTD &= 0x03;

PORTD |= 0x1c;// PD7~PD5输出低电平,PD4~PD2内部上拉

keycodeR = PIND & 0x1c;

return (keycodeC | keycodeR);
}

/*********************************************************/
/* 按键扫描:状态机                                      */
/*********************************************************/

void MatrixKeyScan(stKeyReturn * ps_keyReturn)
{
static etKeyState e_keyState = KEY_STATE_KEY_NO_PRESS;

etKeyCode e_keyCode = KEY_NO_PRESS;

etKeyCode e_keyCodeTmp = KEY_NO_PRESS;

static unsigned char keyHoldTimeCnt = 0;

e_keyCode = MatrixKeyRead_LineReverse();
       
        switch(e_keyState)
        {
                case KEY_STATE_KEY_NO_PRESS:                                // 按键状态0:无按键
                {
                        if(e_keyCode != KEY_NO_PRESS)                        // 有键按下,转入按键状态1:按键消抖
                        {                               
                                e_keyState = KEY_STATE_KEY_FILTER;       
                        }

                        break;
                }

                case KEY_STATE_KEY_FILTER:                                        // 按键状态1:按键消抖
                {
                        if(e_keyCode != KEY_NO_PRESS)                        // 有键按下,确定按键,打开计数器,转入按键状态2:按键延时
                        {
                                keyHoldTimeCnt = 0;

//                                s_keyReturn.keyCode = e_keyCode;

                                e_keyCodeTmp = e_keyCode;

                                e_keyState = KEY_STATE_KEY_HOLD_TIME;
                        }
                        else                                                                        // 无键按下,转入按键状态0:无按键
                        {
                                e_keyState = KEY_STATE_KEY_NO_PRESS;
                        }

                        break;
                }

                case KEY_STATE_KEY_HOLD_TIME:                                // 按键状态2:按键延时
                {
                        if(e_keyCode == KEY_NO_PRESS)                        // 如果按键已经释放,确定为短按键及其键值,转入状态0:无按键
                        {
                                ps_keyReturn->keyCode = e_keyCodeTmp;
                               
                                ps_keyReturn->keyType = KEY_TYPE_KEY_SHORT_PRESS;

                                e_keyState = KEY_STATE_KEY_NO_PRESS;        
                        }
                        else if((++ keyHoldTimeCnt) > 100)                // 如果计时超过规定时间仍然没有释放,转入状态3:长按键释放
                        {
//                                s_keyReturn.keyType = KEY_TYPE_KEY_LONG_PRESS;

                                e_keyState = KEY_STATE_KEY_RELEASE;
                        }

                        break;
                }

                case KEY_STATE_KEY_RELEASE:                                        // 按键状态3:长按键释放
                {
                        if(e_keyCode == KEY_NO_PRESS)                        // 如果按键已经释放,确定为长按键以及相应键值,转入状态0:无按键
                        {
                                ps_keyReturn->keyCode = e_keyCodeTmp;
                               
                                ps_keyReturn->keyType = KEY_TYPE_KEY_LONG_PRESS;
                               
                                e_keyState = KEY_STATE_KEY_NO_PRESS;
                        }

                        break;
                }

                default:break;
        }
}

ISR(TIMER0_OVF_vect)
{       
        TCNT0 = 0x28;

        keyScanOnceFlg = 1;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 14:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表