矩阵键盘程序

矩阵键盘程序,第1张

假设按下的是S1键进行如下检测(4*4键盘)

先在P3口输出

p3 00001111

低四位 行会有变化

cord_h =00001111&00001110 =00001110

if !=00001111

延时0.1us

cord_h=00001110&00001111=00001110

if !=00001111

P3再输出11111110

P3=00001110|11110000=11111110

输出高四位

cord_l=P3&0xf0 //此时P3口就是输入值01111110 而不是上面的11111110

cord_l=01111110&11110000=01110000

cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码

#include <reg52.h>//包含头文件

#define uchar unsigned char

#define uint unsigned int

unsigned char const table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,

0x77,0x7c,0x39,0x5e,0x79,0x71}//0-F

uchar keyscan(void)

void delay(uint i)

void main()

{

uchar key

P2=0x00//1数码管亮 按相应的按键,会显示按键上的字符

while(1)

{

key=keyscan()//调用键盘扫描,

switch(key)

{

case 0x7e:P0=table[0]break//0 按下相应的键显示相对应的码值

case 0x7d:P0=table[1]break//1

case 0x7b:P0=table[2]break//2

case 0x77:P0=table[3]break//3

case 0xbe:P0=table[4]break//4

case 0xbd:P0=table[5]break//5

case 0xbb:P0=table[6]break//6

case 0xb7:P0=table[7]break//7

case 0xde:P0=table[8]break//8

case 0xdd:P0=table[9]break//9

case 0xdb:P0=table[10]break//a

case 0xd7:P0=table[11]break//b

case 0xee:P0=table[12]break//c

case 0xed:P0=table[13]break//d

case 0xeb:P0=table[14]break//e

case 0xe7:P0=table[15]break//f

}

}

}

uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法

{

uchar cord_h,cord_l//行列值

P3=0x0f //行线输出全为0

cord_h=P3&0x0f//读入列线值

if(cord_h!=0x0f)//先检测有无按键按下

{

delay(100) //去抖

cord_h=P3&0x0f //读入列线值

if(cord_h!=0x0f)

{

P3=cord_h|0xf0 //输出当前列线值

cord_l=P3&0xf0 //读入行线值

return(cord_h+cord_l)//键盘最后组合码值

}

}return(0xff)//返回该值

}

void delay(uint i)//延时函数

{

while(i--)

}

#define uchar unsigned char

long First,End //定义全局变量

void delay(int n) //***延时程序***//

{int i,j

for(i=0i<ni++)

{for(j=0j<50j++)

}

}

long add(long x,long y)//***加法程序***//

{long z

z=x+y

return(z)

}

long sub(long x,long y)//***减法程序***//

{long z

if(x>=y)

z=x-y

else

{z=y-x

z=z+10e6} //***最高位用1表示负数***//

return(z)

}

long mul(long x,long y)//***乘法程序***//

{long z

z=x*y

return(z)

}

long div(long x,long y)//***除法程序***//

{long z

z=x/y

return(z)

}

uchar kbscan(void) //***键盘扫描程序***//

{

uchar sccode

P1=0xf0

if((P1&0xf0)!=0xf0) //发全0行扫描码,列线输入

{ delay(222) //延时去抖

if((P1&0xf0)!=0xf0)

{sccode=0xfe//逐行扫描初值

while((sccode&0x10)!=0)

{P1=sccode//输出行扫描码

if((P1&0xf0)!=0xf0)

{

return(P1)} //如果检测到有键按下,返回键值

else

sccode=(sccode<<1)|0x01//行扫描码左移一位

}

}

}

return(0) //无键按下,返回值为0

}

void display(void) //***显示程序***//

{int i

uchar code rel[]= //数码管选通

uchar code led[]= //定义0-9

uchar data num[8]

num[0]=First/10000000 //千万位

num[1]=First/1000000%10 //百万位

num[2]=First/100000%10 //十万位

num[3]=First/10000%10 //万位

num[4]=First/1000%10//千位

num[5]=First/100%10 //百位

num[6]=First/10%10 //十位

num[7]=First%10 //个位

for(i=7i>=0i--)

{P3=rel[i] //位选输出

P2=led[num[i]]//数据输出

delay(2) //此延时必不可少?

}

}

