搜索
bottom↓
回复: 32

4*4矩阵键盘范例(M16)

[复制链接]

出0入0汤圆

发表于 2007-8-25 22:54:37 | 显示全部楼层 |阅读模式
用MEGA16做矩阵键盘扫描,检测到以后由串口发给电脑,有软件消抖

点击此处下载armok01168228.rar
头像被屏蔽

出0入0汤圆

发表于 2007-8-25 23:59:17 | 显示全部楼层
谢谢共享。。。

出0入0汤圆

发表于 2007-8-26 11:19:52 | 显示全部楼层
谢谢分享,学习一下

出0入0汤圆

发表于 2008-3-23 21:44:28 | 显示全部楼层
谢谢你的分享

出0入0汤圆

发表于 2008-3-23 22:24:48 | 显示全部楼层
请问楼主
         Init_Io_2();
         asm("nop");
         temp=PINA|0x0f;
         while(!temp)   {;}
         temp=~temp;
        temp=(temp>>4);
按键扫描中的 while(!temp)   {;} 做什么的

出0入0汤圆

发表于 2008-3-23 22:58:19 | 显示全部楼层
是不支持几个建同时按  不然有乱码吗

出0入0汤圆

发表于 2008-3-24 17:21:08 | 显示全部楼层
顶上去

出0入0汤圆

发表于 2008-3-24 17:34:42 | 显示全部楼层
不会吧  居然没人回答  5555555555

出0入0汤圆

发表于 2008-3-24 20:51:57 | 显示全部楼层
while(!temp)   {;}
除非temp接到向前走的命令(temp不为0),不然一直原地踏步.

出0入0汤圆

发表于 2008-3-24 21:23:17 | 显示全部楼层
.那在这段程序中的作用呢

出0入0汤圆

发表于 2008-3-24 21:35:01 | 显示全部楼层
void Init_Io_1()
{
DDRA=0xf0; PORTA=0x0f;  //先让高位输出,低位输入且上拉

}
void Init_Io_2()
{
DDRA=0x0f;  PORTA=0xF0;//与上相反


}
Getkey(void)
{uchar temp;
if((~(PINA|0xf0))!=0)  // 有键按下
   {Delayms(10);
   if((~(PINA|0xf0))!=0)
      {  temp=PINA|0xf0;
         temp=~temp  ;
         if(temp==1) key=1;
         else  if(temp==2) key=5;
         else  if(temp==4) key=9;
         else  if(temp==8) key=13;
         Init_Io_2();
         asm("nop");
         temp=PINA|0x0f;
         while(!temp)   {;}
         temp=~temp;
        temp=(temp>>4);
        if(temp==1) key+=0;
        else  if(temp==2) key+=1;
        else  if(temp==4) key+=2;
        else  if(temp==8) key+=3;
       Init_Io_1();
       bool=1;
      }
   }
   return key;  //返回1~16键值
}


void main(void)
{uchar i;
uart_init();
Init_Io_1();
while(1)
     {i=Getkey();
       if(bool==1)
         {puts("你按了:");
          putchar(i+0x30);//有键按键,转为ASCII显示一位键盘数,

          bool=0;
          Delay_nms(200);
         }
     }
}

出0入0汤圆

发表于 2008-3-25 00:42:46 | 显示全部楼层
我也发一个,下面是其中的一段,我是设定时5ms运行次KeyJudge,结果在key这个变量里,按下放开都有20s按键消抖,消抖和判断的程序有点状态机的思想,以前写的时候也还不知道状态机这东西,要知道就写的好看点了,没这么难看

按键是可以有2个组合键的,当然,单键也可以啦。

初学AVR,程序从以前写的51的程序移植的,菜鸟一个,大家多指教啊


/***************************************************
KEY FOR AVR 2008.3.16 BY CY
***************************************************/
#define uint unsigned int
#define uchar unsigned char

#include <avr/io.h>

//#include "DM12864J_1ForAVRYY.h"
//#include <avr/pgmspace.h>

#define KeyPort PORTC
#define KeyPortDDR DDRC
#define KeyPortPIN PINC

/*==================================================
按键按下放开后
若KeyAllow=1则按键通过
若KeyAllow=0则按键无效
结果在Key中体现
==================================================*/
uchar KeyTimeCon = 0;                        //定时计数器
uchar Key = 0xff;                                //Key为确认的按键,体现按下的结果
uchar KeyTemp, KeyState = 0xff;                //来存放 还没确认 及 确认 的按键读数,按键为空时为0xff
uchar EffectiveKey = 0xff;                        //存放有效的按键读数
uchar KeyAllow = 1;       
                                                               
