打印

关于avr矩阵键盘扫描问题

[复制链接]
866|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
木乄可|  楼主 | 2017-8-6 16:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
nclude <iom16v.h>
#include <macros.h>
#include<AVR_HJ-2G.h>
#define  uchar unsigned char
#define  uint  unsigned int
#pragma data:code
const  table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,
                           0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0XFF};
void delay(uint ms)
{
        uint i,j;
        for(i=0;i<ms;i++)
           {
           for(j=0;j<1141;j++);
       }
}
void show(uchar j,uchar k)
{
    PORTA|=BIT(3);
        PORTB=table[j];
        PORTA&=~BIT(3);
       
        PORTB=0XFF;
        PORTB&=~BIT(k);
        PORTA|=BIT(4);
        PORTA&=~BIT(4);
        delay(100);
}
uchar key_press()
{
     uchar i;
     DDRD=0XFF;
         PORTD=0XF0;
         
         DDRD=0X0F;
         
         i=PIND;
         if(i==0XF0)
         {
           DDRD=0XFF;
           return 0;
         }
         else
         {
           DDRD=0XFF;
           return 1;
         }
}
uchar key_scan()
        {
         uchar a,KeyValue;
          delay(10);
         if(key_press())
         {
         PORTD=0xf0;
         DDRD=0X0f;
         a=PIND;
         
         switch(a)
                {
       case 0x70:
                           KeyValue=4;
                        break;
           case 0xb0:
                           KeyValue=3;
                        break;
           case 0xd0:
                           KeyValue=2;
           case 0xe0:
                KeyValue=1;
                        break;
                }       
    DDRD=0xff;               
        PORTD=0x0f;
        DDRD=0xf0;
        a=PIND;
        switch(a)
                {
       case 0x07:
                           KeyValue=KeyValue+12;
                        break;
           case 0x0b:
                           KeyValue=KeyValue+8;
                        break;
           case 0x0d:
                           KeyValue=KeyValue+4;
           case 0x0e:
                KeyValue=KeyValue;
                        break;
                }
                return KeyValue;
          }
                else
                {
                 return 0;
                }
                        
               
                }
void main()
{
     uchar l;
         //LEDOFF();   //关LED总开关
         SEGOFF();//关数码显示管函数 用于开机时数码管不显示
     DDRA|=0X18;// 0001 1000
         DDRB=0XFF;
         LEDON();
         while(1)
         {
           if(key_scan()==1)
           {
              //l=key_scan();
                  //show(key_scan(),0);
                  PORTB=0x00;
           }
         }
         
}
扫描函数那里那里错了,为什么得不到我要的结果,上面程序的结果是,如果key_scan()=1,我按矩阵键盘第一行和第二行都可以把灯点亮,但是第三第四行没反应,把key_scan()=2,所有按键怎么按都没反应

相关帖子

沙发
木乄可|  楼主 | 2017-8-6 16:40 | 只看该作者
求助,搞了很久了,是不是逻辑哪里错了,我还想把这种思想用到stm32

使用特权

评论回复
板凳
dirtwillfly| | 2017-8-7 08:28 | 只看该作者
矩阵按键的扫描,网上有很多例程,楼主可以参考下
https://wenku.baidu.com/view/78006b4bbceb19e8b9f6baa1.html

使用特权

评论回复
地板
xjl626| | 2017-8-7 11:17 | 只看该作者
一个实际例程,先读行再读列值 ,注意Keyscan_bit 时启动按键计时,参考下:

// ------------------------ 按键值扫描读取 ------------------------       
        Keyscan_out(CY);                                                 // 列线为0       
       
        if((Get_Keyscan_curr(CX) != KEY_X1) && (!Keylock_bit))                   
        {       
                Key_xx = Get_Keyscan_curr(CX);                 // 读入行线值               

                Keyscan_out(CX);                                        // 行线为0
                Key_yy = Get_Keyscan_curr(CY);            // 读入列线值
                       
                Keyscan_bit = ON;                                        // lock               
               
                while((Get_Keyscan_curr(CY) != KEY_Y1) && (Keydown_count<300))         // 待松开按键
                {       
                        Key_yy = Get_Keyscan_curr(CY);        // 读入列线值
                       
                // ----------------- 再次读取 X 值 -----------------
                        Keyscan_out(CY);                                         // 列线为0                               
                        if(Get_Keyscan_curr(CX) != KEY_X1)   
                                Key_xx = Get_Keyscan_curr(CX);         // 读入行线值
                               
                // ----------------- 再次读取 Y 值 -----------------       
                        Keyscan_out(CX);                                        // 行线为0
                        if(Get_Keyscan_curr(CY) != KEY_Y1)   
                                Key_yy = Get_Keyscan_curr(CY);        // 读入列线值
                               
               
                        WDT_CONTR = WDT_1s;                           // 启动动看门狗并喂狗 1.1s
                        LCD_display();                                        // LCD 显示
                        delayms(3);                                                // 保证在 LCD_display() 为空执行延时,否则按键响应迟顿
                        transmit_start();                                // 串口发送
                        transmit_start1();                                // 串口1发送
                       
                        key_id = (Key_yy | Key_xx);                               
                // --------------------- 特殊按键/多位按键 ---------------------
                        if(Keydown_count >= 33)                // x*10ms
                        {
                                if( (key_id==KEY_YX_S1) || (key_id==KEY_YX_S2) || (key_id==KEY_YX_S3) || (key_id==KEY_YX_S4) || (key_id==KEY_YX_S5) ||
                                        (key_id==KEY_YX_S6) || (key_id==KEY_YX_S7) || (key_id==KEY_YX_S8) || (key_id==KEY_YX_S9) || (key_id==KEY_YX_S10)||
                                        (key_id==KEY_YX_F1)  )
                                {
                                        break;
                                }
                        }                       
                }       
               
                if(Keydown_count>=300)                        // 长按键,解锁
                {                                       
                        Keylock_bit = OFF;                        // 解锁
                       
                // ----------------- 延时 -----------------       
                        Wait_time = 5;                                // x*10ms
                        while(Wait_time)
                        {
                                WDT_CONTR = WDT_1s;           // 启动动看门狗并喂狗 1.1s
                                LCD_display();                        // LCD 显示
                                transmit_start();                // 串口发送
                                transmit_start1();                // 串口1发送
                        }
                }
               
                key_id = (Key_yy | Key_xx);               
                key_temp_code = key_id;                        // 按键值 缓存
        }
       
       
        if(Get_Keyscan_curr(CX) == KEY_X1)                // 按键松开,参数复位
        {
                Keyscan_bit = OFF;       
                key_id = KEY_YX;
        }
       
// ------------------------ 按键值转换 ------------------------
        switch(key_id)                                                //
        {
           .....................................
        }

// --------------------- done ---------------------

使用特权

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

本版积分规则

1

主题

2

帖子

0

粉丝