搜索
bottom↓
回复: 2

本人初学单片机,编个测试矩阵键盘的小程序,望高手指正

[复制链接]

出0入0汤圆

发表于 2012-3-29 22:22:54 | 显示全部楼层 |阅读模式
单片机为AT89S52,P1口接矩阵键盘!

//4X4按键扫描测试!


#include <reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;

uint8 code table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};                                                                //共阳极数码管扫描吗
uint8 keyvalue[]={1,2,3,12,4,5,6,13,7,8,9,14,10,0,11,15};                                                                                                                                //键盘码
uint8 keyset=0;                                                                                                                                                                                                                                                                                                        //按键值与按下标志位,第7位为按下标志位



void delay(unsigned int delaynums)                                                                                                                                                                                                                        //延时函数,测试用
{

        for(;delaynums>1;delaynums--);
       
}

void ledout(unsigned char lednum,unsigned char ledbit)                                                                                                                                        //数码管单位显示函数
{
        //lednum是需要显示的数值
        //ledbit是显示的位置
        if (ledbit<5)
                {
                        P0|=255;                                                        //关闭led显示
                        P1|=15;                                                        //关闭led片选
                        P0=lednum;                                                //led显示数据准备               
                        P1&=~(16>>ledbit);                           //led片选打开               
                }
}

uint8 keyboard(uint8 key_value)                                                                                                                                                                                                                                        //根据扫描码返还扫描行或列数
{
  uint8 key_line;
  if(key_value & 3)
  {
          if(key_value & 1)       
          {
                  key_line = 0;
          }
          else
          {
                  key_line = 1;
          }
  }
  else
  {
          if(key_value & 4)
          {
                  key_line = 2;       
          }                       
          else
          {       
                  key_line = 3;
          }
  }
  return key_line;
}

void keyscanning()
{
        uint8 key_value,key_line,key_column;
       
        if(        P2<240)                                                                                                                                                                                                                                                                                                                //按键是否被按下查询
        {
                if(keyset&128){}                                                                                                                                                                                                                                                                                //按键按下标志位检查,按下就不再扫描
                else                                                                                                                                                                                                                                                                                                                                //按键标志位未被置位,延时后再次检查按键是否按下
                {
                        delay(10);
                        if(P2<240)
                        {
                                key_value = (~P2)>>4;                                                                                                                                                                                                                                                //高4位扫描码转换
                                key_line=keyboard(key_value);                                                                                                                                                                                                                //返回按键行数值
                                P2=255;                                                                                                                                                                                                                                                                                                        //拉低高4位,准备再次扫描
                                P2=15;
                                delay(10);
                                key_value =~( P2|240);                                                                                                                                                                                                                                        //取出低4位扫描码
                                key_column=keyboard(key_value);                                                                                                                                                                                                        //返回按键列数
                                P2=255;
                                P2=240;
                                keyset=keyvalue[key_line+(key_column<<2)];                                                                                                                                                        //根据行列数值,在数组中取出按键码
                                keyset |=224;                                                                                                                                                                                                                                                                                //置位按键按下标志位,
                        }       
                }
        }
        else
        {
                if(keyset&128)                                                                                                                                                                                                                                                                                        //按键未按下时如果标志位未被置零
                {
                        keyset=keyset-32;                                                                                                                                                                                                                                                                        //3次扫描后按下标志位置零
                }
                else
                {
                        keyset=0;                                                                                                                                                                                                                                                                                                        //标志位为零时,按键值归零
                }
        }       
}

void main()
{
        P2=240;
        while(1)
        {
               
                keyscanning();
                if(keyset&128)                                                                                                                                                                                                                                                                                        //检查按下标志位,如按下则显示键值,未按下数码管关闭
                {
                        ledout(table[keyset&15],1);       
                }
                else
                {
                        P1|=15;
               
                }  
                delay(100);
        }
       
}


原理图见附件

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2012-3-29 22:24:37 | 显示全部楼层
不知道使用数组节省资源还是用case节省资源!请高手指教!!!

出0入0汤圆

发表于 2012-3-30 02:50:12 | 显示全部楼层
嘿嘿~奸笑中!












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

本版积分规则

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

GMT+8, 2024-5-20 03:57

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

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