/*===================================================================
直接读取按键当前状态
===================================================================*/
uchar ReadKey(void)
{
        uchar i = 0;
        uchar a[] = {0, 0, 0};
        KeyPortDDR = 0x0f;

        KeyPort = 0xfe;
        asm("nop");
        if(!(KeyPortPIN & (1 << 4)))a[i++] = 1;
        if(!(KeyPortPIN & (1 << 5)))a[i++] = 2;
        if(!(KeyPortPIN & (1 << 6)))a[i++] = 3;
        if(!(KeyPortPIN & (1 << 7)))a[i++] = 4;

        KeyPort = 0xfd;
        asm("nop");
        if(!(KeyPortPIN & (1 << 4)))a[i++] = 5;
        if(!(KeyPortPIN & (1 << 5)))a[i++] = 6;
        if(!(KeyPortPIN & (1 << 6)))a[i++] = 7;
        if(!(KeyPortPIN & (1 << 7)))a[i++] = 8;

        KeyPort = 0xfb;       
        asm("nop");
        if(!(KeyPortPIN & (1 << 4)))a[i++] = 9;
        if(!(KeyPortPIN & (1 << 5)))a[i++] = 0;
        if(!(KeyPortPIN & (1 << 6)))a[i++] = 10;
        if(!(KeyPortPIN & (1 << 7)))a[i++] = 11;

        KeyPort = 0xf7;       
        asm("nop");
        if(!(KeyPortPIN & (1 << 4)))a[i++] = 12;
        if(!(KeyPortPIN & (1 << 5)))a[i++] = 13;
        if(!(KeyPortPIN & (1 << 6)))a[i++] = 14; //0x0e
        if(!(KeyPortPIN & (1 << 7)))a[i++] = 15; //0x0f
       
        a[1] = a[1] << 4;
        if (i == 0)return 0xff;
        else return (a[0] + a[1]);
}
/*===================================================================
按键判断,结果体现在Key中,无按键或按键无效则Key=0xff
变化状态后,当前有一个取消键则无效KeyAllow=0
有效的情况为:        1、无取消键且当前为组合键
                2、无取消键且当前为单键且上一个状态为放开
===================================================================*/
void KeyJudge(void)
{
        if(KeyTimeCon)
        {
                KeyTimeCon++;
                if(KeyTimeCon == 5)
                {
                        KeyTimeCon = 0;
                        if(KeyTemp == ReadKey())                        //确认是否改变了一次状态
                        {
                                if(KeyTemp == 0xff)                //现在确定的状态为放开
                                {                                //判断刚才的按键是否有用
                                        if(KeyAllow == 1)                //按键允许生效
                                        {
                                                Key = EffectiveKey;        //结果在Key中体现
                                                EffectiveKey = 0xff;
                                        }
                                        else                                 //按键不允许
                                        {
                                                Key = 0xff;
                                                KeyAllow = 1;
                                                EffectiveKey = 0xff;                               
                                        }
                                }
                                else if((0xf0 == (KeyTemp & 0xf0)) || (0x0f == (KeyTemp & 0x0f)))//现在确定的状态为按下       
                                {                                                                                                                                        //有取消键
                                                     KeyAllow = 0;                                                                                                        //则此次按键无效
                                }
                                else if((KeyTemp > 0x0f) || (KeyState == 0xff))                //无取消键
                                {
                                        EffectiveKey = KeyTemp;//除了是单键且前一次是放开以外的情况,都可使按键生效
                                }

                                KeyState = KeyTemp;        //使用先前的状态判断完毕,可以把确认状态改变
                        }
                }
        }
       
        else if(KeyState != ReadKey())
                                {
                                        KeyTemp = ReadKey();
                                        KeyTimeCon++;
                                }                       
}

出0入0汤圆

 楼主| 发表于 2008-3-29 18:35:31 | 显示全部楼层
sjzd :
不好意思,我很久没有登陆了,看到你的邮件,我来上一个,程序很久以前的了,我当时好像是每当有按键时,想让程序
一直等待,直到按键弹出。这样不会在一次按键过程中多次执行GETKEY()造成
多次PUTCHAR()。
while(!temp)   {;}
要改成while(~(PINA|0x0f));这样当按键弹起才会跳出循环

出0入0汤圆

发表于 2008-3-29 23:20:22 | 显示全部楼层
恩 我知道了  谢谢啊  o(∩_∩)o...

出0入0汤圆

发表于 2008-8-13 10:07:23 | 显示全部楼层
谢谢共享。。。

出0入0汤圆

发表于 2008-8-13 18:39:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-8-18 11:03:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-8-18 22:25:08 | 显示全部楼层
记号。有时间看看。

出0入0汤圆

发表于 2009-3-10 10:41:59 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-3-11 22:02:01 | 显示全部楼层
看了,学习了。

出0入0汤圆

发表于 2009-4-13 19:22:45 | 显示全部楼层
好好学习,天天向上

出0入0汤圆

发表于 2009-4-14 15:25:45 | 显示全部楼层
mark

出0入10汤圆

发表于 2009-4-14 15:50:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-22 20:10:28 | 显示全部楼层
我感觉这个更好点http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=3290821&bbs_page_no=1&search_mode=3&search_text=Adrian&bbs_id=9999

出0入0汤圆

发表于 2009-10-11 17:16:54 | 显示全部楼层
狂顶~~~

出0入0汤圆

发表于 2009-10-11 17:35:34 | 显示全部楼层
zhichi~~~

出0入0汤圆

发表于 2009-10-11 17:36:24 | 显示全部楼层
支持楼主

出0入0汤圆

发表于 2010-1-9 01:55:32 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2010-1-9 14:15:08 | 显示全部楼层
回复【楼主位】chuanhuibh
-----------------------------------------------------------------------

谢谢分享

出0入4汤圆

发表于 2010-1-10 14:33:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-10 15:23:36 | 显示全部楼层

出0入0汤圆

发表于 2010-9-1 00:59:49 | 显示全部楼层
mark

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-7 13:51

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

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