搜索
bottom↓
回复: 9
打印 上一主题 下一主题

马老师,麻烦给钦点一下,状态机按键,逼上绝路了!!

[复制链接]

出0入0汤圆

跳转到指定楼层
1
发表于 2010-7-3 11:02:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小弟的程序,基于状态机的4*4键盘,最简单的想按键弹起时返回键值,但是看了老久了,就是找不出毛病,麻烦给看看吧,快疯了!!!

#define uchar unsigned char
#define uint unsigned int

#define     NO_KEY           0x00

#define key_k1 '1'  
#define key_k2 '2'   
#define key_k3 '3'   
#define key_k4 '4'  
#define key_k5 '5'
#define key_k6 '6'
#define key_k7 '7'
#define key_k8 '8'
#define key_k9 '9'
#define key_k0 '0'
#define key_k10 'A'
#define key_k11 'B'
#define key_k12 'C'
#define key_k13 'D'
#define key_k14 'E'
#define key_k15 'F'

char Key_time_ok;

void initialize_timer(void)
{
     TCNT0=0x00; // {(0xff-0x70)+1}*1024*(1/14.7456MHz)=10ms
TCCR0=0x06; // 定时器0 prescaler=1024
TIMSK=0x01; // OCIE0=1,定时器0溢出标志
SREG = 0x80;          //使能全局中断
}

#pragma interrupt_handler timer0:17
void timer0(void)
{
  TCNT0=0x00;
  Key_time_ok=1;
}


uchar GetKeyCode(void)
{
        uchar i;
        DDRC=0xf0; //高4位输出,低4位输入
    PORTC=0x0f;//高4位输出0,低4位带上拉输入
    //delay_nms(1);
    waitsomeNOP();   //等待8个时钟周期(NOP)
    i=PINC&0x0f;      

    /*获取行地址*/
    DDRC=0x0f;//高4位输入,低4位输出
    PORTC=0xf0;//低4位输出0,高4位带上拉输入
    //delay_nms(1);
        waitsomeNOP();

    i|=PINC&0xf0;
return i;
}

uchar get_key(void)
{
    static char KeyState   = 0;        //按键状态
    static char KeyPrev1   = 0;        //上一次按键
static char KeyPrev    = 0;        //新一次按键
     
    char KeyPress  = NO_KEY;           //按键值
    char KeyReturn = NO_KEY;           //按键返回值  
   
    KeyPress = GetKeyCode();
         
    switch(KeyState)
    {
        //按键初始态00
        case 0:      
            if( KeyPress !=NO_KEY )  
            {  
                KeyState = 1;
KeyPrev1  = KeyPress;
            }
            break;
        //按键确认态01
        case 1:
            if( KeyPress !=NO_KEY  )  
            {
                //与上次按键不同,是乱码
                if(KeyPrev1  != KeyPress)
                {
                    KeyState  = 0;
                }
                else
                {
                    KeyState  = 2;
        switch (KeyPress)                        // 与状态1的相同,确认按键  
                        {              // 键盘编码,返回编码值   
                           case 0Xdb: KeyPrev = key_k0; break;
   case 0X77: KeyPrev = key_k1; break;
                           case 0X7b: KeyPrev = key_k2; break;   
                           case 0X7d: KeyPrev = key_k3; break;   
                           case 0X7e: KeyPrev = key_k4; break;  
                           case 0Xb7: KeyPrev = key_k5; break;
                           case 0Xbb: KeyPrev = key_k6; break;
                           case 0Xbd: KeyPrev = key_k7; break;
                           case 0Xbe: KeyPrev = key_k8; break;
                           case 0Xd7: KeyPrev = key_k9; break;
                           case 0Xdd: KeyPrev = key_k10;break;
                           case 0Xde: KeyPrev = key_k11;break;
                           case 0Xe7: KeyPrev = key_k12;break;
                           case 0Xeb: KeyPrev = key_k13;break;
                           case 0Xed: KeyPrev = key_k14;break;
   case 0Xee: KeyPrev = key_k15;break;
   default :break;
                        }  
}
            }
            else
            {//按键抬起,是抖动,不响应按键
                KeyState = 0;
            }
            break;
            
     
        //按键释放态10
        case 2:
            if(KeyPress == NO_KEY )  
            {
                KeyState   = 0;
                KeyReturn  =  KeyPrev;             //返回按键抬起值
            }   
            break;

        default :break;
    }
return KeyReturn;
}

void main()
{
  initialize_timer();
  while(1)
     {
       Uchar MMtemp;
       if(Key_time_ok==1)
          {
            Key_time_ok=0;
    MMtemp=get_key();           //有按键按下时
   
    if(MMtemp=='1')
      {
    sendbyte(0xff);  
  }

          }
    }
}

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

2
发表于 2010-7-3 13:17:43 | 只看该作者
先检查你连线有没有错误,再一个你的问题是什么?

出0入0汤圆

3
发表于 2010-7-3 13:32:04 | 只看该作者
回复【楼主位】june2008
-----------------------------------------------------------------------

马老师,小弟的程序………………


马老大,学生的程序………………

就这么搭配。

出0入0汤圆

4
发表于 2010-7-4 15:00:53 | 只看该作者
。。。不想说  也没工夫看你程序

出0入0汤圆

5
发表于 2010-7-6 15:14:17 | 只看该作者
马老师的按键状态机如下:
    
    状态0:
       按键输出;
              NOP();
              NOP();
       按键输出;
              读键端口
          if (有按键按下)
                  转状态1
    状态1: 
       读键端口
          if (前后两次相同)
       {
                  置按键标志
                  转状态2,等等按键释放
               }
               else
         转状态0
    状态2:
       按键输出;       
              读键端口
       if (按键已经释放)  ---> 读到的按键值==NO_KEY
         转状态0   



    你仔细对照一下,程序是否和上面的状态机一致?  

出0入0汤圆

6
发表于 2013-10-8 11:47:37 | 只看该作者
状态机学习中

出0入0汤圆

7
发表于 2013-12-23 10:09:20 | 只看该作者
状态机学习。。。。

出0入0汤圆

8
发表于 2014-2-11 09:13:49 | 只看该作者
有一个地方,我没看懂
uchar get_key(void)
{
    static char KeyState   = 0;        //按键状态
    static char KeyPrev1   = 0;        //上一次按键
static char KeyPrev    = 0;        //新一次按键
     
    char KeyPress  = NO_KEY;           //按键值
    char KeyReturn = NO_KEY;           //按键返回值  
   
    KeyPress = GetKeyCode();
         
    switch(KeyState)
    {
        //按键初始态00
        case 0:      
            if( KeyPress !=NO_KEY )  
            {  
                KeyState = 1;
KeyPrev1  = KeyPress;
            }

KeyState           初始化为0,之后没有被修改过。switch语句永远执行   case 0:      ,你再怎么按,都不会有反应

出0入0汤圆

9
发表于 2014-2-11 14:25:00 | 只看该作者
const_J 发表于 2014-2-11 09:13
有一个地方,我没看懂
uchar get_key(void)
{

你先去学学static的用法吧

出0入0汤圆

10
发表于 2014-2-12 09:45:27 | 只看该作者
sbk100 发表于 2014-2-11 14:25
你先去学学static的用法吧

哦,不好意思,没注意后面的        case 0:      
            if( KeyPress !=NO_KEY )  
            {  
                KeyState = 1;
                KeyPrev1  = KeyPress;
            }
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-26 16:45

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

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