📄 main.c
字号:
#include <stc89.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P2^0;//数据命令选择端
sbit rw=P2^1;//读写选择端
sbit e=P2^2;//使能端
#define port P0//lcd数据
sbit beep=P1^0;//蜂鸣器
sbit led=P1^1;//开锁指示灯
uchar buffer[4];
uchar n;
uchar dat;
uchar js;//解锁
bit ks; //开锁
uchar wrong;
uchar bp; //蜂鸣器时间控制
uchar mima[17]; //已设定密码
uchar mima_temp[17]; //当前输入密码
uchar mima1[17]; //改密码用
uchar mmxg; //密码修改控制
uchar asc[16]="01234567890ABCDEF";
void show(uchar c);
void lcd_wr(uchar a,uchar c);
void delay(uchar c);
void send(uchar c);
void IAP_Disable();
void eeprom_wr();
void eeprom_re();
void delay(uchar c) //1ms 误差 -0.651041666667us
{
unsigned char a,b;
while(c--)
{
for(b=102;b>0;b--)
for(a=3;a>0;a--);
}
}
void InitUART(void) //9600串口初始化
{
TMOD = 0x21;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
uchar lcd_re(uchar a)
{
uchar c;
e=0;
rw=1;
rs=a;
;
;
e=1;
;
;
e=0;
c=port;
return c;
}
void busy()
{
uchar i;
i=1;
while((lcd_re(0)&0x80)&&i++);
}
void lcd_wr(uchar a,uchar c)
{
busy();
e=0;
rw=0;
rs=a;
port=c;
;
;
e=1;
;
;
e=0;
}
/**************初始化**************/
void lcd_int(void)
{
delay(15);
rs=0;
rw=0;
port=0x38;
e=1;
;
;
e=0;
delay(5);
port=0x38;
e=1;
;
;
e=0;
delay(5);
port=0x38;
e=1;
;
;
e=0;
rw=1;
rs=1;
lcd_wr(0,0x38); //显示模式设置
lcd_wr(0,0x08); //关闭显示
lcd_wr(0,0x01); //清屏
lcd_wr(0,0x02);
lcd_wr(0,0x06); //光标又移,整屏不移动
lcd_wr(0,0x0c); //开显示
}
//mm:ss:s
void show(uchar c)
{
uchar i;
lcd_wr(0,0x80);//地址为第一行第一个字符
lcd_wr(1,'E');
lcd_wr(1,'n');
lcd_wr(1,'t');
lcd_wr(1,'e');
lcd_wr(1,'r');
lcd_wr(1,' ');
lcd_wr(1,'P');
lcd_wr(1,'a');
lcd_wr(1,'s');
lcd_wr(1,'s');
lcd_wr(1,'W');
lcd_wr(1,'o');
lcd_wr(1,'r');
lcd_wr(1,'d');
lcd_wr(1,' ');
if(mmxg==1) lcd_wr(1,'1');
else if(mmxg==2) lcd_wr(1,'2');
else lcd_wr(1,' ');
lcd_wr(0,0xc0);//o代表指令,1代表数据//地址为第二行第一个字符
if(c<17)//c输入密码个数
{
for(i=0;i<c;i++)
lcd_wr(1,'*');
}
else
{
if(c==110) //show PassWord Right
{
lcd_wr(1,'P');
lcd_wr(1,'a');
lcd_wr(1,'s');
lcd_wr(1,'s');
lcd_wr(1,'W');
lcd_wr(1,'o');
lcd_wr(1,'r');
lcd_wr(1,'d');
lcd_wr(1,' ');
lcd_wr(1,'R'); //Ringht
lcd_wr(1,'i');
lcd_wr(1,'g');
lcd_wr(1,'h');
lcd_wr(1,'t');
lcd_wr(1,'!');
}
if(c==119)
{
lcd_wr(1,'P');
lcd_wr(1,'a');
lcd_wr(1,'s');
lcd_wr(1,'s');
lcd_wr(1,'W');
lcd_wr(1,'o');
lcd_wr(1,'r');
lcd_wr(1,'d');
lcd_wr(1,' ');
lcd_wr(1,'W'); //wrong
lcd_wr(1,'r');
lcd_wr(1,'o');
lcd_wr(1,'n');
lcd_wr(1,'g');
lcd_wr(1,'!');
}
}
for(i=0;i<16;i++) //写空格,防止显示重叠
lcd_wr(1,' ');
lcd_wr(0,0x0c); //开显示
}
uchar mmyz()//密码验证
{
uchar j;
for(j=0;j<17;j++)
{
send(mima_temp[j]);
send(mima[j]);
}
if(mima_temp[16]==mima[16])
{
for(j=0;j<mima[16];j++)
if(mima_temp[j]!=mima[j]) return 2; //密码错误退出
wrong=0;
return 1;
}
else return 2;
}
main()
{
uchar i,j;
uchar k,s;
eeprom_re();
if(mima[16]>16)
{
for(j=0;j<17;j++)
mima[j]=6;
}
lcd_int();
InitUART(); //串口初始化
ET0=1;
EX1=1; //开外部中断1
IT1=1; //下隆沿中断
show(0);
while(1)
{
if(js)
{
js=0;
if(buffer[2]<13)
{
if(i<16)
{
mima_temp[i]=buffer[2];
i++;
show(i);
}
}
else
{
if(buffer[2]==13&&i) i--,show(i); //退格
if(buffer[2]==14)
{
if(ks) ks=0;
i=0,show(i); //清屏
}
if(buffer[2]==15&&ks) //修改密码
{
mmxg=1;
i=0;
show(i);
}
if(buffer[2]==16) //确定
{
i=0;
if(mmxg) //密码修改
{
if(mmxg==2)
{
s=0;
if(mima1[16]==mima_temp[16])
{
s++;
for(j=0;j<mima_temp[16];j++)
{
if(mima1[j]==mima_temp[j])
{
s++;
}
}
}
mmxg=0;
if(s>mima1[16])
{
for(j=0;j<17;j++)
{
mima[j]=mima1[j];
// send(mima[j]);
}
show(110);
eeprom_wr();
}
else show(119);
}
if(mmxg==1)
{
for(j=0;j<17;j++)
mima1[j]=mima_temp[j];
mmxg=2;
show(i);
}
}
else k=mmyz();
}
}
mima_temp[16]=i; //密码长度
// send(buffer[2]);
// send(mima_temp[16]);
}
if(k==1) ks=1,show(110);
if(k==2) ks=0,show(119),wrong++;
k=0;
if(ks) led=0;
else led=1;
if(wrong>2) wrong=0,bp=100;
}
}
/************外部中断1**********************/
void Int1(void) interrupt 2 using 1
{
uchar dh;
uchar k;
TR0=0;
dh=TH0;
TL0=0;
TH0=0;
TR0=1;
if(dh>25&&dh<100) n=33;
else if(dh>2&&dh<5) k=0;
else if(dh>6&&dh<12) k=1;
else n=0;
if(n)
{
dat=dat<<1;
dat+=k;
if(n==25) buffer[0]=dat,dat=0;
if(n==17) buffer[1]=dat,dat=0;
if(n==9) buffer[2]=dat,dat=0;
if(n==1) buffer[3]=dat,dat=0;
n--;
if(!n)
{
if(!(buffer[2]&buffer[3])) //数据校验
{
js=1; //接收完成
beep=0;
}
else
{
buffer[0]=0;
buffer[1]=0;
}
}
}
// send(dh);
}
/************定时器0**********************/
void Timer0Interrupt(void) interrupt 1
{
TR0=1;
n=0;
if(bp) bp--,beep=0;
else beep=1;
}
/************串口**********************/
void send(uchar c)
{
EA=0;
SBUF = c;
while(!TI);
TI = 0;
EA=1;
}
void delay1s(void) //误差 -0.000000000285us
{
unsigned char a,b,c;
for(c=13;c>0;c--)
for(b=247;b>0;b--)
for(a=142;a>0;a--);
}
void UARTInterrupt(void) interrupt 4
{
uchar c;
if(RI)
{
RI = 0;
c=SBUF;
if(c==0xaa)
{
delay1s();
ISP_CONTR=0x60;
}
}
else
TI = 0;
}
//******************************EEPROM***********************************//
void IAP_Disable()
{
//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
ISP_CONTR = 0; //关闭IAP 功能
ISP_CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用
ISP_TRIG = 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
ISP_ADDRH = 0;
ISP_ADDRL = 0;
}
void eeprom_wr()
{
uchar *p;
uchar i;
p=mima;
ISP_CONTR=0x82; //启动IAP
ISP_CMD=0x03; // 擦除
ISP_ADDRH=0x20; //地址
ISP_ADDRL=1;
EA=0;
ISP_TRIG=0x46; //命令生效
ISP_TRIG=0xb9;
;
EA=1;
ISP_CMD=0x02; //命令写
for(i=0;i<17;i++)
{
ISP_DATA=*p; //数据
p++;
ISP_ADDRH=0x20; //地址
ISP_ADDRL=i;
EA=0;
ISP_TRIG=0x46; //命令生效
ISP_TRIG=0xb9;
;
EA=1;
}
IAP_Disable();
}
void eeprom_re()
{
uchar *p;
uchar i;
p=mima;
ISP_CONTR=0x82; //启动IAP
ISP_CMD=0x01; //命令读
for(i=0;i<17;i++)
{
ISP_ADDRH=0x20; //地址
ISP_ADDRL=i;
ISP_TRIG=0x46; //命令生效
ISP_TRIG=0xb9;
;
*p=ISP_DATA;
p++;
}
IAP_Disable();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -