📄 程序.c
字号:
#include<AT89X52.H>
#define uchar unsigned char
uchar digbit; // 字位
uchar wordbuf[6 ]; // 字型缓冲码
uchar t1count; // 定时器T0由50ms累积到5 s所用的计数器
unsigned char second; // 秒
unsigned char minute; // 分
unsigned char hour; //时
unsigned int tcnt;
uchar count; // 密码位记数
uchar pw[6]; // 初始密码存储区
uchar pwbuf[6]; // 输入密码存储区
uchar wrong; //错误次数计数器
bit cancelflag; // 取消键标志位
bit enterflag; // 确认键标志位
bit zhflag; // 功能键转换标志位
bit pwflag; // 密码正确标志位
bit showflag; // 数码管显示标志位
sbit green=P2^2;
sbit red=P2^1;
sbit spk=P2^0;
void display();
bit pwcmp ();
/* 键盘消抖延时函数 10mus */
void delay ()
{
uchar i,j ;
for (i=200;i>0;i--)
for (j=50;j>0;j--);
}
/* 键盘扫描程序 */
uchar keyscan (void)
{
uchar scancode,tmpcode;
P0= 0xf0; // 发全0行扫描
if ((P0&0xf0)!= 0xf0) // 若有键按下
{
delay(); // 消除抖动 10ms
if ((P0&0xf0)!= 0xf0)
{
scancode=0xfe;
while ((scancode&0x10)!=0) // 逐行扫描
{
P0 = scancode; // 输出行扫码
if ((P0&0xf0)!=0xf0) // 本行有键按下
{
tmpcode=(P0&0xf0)|0x0f ;
while ((P0&0xf0)!=0xf0) ;
return ((~scancode)+(~tmpcode)); // 按键行列码
}
else scancode=( scancode<<1)|0x01 ; // 行扫码左移一位
}
}
}
return (0);
}
void time1_int(void) interrupt 3 using 0
{
tcnt++; //定时器中断次数加1,250US
if(tcnt==4000)
{
tcnt=0;
second++;
if(second==60) // 秒进位
{
second=0;
minute++;
if(minute==60) //分进位
{
minute=0;
hour++;
if(hour==24) // 时进位
{
hour=0;
}
}
}
} //if(tcnt==4000) END
}
void time0_int(void) interrupt 1 // 50ms
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
if (t1count<100) // 5秒
{
t1count ++;
}
else
{
TR0=0; // 关T0
count=0; //密码计数器清零
t1count=0; // 5秒计数器清零
red=1;
green=1;
cancelflag=0;
showflag=1; // 打开显示
digbit=0xfe; // 第一位字型码
/* 初始显示 */
wordbuf[0]=0x0e;
wordbuf[1]=0x0e;
wordbuf[2]=0x0e;
wordbuf[3]=0x0e;
wordbuf[4]=0x0e;
wordbuf[5]=0x0e;
}
}
/* 共阳极数码管0~9,A~B字型代码 */
uchar getcode (uchar i )
{
uchar p;
switch (i)
{
case 0: p=0xc0; break; // 0
case 1: p=0xf9; break; // 1
case 2: p=0xa4; break; // 2
case 3: p=0xb0; break; // 3
case 4: p=0x99; break; // 4
case 5: p=0x92; break; // 5
case 6: p=0x82; break; // 6
case 7: p=0xf8; break; // 7
case 8: p=0x80; break; // 8
case 9: p=0x90; break; // 9
case 10: p=0x88; break; // 10
case 11: p=0x83; break; // 11
case 12: p=0xc6; break; // 12
case 13: p=0xa1; break; // 13
case 14: p=0x86; break; // 14
case 15: p=0x8e; break; // 15
default: break;
}
return (p) ;
}
/* 显示函数 */
void display(void)
{
uchar i;
switch (digbit)
{
case 0xfe: i=0; break; //第1位字型码
case 0xfd: i=1; break; //第2位字型码
case 0xfb: i=2; break; //第3位字型码
case 0xf7: i=3; break; //第4位字型码
case 0xef: i=4; break; //第5位字型码
case 0xdf: i=5; break; //第6位字型码
default: break;
}
P1 = getcode(wordbuf[i]); // 送字型码
P3 = digbit ; // 送字位码
if (digbit>0xdf) // 共六位
digbit =(digbit<<1)|0x01; // 左移一位
else
digbit = 0xfe;
}
/* 密码比较函数 */
bit pwcmp (void)
{
bit flag ;
uchar i;
for (i=0;i<6;i++)
{
if (pw[i]==pwbuf[i])
flag=1;
else
{
flag=0;
i=6;
}
}
return (flag);
}
/* 报警 */
void sound (void)
{
unsigned int i,j,k;
unsigned int count1,sound1,tone;
count1=60;
sound1=40;
tone=110;
for (k=0;k<count1;k++)
{
P3=0xff;
red = ~ red;
for (i = 0; i<sound1;i++)
{
spk= ~ spk;
for (j=0;j<tone;j++);
}
delay();
}
}
void sound1 (void)
{
unsigned int i,k,j;
unsigned int count1,sound1,tone;
count1=30;
sound1=20;
tone=70;
for (k=0;k<count1;k++)
{
P3=0xff;
green = ~ green;
for (i = 0; i<sound1;i++)
{
spk= ~ spk;
for (j=0;j<tone;j++);
}
delay();
}
}
void sound2 (void)
{
unsigned int i,j,k;
unsigned int count1,sound1,tone;
count1=40;
sound1=30;
tone=90;
for (k=0;k<count1;k++)
{
P3=0xff;
red = ~ red;
for (i = 0; i<sound1;i++)
for (j=0;j<tone;j++);
delay();
}
}
/* 主程序 */
void main()
{
uchar j,key;
P3 = 0xff; // 关闭数码管显示
TMOD=0x21; // 工作方式
TH0=(65536-50000)/256; // 5毫秒
TL0=(65536-50000)%256;
TR0=0;
ET0=1;
TH1=0X06; // 250us
TL1=0X06;
TR1=1;
ET1=1;
EA=1; // 开中断
count=0; // 初始没有密码输入,计数器为0
enterflag=0; // 没有确定键按下
cancelflag=0;
pwflag=0; // 密码标志记为0
green =1;
spk=1;
wrong=0;
red =1; // 红灯、绿灯不亮
/* 设定初始密码 */
pw[0]=1;
pw[1]=2;
pw[2]=3;
pw[3]=4;
pw[4]=5;
pw[5]=6;
/* 设定时间 */
second=50;
minute=58;
hour=12;
showflag =1 ; // 打开数码管显示
/* 刚加电时显示 8888888 */
wordbuf[0]=0x0e;
wordbuf[1]=0x0e;
wordbuf[2]=0x0e;
wordbuf[3]=0x0e;
wordbuf[4]=0x0e;
wordbuf[5]=0x0e;
digbit = 0xfe; // 从第一位开始动态扫描
while (1)
{
display();
key = keyscan(); // 调用键盘扫描函数
switch (key)
{
case 0x11: // 第1行第1列,数字0
TR0=0;
TR0=1;
if (zhflag==1)
{
second++;
if(second==60) // 调秒
{
second=0;
}
}
else
{
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 0;
count+=1;
}
}
break;
case 0x21: // 第1行第2列,数字1
TR0=0;
TR0=1;
if (zhflag==1)
{
minute++;
if(minute==60) // 调分
{
minute=0;
}
}
else
{
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 1;
count+=1;
}
}
break;
case 0x41: // 第1行第3列,数字2
TR0=0;
TR0=1;
if (zhflag==1)
{
hour++;
if(hour==24) // 调时
{
hour=0;
}
}
else
{
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 2;
count+=1;
}
}
break;
case 0x81: // 第1行第4列,数字3
TR0=0;
TR0=1;
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 3;
count+=1;
}
break;
case 0x12: // 第2行第1列,数字4
TR0=0;
TR0=1;
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 4;
count+=1;
}
break;
case 0x22: // 第2行第2列,数字5
TR0=0;
TR0=1;
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 5;
count+=1;
}
break;
case 0x42: // 第2行第3列,数字6
TR0=0;
TR0=1;
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 6;
count+=1;
}
break;
case 0x82: // 第2行第4列,数字7
TR0=0;
TR0=1;
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 7;
count+=1;
}
break;
case 0x14: // 第3行第1列,数字8
TR0=0;
TR0=1;
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 8;
count+=1;
}
break;
case 0x24: // 第3行第2列,数字9
TR0=0;
TR0=1;
if (count<6)
{
wordbuf[count]=0x0f ; // 对应位显示 F
pwbuf[count] = 9;
count+=1;
}
break;
case 0x44:
enterflag=1 ; //比较密码
if (count==6)
pwflag = pwcmp () ;
else
pwflag = 0 ;
break;
case 0x84:
count=0;
cancelflag=1;
for (j=0;j<6;j++) // 取消密码输入
{
wordbuf[j]=8;
pwbuf[j]=0x0f; // 显示888888
}
t1count=50;
TR0=1; //开T0
break;
case 0x18:
count=0;
zhflag=~zhflag; // 功能转换
break;
default: break;
}
if (zhflag==1) //显示电子钟
{
wordbuf[0]=second%10;
wordbuf[1]=second/10;
wordbuf[2]=minute%10;
wordbuf[3]=minute/10;
wordbuf[4]=hour%10;
wordbuf[5]=hour/10;
}
else
{
if ((count==0)&(cancelflag==0))
{
t1count=150;
TR0=1; // 开T0
}
}
if (enterflag ==1)
{
enterflag = 0;
count = 0;
t1count = 0;
if (pwflag==1) //密码正确
{
wrong=0;
sound1();
TR0=1;
}
else
{
wrong+=1;
if(wrong==3) //错误三次
{
sound(); //调用报警并锁定键盘
wrong=0;
TR0=1; //开T0
}
else
{
sound2(); //密码错误
TR0=1;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -