完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
`以下为程序: /*反转法矩阵键盘的应用,我认为这是一个编程简便又容易理解的矩阵键盘编程应用,因此拿来与大家共享*/ /*殷传东对此程序拥有独家版权,仅可用于研究学习,严禁用于商业目的,欢迎喜爱单片机的大虾小虾皮皮虾联系交流QQ:77329961*/ #include #define uchar unsigned char //宏定义 #define uint unsigned int uchar key,n; //定义变量 uchar code table[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; //反转法矩阵键盘的各个按键的计算值 uchar code yin[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴极数码管显示0~F void delay(uint i) //延时函数 { while(i--); } void keyscan() { uchar l,h,i; //定义局部变量,用l得出低4位的值,用h得出高4位的值 P1=0x0f; //给P1赋值00001111 l=P1&0x0f; if(l!=0x0f) { delay(100); if(l!=0x0f) l=P1&0x0f; //若有键按下,得出低四位的值 } P1=0xf0; //给P1赋值11110000 h=P1&0xf0; if(h!=0xf0) { delay(100); if(h!=0xf0) h=P1&0xf0; //若有键按下,得出高4位的值 } key=l+h; //高4位的值与低4位的值相加 for(i=0;i<16;i++) { if(key==table) //通过查表得出n的值 n=i; } } void main() { while(1) { keyscan(); P0=yin[n]; //在数码管上显示相应的键值 } } ` |
|
相关推荐
14个回答
|
|
在线急等{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}{:4:}
|
|
|
|
通过查表得出N的值?只写一个table怎么查?最起码写完整吧,table[i];
|
|
|
|
|
|
|
|
|
|
|
|
像这样显示不全第一个按键还不显示
|
|
|
|
|
|
你买的谁的?没有技术支持吗?这个东西得看硬件,光看这个现象,是不行的,数码管是共阳还是共阴,数组数值编码不一样 |
|
|
|
delay(100);
if(l!=0x0f) l=P1&0x0f; //若有键按下,得出低四位的值 } 括号配对有问题,上面的这个括号应该去掉,其他的你看着配对吧,既然是搬的程序,也可以对比一下原来的程序 评分
|
||
|
||
|
|
你比我看得懂的多得多
|
|
|
|
程序基于AT89S51芯片,两个573锁存器(控制 段选位选) P3口接矩阵键盘,其中P3.0~P3.3接行线,P3.4~P3.7接列线,P0口接共阴极7段数码管。 反转法的原理: 反转法就是通过给单片机的端口赋值两次,最后得出所按键的值的一种算法。 给P3口赋值0x0f,即00001111,假设0键按下了,则这时P3口的实际值为00001110; 给P3口再赋值0xf0,即11110000,如果0键按下了,则这时P3口的实际值为11100000; 通过这两次P3口的实际值相加得11101110,即0xee。 由此我们便得到了按下0键时所对应的数值0xee,以此类推可得出其他15个按键对应的数值,有了这种对应关系,矩阵键盘编程问题也就解决了,也就是程序的算法已经有了。 (上述方法来源于网络) 好了下面直接进入程序 #include #define uchar unsigned char //宏定义 #define uint unsigned int uchar key,n,i; //定义变量 uchar code table[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; //反转法矩阵键盘的各个按键的计算值 uchar code yin[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴极数码管显示0~F void delay(uint i) //延时函数 { while(i--); } void keyscan() { uchar l,h,i; //定义局部变量,用l得出低4位的值,用h得出高4位的值 P3=0x0f; //给P3赋值00001111 l=P3&0x0f; if(l!=0x0f) { delay(100); //延迟后再检测 P3=0x0f; l=P3&0x0f; if(l!=0x0f) { h=P3&0xf0; //若有键按下,得出高四位的值 P3=0xf0; //给P3赋值11110000 h=P3&0xf0; //若有键按下,得出低四位的值 key=l+h; //高4位的值与低4位的值相加 for(i=0;i<16;i++) { if(key==table[i]) //通过查表得出n的值 n=i; } } } } void main() { while(1) { keyscan(); for(i=0;i<6;i++) //送入位选信号控制数码管 { P2_6=1;P2_7=0; P0=yin[n]; P2_6=0;P2_7=1; switch(i) { case 0:P0=0xfe;break; case 1:P0=0xfd;break; case 2:P0=0xfb;break; case 3:P0=0xf7;break; case 4:P0=0xef;break; case 5:P0=0xdf;break; default:break; } P2_6=0;P2_7=0; delay(100); } } } 新手标注可能不够到位,多多理解,如有错误请多多指教。 |
|
|
|
|
|
|
|
这个是使用先给按键矩阵IO口赋值,并通过判断值是否变化来判断是否有按键按下,从IO口取值判断是哪行(列)有按键按下;同时再次反向赋值,并取值再次判断是哪列(行)有按键按下,就能直接得出按键值,我学矩阵键盘时也是这个思路写的,不过用的swich语句判断,这个table【】数组用的更灵活些
/**************************************************************************************************** 4*4=16个矩阵键盘,开始数码管不显示,在分别按下这16个按键时,数码管静态分别显示0-F 实现电路:郭天祥GTX-1C,4*4矩阵键盘的4行和4列分别连接P3.0-P3.7口 ****************************************************************************************************/ #include #include #define uchar unsigned char #define uint unsigned int uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; ***it dula=P2^6; //定义段拉 ***it wela=P2^7; //定义位拉 uchar key; void delay(uint x) //延时子函数500uS { uchar y; for(x;x>0;x--) for(y=225;y>0;y--); } void scankey() //按键扫描程序 { uchar tmp,tmp1; if(P3!=0x0f) //在主函数中,先给P3送了0x0f(00001111)电平,以检测按下的是哪一行,如果有按键按下,这个值都会变化。 { tmp1=P3; //如果是1-4按键按下,则变为00001110,5-8为00001101,9-12为00001011,13-16为00000111,把这个值赋给tmp1 delay(20); //延时10mS,消抖 P3=0xf0; //再次给P3送0xf0(11110000)电平,以检测是那一列按键按下 if(P3!=0xf0) //消抖后仍然检测到按键按下,值发生变化,P3不等于0xf0 { //如果是1.5.9.13按键按下,则变为11100000,2.6.10.14为11010000,3.7.11.15为10110000,4.8.12.16为01110000 tmp=(tmp1|P3); //将检测的行值和列值进行或运算 switch(tmp) //switch语句对tmp值进行多条件选择 { case 0xee: //如果是1按键按下,这个值对应为11101110,则显示数组的0位数 key=0; break; case 0xde: key=1; break; case 0xbe: key=2; break; case 0x7e: key=3; break; case 0xed: key=4; break; case 0xdd: key=5; break; case 0xbd: key=6; break; case 0x7d: key=7; break; case 0xeb: key=8; break; case 0xdb: key=9; break; case 0xbb: key=10; break; case 0x7b: key=11; break; case 0xe7: key=12; break; case 0xd7: key=13; break; case 0xb7: key=14; break; case 0x77: key=15; break; } while(P3!=0xf0); //等待按键放开 dula=1; P0=table[key]; //送数码管段数据 dula=0; } } } void main() { wela=1; P0=0x00; wela=0; //因为是静态显示,所以就没有写单独的display显示子函数 while(1) { P3=0x0f; //先给P3送00001111电平 scankey(); //扫描按键子函数 } } |
|
|
|
两个结合一起程序显得更清爽了哈:
#include #include #define uchar unsigned char #define uint unsigned int uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar code table0[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; //反转法矩阵键盘的各个按键的计算值 ***it dula=P2^6; //定义段拉 ***it wela=P2^7; //定义位拉 uchar key; void delay(uint x) //延时子函数500uS { uchar y; for(x;x>0;x--) for(y=225;y>0;y--); } void scankey() //按键扫描程序 { uchar tmp,tmp1,i; if(P3!=0x0f) //在主函数中,先给P3送了0x0f(00001111)电平,以检测按下的是哪一行,如果有按键按下,这个值都会变化。 { tmp1=P3; //如果是1-4按键按下,则变为00001110,5-8为00001101,9-12为00001011,13-16为00000111,把这个值赋给tmp1 delay(20); //延时10mS,消抖 P3=0xf0; //再次给P3送0xf0(11110000)电平,以检测是那一列按键按下 if(P3!=0xf0) //消抖后仍然检测到按键按下,值发生变化,P3不等于0xf0 { //如果是1.5.9.13按键按下,则变为11100000,2.6.10.14为11010000,3.7.11.15为10110000,4.8.12.16为01110000 tmp=(tmp1|P3); //将检测的行值和列值进行或运算 for(i=0;i<16;i++) { if(tmp==table0[i]) key=i; } while(P3!=0xf0); //等待按键放开 dula=1; P0=table[key]; //送数码管段数据 dula=0; } } } void main() { wela=1; P0=0x00; wela=0; //因为是静态显示,所以就没有写单独的display显示子函数 while(1) { P3=0x0f; //先给P3送00001111电平 scankey(); //扫描按键子函数 } } |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
48 浏览 0 评论
【每周推荐】采用11代Intel CPU,基于youyeetoo X1开发板搭建少儿AI智能STEAM积木平台
825 浏览 0 评论
2360 浏览 2 评论
【youyeetoo X1 windows 开发板体验】+ 影音处理和AI模型移植
2226 浏览 5 评论
I.MX6ULL-飞凌 ElfBoard ELF1板卡- 移植zbar的方法
1694 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
5698 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-23 14:09 , Processed in 0.685668 second(s), Total 88, Slave 69 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号