完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
本帖最后由 dianzi_fans 于 2011-4-4 15:00 编辑 原理图如下
从原理图可以看到16个键盘依次接在了P3.0-P3.7口上(图上的CSDA,INT1,LCDEN,RS,WR,RD依次是P3.2-P3.7接口) 检测的原理是:比如检测要第一行的键盘S6,S7,S8,S9首先是初始化P3.0的电平为0,P3.1-P3.3的电平为1,P3.4-P3.7的电平也为1。如果有人按下了S6键,因为S6键开关的左边的触点接在了P3.0上,右边的触点接在了P3.4上,当S6按下去以后,P3.0和P3.4就是线与关系了,我们就编程检测P3.4上的电平,因为是按下去了,所以这时P3.4上的电平就是0了,这样就完成了S6按键的检测。其他的15个键同理,都是这样检测。 以下程序实现的功能是实验板不上电时,数码管不显示,顺序按下矩阵键盘后,数码管依次显示0-F,六个数码管同时静态显示。 #include/**************变量的定义*****************/ #define uint unsigned int //宏定义 #define uchar unsigned char //宏定义 ***it dula=P2^6; //声明锁存器的锁存端 ***it wela=P2^7; //声明锁存器的锁存端 uchar code table[]={ //数码管显示0-F的编码 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0}; uchar num,temp; /*********子函数的声明************/ void delay(uint z); //延时函数的声明 uchar keyscan(); //键盘扫描函数的声明 void display(uchar aa); //数码管显示函数的声明 /***********主程序************/ void main() { /*********主程序中初始化的操作*************/ num=17; //这个语句的作用是当什么都没按的话什么都不显示 dula=1; //打开段选 P0=0; //送给段选的数据为0,也就是让数码管什么都不显示 dula=0; //关闭段选 wela=1; //打开位选 P0=0xc0; //初始化六个数码管全处于工作状态 wela=0; //位选锁存端关闭 while(1) //进入死循环,不停地调用矩阵键盘检测函数 { display(keyscan()); //调用矩阵键盘检测函数 } } /***********延时子函数***************/ void delay(uint z) //延时子函数用来延时zms { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } /**********数码管显示子函数*************/ void display(uchar aa) //矩阵键盘检测子函数 { dula=1; //打开段选送入要显示的数据0-F P0=table[aa-1]; //赋给P0口要显示的数据0-F dula=0; //关闭段选 } /*********以下是矩阵键盘检测子函数***********/ uchar keyscan() { /*********第一行键盘的检测**********/ P3=0xfe; //设置P3口的电平为11111110,也就是让P3.0口为低电平,其他的口为高电平 temp=P3; //读取p3口的电平 temp=temp&0xf0; //p3口的电平跟11110000做与操作 while(temp!=0xf0) //检测到第一行上有键盘按下去了 { delay(5); //延时5ms用来消除按键的抖动 temp=P3; //再次读取P3口的电平 temp=temp&0xf0; //p3口的电平跟11110000做与操作 while(temp!=0xf0) //延时后确实有人按下了第一行的键盘(不是别的干扰导致的) { temp=P3; //因为已经确定按下了键,这时就读取P3口的电平 switch(temp) { case 0xee:num=1; //按下的是第一个键,我们就把1赋值给num break; //跳出switch语句 case 0xde:num=2; //按下的是第二个键,我们就把2赋值给num break; //跳出switch语句 case 0xbe:num=3; //按下的是第三个键,我们就把3赋值给num break; //跳出switch语句 case 0x7e:num=4;//按下的是第四个键,我们就把4赋值给num break; //跳出switch语句 } while(temp!=0xf0) //等待松手,如果按下去是一直按着的,没松手的话就一直循环,如果松了手的话,就可以跳出while语句了,回到最后的return语句,返回num的值,接着数码管执行显示num的值 { temp=P3; temp=temp&0xf0; } } } /**************第二行键盘的检测*************/ P3=0xfd; temp=P3; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P3; temp=temp&0xf0; while(temp!=0xf0) { temp=P3; switch(temp) { case 0xed:num=5; break; case 0xdd:num=6; break; case 0xbd:num=7; break; case 0x7d:num=8; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } /********第三行键盘的检测*********/ P3=0xfb; temp=P3; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P3; temp=temp&0xf0; while(temp!=0xf0) { temp=P3; switch(temp) { case 0xeb:num=9; break; case 0xdb:num=10; break; case 0xbb:num=11; break; case 0x7b:num=12; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } /*******第四行键盘的检测*******/ P3=0xf7; temp=P3; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P3; temp=temp&0xf0; while(temp!=0xf0) { temp=P3; switch(temp) { case 0xe7:num=13; break; case 0xd7:num=14; break; case 0xb7:num=15; break; case 0x77:num=16; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } return num; //返回num的值给主程序 } 代码摘自书上,自己稍微加了下注释。 |
|
相关推荐
30 个讨论
|
|
|
学习了 ,谢谢分享!
|
|
|
|
|
|
|
|
|
辛苦楼猪了 谢谢
|
|
|
|
|
|
|
|
|
uchar Matrixkeyscan() { uchar num; uchar key_lie; //按键扫描函数里用来存储列的变量 uchar key_hang; //存储行的变量 uchar key; //具体按下的键值的编码 P2=0xf0; //1111 0000,行为低电平,列为高电平 key_lie=P2; //读取IO的数值 key_lie=key_lie&0xf0; //与,将低四位屏蔽 if(key_lie!=0xf0) //如果不等,说明有按键按下 { Delay_ms(10); //去抖动 if(key_lie!=0xf0) //说明确实有按键被按下 { key_lie=P2; //读取最新的P2值 key_lie=key_lie&0xf0; //得到最新的列的信息(这两行可以不写,写上更严谨) //假如第一列的某个按键按下,则key_lie为1110 0000 P2=0x0f; //0000 1111,列为低电平,行为高电平 key_hang=P2; //读取P2口 key_hang=key_hang&0x0f; //将高四位屏蔽掉,得到具体的行的信息,假如第一行的某个按键被按下 //则key_hang为0000 1110 key=key_hang|key_lie; //将行和列的信息相或,1110 0000 |0000 1110=1110 1110, //可知第一行,第一列的按键被按下 } while(P2!=0x0f); //等待按键被释放 } switch(key) //根据按键的数值进行判断 { case 0xee: num=0;break; //0xee=1110 1110 说明第一个按键被按下,则num的值为0; case 0xde: num=1;break; case 0xbe: num=2;break; case 0x7e: num=3;break; case 0xed: num=4;break; case 0xdd: num=5;break; case 0xbd: num=6;break; case 0x7d: num=7;break; case 0xeb: num=8;break; case 0xdb: num=9;break; case 0xbb: num=10;break; case 0x7b: num=11;break; case 0xe7: num=12;break; case 0xd7: num=13;break; case 0xb7: num=14;break; case 0x77: num=15;break; case 0x00: num=16;break; //如果没有按键按下,则不显示 } return num; } |
|
|
|
|
|
|
|
【瑞萨RA6E2】瑞萨E2S软件安装过程,等待过程玩下97_e2 studio_ZGZZ
234 浏览 0 评论
514 浏览 0 评论
【原创】【RA4M2-SENSOR开发板评测】低功耗+USB综合测试
826 浏览 0 评论
1366 浏览 2 评论
814 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
16911 浏览 31 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-3 03:13 , Processed in 0.790420 second(s), Total 54, Slave 46 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
11118