#include<reg52.h>
typedef unsigned char uchar
typedef unsigned int uint
sbit key1=P0^0
sbit key2=P0^1
sbit key3=P0^2
sbit key4=P0^3
sbit wela=P2^0//位锁判首简芹明存端
#define SMG P1
sbit LED=P3^0//低电平亮
uchar code table[]={0x8d,0x86}//共阳数码管 P,E
uchar chushi_mima[]={2,1,3}
uchar shuru_mima[3]
uchar index//控制输入密码的位数
uchar flag_3s=0//3s标志位
uchar keydown//确定按键变量
#define times 15//去抖时间15Ms
uchar key1_count,key2_count,key3_count,key4_count
void init()
{
wela=0
SMG=0xff
TMOD=0x01
TH0=(65536-1000)/256
TL0=(65536-1000)%256
ET0=1
EA=1
TR0=1
LED=1;
}
void main()
{
init()
while(1)
{
switch(keydown)
{
if(index>2)index=0
case 1:
shuru_mima[index]=0
index++
break
case 2:
shuru_mima[index]=1
index++
break
case 3:
shuru_mima[index]=2
index++
break
case 4:
shuru_mima[index]=3
index++
break
}
flag_3s=0
for(i=0i<3i++)
{
if(shuru_mima[i]==chushi_mima[i])
{
LED=0
wela=1
SMG=table[0]
if(flag_3s)
{
flag_3s=0
wela=0
}
}
else
{
LED=1
wela=1
SMG=table[1]
if(flag_3s)
{
flag_3s=0
wela=0
}
}
}
}
}
void timer0() interrupt 1
{
uchar count
TH0=(65536-1000)/256
TL0=(65536-1000)%256
if(++count>=600)
{
count=0
flag_3s=1
}
/*********1ms中断扫描按键(包含去抖程序)********/
if(!key1&&key1_count!=0)
{
key1_count--
if(key1_count==0)
{
keydown=1
}
}
else if(!key1) key1_count=times
// key2,key3,key4你自己写吧
}
#include <reg52.h>#define uint unsigned int
#define uchar unsigned char
#define BIN(a,b,c,d,e,f,g,h) ((a<<7)+(b<<6)+(c<<5)+(d<<4)+(e<<3)+(f<<2)+(g<<1)+(h<锋伍<0))
//下面的code表示数组存放在ROM中,因为这个数组的值不需要改写
uchar code KeyCode[16]={15,14,12,8,30,28,24,16,60,56,48,32,120,112,96,64}//值为m*(n+1)的乘积,用于Key()
uchar dis[6]
msdelay(uint x)//延时子函数
{uchar j
while(x--)
{for(j=0j<125j++){}
}
}
//键盘子程序一,键盘值与数组值对比得到
uchar Key(void)
{uchar temp,m,n,i,j,matrix,k
P1=0xF0 /*行线电平为高,列线为低*/
temp=P1&0xf0
if (temp==0xf0) return(16)/*行仍轿扒为高,无按健,退出*/
else msdelay(10)
for(i=1i<16i=i*2)
{m=i
for(j=1j<16j=j*2)
{n=(~j)&0x0f
P1=(m<<4)|n/*m为P1的行值由i循环得到,n为列值,由j循环并取反得到*/
temp=P1&0xf0
if (!temp)
{do{temp=P1&0xf0}while(!temp)
matrix=m*(n+1)/*为避免乘积重复,n+1*/
for(k=0k<16k++){if (matrix==KeyCode[k]) return(k)} //KeyCode:见前
return(16)
} //if loop
}//j loop
}//i loop
}//Key end
//用Switch...case语句得到键盘值*/
uchar Key1(void)
{uchar temp,m,n,i,j,matrix
P1=0xF0 /*行线电平为高,列线为低*/
temp=P1&0xf0
if (temp==0xf0) return(16) /*行仍为高,无按健,退出*/
else msdelay(10)
for(i=1i<16i=i*2)
{m=i
for(j=1j<16j=j*2)
{n=(~j)&0x0f
P1=(m<<4)|n/*m为P1的行银帆或值由i循环得到,n为列值,由j循环并取反得到*/
temp=P1&0xf0
if (!temp)
{do{temp=P1&0xf0}while(!temp)
matrix=m*(n+1)
switch(matrix) //此方法的基本思路:
{case 15:return(1)break //由循环得到的m,n值赋于P1端口实现逐个键扫描
case 14:return(2)break //同时由m,n+1的值相乘得到对应键点de的积
case 12:return(3)break //m*(n+1)值扫描键点对应而得出键值
case 8:return(4)break //
case 30:return(5)break //
case 28:return(6)break //
case 24:return(7)break //
case 16:return(8)break
case 60:return(9)break
case 56:return(0)break
case 48:return(10)break
case 32:return(11)break
case 120:return(12)break
case 112:return(13)break
case 96:return(14)break
case 64:return(15)break
default:return(16)
} //switch end
} //if loop
}//j loop
}//i loop
}//Key end
//依次扫描16个按键
uchar Key2(void)
{uchar temp
P1=0xF0 /*使P1=1111 0000,行线电平为高,列线为低*/
temp=P1&0xf0
if (temp==0xf0) return(16) /*读P1=1111 xxxx,表示行仍为高,无按健,退出(x表示不关心)?/
else msdelay(10)
P1=0x1e /*P1=0001 1110,行一为高,列一为低,扫描第一个按键*/
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(1)}
P1=0x1d /*P1=0001 1101,行一为高,列二为低,扫描第二个按键,下面扫描其余按键*/
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(2)}
P1=0x1b
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(3)}
P1=0x17
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(4)}
P1=0x2e
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(5)}
P1=0x2d
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(6)}
P1=0x2b
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(7)}
P1=0x27
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(8)}
P1=0x4e
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(9)}
P1=0x4d
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(0)}
P1=0x4b
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(10)}
P1=0x47
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(11)}
P1=0x8e
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(12)}
P1=0x8d
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(13)}
P1=0x8b
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(14)}
P1=0x87
temp=P1&0xf0
if (!temp) {do{temp=P1&0xf0}while(!temp)
return(15)}
return(16) //扫描all按键都未按下,则输出16
}//Key2 end.
////////时钟中断显示子程序
void T0_int() interrupt 1
{static uchar i
if (i==6){i=0}
P0=5-i
P0=P0|(dis[i]<<4)
i++
TL0=0
TH0=252}
void distri(uint disnum)
{uint temp
dis[0]=0
dis[1]=disnum/10000
temp=disnum%10000
dis[2]=temp/1000
temp=temp%1000
dis[3]=temp/100
temp=temp%100
dis[4]=temp/10
dis[5]=temp%10
}
Main()
{uchar KeyVal,i=0
TMOD=0x01
IE=0x82
TH0=252
TL0=0
TR0=1
distri(0)
do{
KeyVal=Key()
if (KeyVal!=16) dis[1]=KeyVal//注意:当有按键时才赋于显示位dis[1],否则出错,请分析!
}while(1)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)