void main(void) //***主程序***//

{ int k,n

uchar f,g,key,gn1

n=0

f=0

P0=0//初始时指示灯灭

while(1) //不断查询是否有按键动作

{ key=kbscan() //获取返回键值

if(key!=0)

{

switch(key) //译码,将对应按键返回值转换为相应数值

{

case 0xee: k=0break//0

case 0xde: k=1break//1

case 0xbe: k=2break//2

case 0x7e: k=3break//3

case 0xed: k=4break//4

case 0xdd: k=5break//5

case 0xbd: k=6break//6

case 0x7d: k=7break//7

case 0xeb: k=8break//8

case 0xdb: k=9break//9

case 0xbb: k=10First=0End=0f=0break//清除

case 0x7b: k=11break//等于

case 0xe7: k=12f=1break//加

case 0xd7: k=13f=2break//减

case 0xb7: k=14f=3break//乘

case 0x77: k=15f=4break//除

}

P0=1

delay(280)//有按键时,指示灯的显示时间

P0=0 //按键指示灭

if(k<10) //为数字键时(0-9)

{

if(f!=0) //为数字键时,如果已经有功能键按下

{

n++//记录数字键所按次数

gn1=0 //清除标志,再次为功能键时进行运算

g=f//保存运算标志

if(n==1) //输入为各位数时,直接赋值

First=k

else if(n>1) //输入为多位数时,将它转化为10进制的多位数

First=First*10+k

}

else//如果没有功能键按下

{

n++

gn1=1 //定义标志,当下一次为功能键时,停止数据输入

if(n==1)

First=k

else if(n>1)

First=First*10+k

End=First //将第一个数保存

}

}

else if(k>11) //为功能键时(+-*/)

{

if(gn1==1) //前一次数字键之后为功能键时

{

n=0 //清除计数标志

}

else //如果再次输入功能键,则进行运算

{n=0 //清除计数标志

switch(g)

{case 1: First=add(End,First)break

case 2: First=sub(End,First)break

case 3: First=mul(End,First)break

case 4: First=div(End,First)break}

}

End=First//保存本次结果

}

else if(k==11) //为等于号时(=)

{n=0

gn1=1 //接着输入为功能键时可以继续运算

switch(g)

{case 1: First=add(End,First)break

case 2: First=sub(End,First)break

case 3: First=mul(End,First)break

case 4: First=div(End,First)break

}

End=First//保存最终运算结果

f=0 //清除运算标志

}

}

display() //调用显示程序

}

}

这是一个以前写的矩阵键盘程序,显示在数码管上的。你该改就可以了

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^6

sbit wela=P2^7

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,0x67}

void delay(uint m)

{ uint i,j

for(i=mi>0i--)

for(j=110j>0j--)

}

void display(uchar num)

{ wela=1

P0=0xc0

wela=0

P0=0XFF

dula=1

P0=table[num]

dula=0

}

void keycans()

{ uchar a,key,c

P3=0X0f

if(P3!=0X0f)

{ delay(10)

if(P3!=0x0f)

{

a=P3

P3=0Xf0

c=P3

a=a|c

switch(a)

{case 0xee:key=1break

case 0xde:key=2break

case 0xbe:key=3break

case 0x7e:key=4break

case 0xed:key=5break

case 0xdd:key=6break

case 0xbd:key=7break

case 0x7d:key=8break

case 0xeb:key=9break

case 0xdb:key=10break

case 0xbb:key=11break

case 0x7b:key=12break

case 0xe7:key=13break

case 0xd7:key=14break

case 0xb7:key=15break

case 0x77:key=16break

}

while(!a)

display(key)

}

}

}

void main()

{

while(1)

keycans()

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12017776.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存