先在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 charlong 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()
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)