打印
[AVR单片机]

在atmega16芯片上设计了一个4*4的矩阵键盘存在问题

[复制链接]
3030|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wagina|  楼主 | 2007-4-5 16:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用avr单片机设计了一个4*4矩阵键盘,但是实验发现只能识别8个按键第一行和第二行不能识别,不知道是什么问题请高手指教按键程序如下:
uchar x=1;
 uchar get_key(void) 
  {  
     uchar key=0; 
     DDRA=0xff; 
     PORTA=0xF0;
      DDRA=0x0F;
     
      if(PINA==0xf0) 
     {x=0;} 
     else 
      {  
        
       delay(12); 
       if((PINA!=0xf0)&&(x==0)) 
       { 
            nop();nop();nop();nop();
         delay(10);
         if(~PINA&0x80) 
              key=0;//第一横高端 
         else if(~PINA&0x40) 
              key=4;//第二横 
         else if(~PINA&0x20) 
              key=8;//第三横 
         else if(~PINA&0x10) 
              key=12;//第四横 
                
             
         DDRA=0xff;
         PORTA=0x0f;
         DDRA=0xf0;
         delay(15); 
          
         if(~PINA&0x08) 
            key+=0;//第一竖 
         else if(~PINA&0x04) 
              key+=1;//第二竖 
         else if(~PINA&0x02) 
              key+=2;//第三竖 
         else if(~PINA&0x01) 
              key+=3;//第四竖低端 
              x=1; 
                
             } 
        } 
         return(key); 

//在主函数中根据不同键值实现不同功能
设计电路如下:

相关帖子

沙发
wagina|  楼主 | 2007-4-9 10:58 | 只看该作者

谢谢zsmbj兄!但是不知道pgm_read_byte()函数是什么?

谢谢zsmbj兄!我的设计还要用到LCM12864的我驱动写好了,但是不知道怎么编菜单,可否指教一下!谢谢了!

使用特权

评论回复
板凳
zsmbj| | 2007-4-9 11:17 | 只看该作者

哦,我是用winavr编写的。

pgm_read_byte()是读取程序空间上的数据。

如果用其他编译器,则去掉这个函数即可。不过注意上面的 定义PROGMEM    要修改成对应的编译器的关键字即可。

至于LCD的菜单需要根据菜单的内容自己写。好像论坛里原来有一个结构。搜索一下吧。

使用特权

评论回复
地板
wagina|  楼主 | 2007-4-9 12:13 | 只看该作者

zsmbj兄谢谢了!以后多多指教!

使用特权

评论回复
5
ayb_ice| | 2007-4-9 13:58 | 只看该作者

反转扫描法很快。。。

反转扫描法很快。。。

使用特权

评论回复
6
wagina|  楼主 | 2007-4-9 14:46 | 只看该作者

ayb_ice兄可以给个参考吗?

ayb_ice兄可以给个参考吗?我设计的不很稳定,只能识别8个按键不知道是什么问题

使用特权

评论回复
7
zsmbj| | 2007-4-9 15:52 | 只看该作者

我给你的就是反转法啊。

如果不需要做按键对应,那么后面的那个查表就不需要了。

    KeyPort = 0x0f;
    KeyDir = 0xf0;                //open key low 4 bit port
    delay(5);
    getkey  = KeyVal & 0x0f;        //get low 4 bit

    KeyPort = 0xf0;
    KeyDir = 0x0f;                //open key high 4 bit port
    delay(5);
    getkey += KeyVal & 0xf0;        //get high 4 bit

    KeyPort = 0xff;
    KeyDir = 0x00;                //off key port

仅仅这就够了。

使用特权

评论回复
8
wagina|  楼主 | 2007-4-9 17:14 | 只看该作者

zsmbj兄,我知道是,我也这么写过但是不行

    KeyPort = 0x0f;
    KeyDir = 0xf0;   //低四位开上拉,高四位是高阻态,
这样keyval是0x00而不是想要的0x0f
同理下边也有问题,我测试过的,可能是拙见,请指教!

使用特权

评论回复
9
zsmbj| | 2007-4-9 17:43 | 只看该作者

不会啊。

KeyPort = 0x0f;
KeyDir = 0xf0;

是高4位输出,低4位输入,而高4位输出的是0电平,低4位输入的是带上拉的。如果没有任何按键按下,则:
getkey  = KeyVal & 0x0f;        //get low 4 bit
后读取的值应该是0x0f。不会是0x00。

同理,后面的一个读正好相反。如果没有按键则高位为f,拼在一起就是0xff。就是没有按键。

另外注意那个delay,不要省略。

使用特权

评论回复
10
wagina|  楼主 | 2007-4-9 20:03 | 只看该作者

zsmbj兄,我实际调试了

我设置了断点,不知道为什么第一次的时候确实PINA=0x00(理论应该为0x0f),第二次就正确了,但是搭了个电路测试还是没有反应啊?是不是延迟时间设置的不对啊?

使用特权

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

本版积分规则

4

主题

19

帖子

0

粉丝