智能门锁---基于15单片机
| | | |
| —- | —- | —- |
| | | |
/基于15单片机的程序/
/author:CJ=/
/date:2020/2/25=/
include “stc15.h”
include “iic.h”
define u8 unsigned char
define u16 unsigned int
define set(x) P4=(x>>3|x>>4);P3=x //定义矩阵按键
define get() ((P4&0x10)<<3)|((P4&0x04)<<4)|(P3&0x3f)
u8 Trg,Cont,dat,key_flag=0;
u8 code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0X8C,0X86,0XC8,0xc6};
u8 dis[8]={11,11,11,11,11,11,11,11},com=0;
u8 pwd[6]={8,8,8,8,8,8}; //密码888 888
u8 mima[6]; // 数码管对应
void Timer0Init(void);
u16 right,error;
u16 xiu_f, right_n,error_n; //标志位
u8 num,f;
u8 input,eliminate,modify=0;
void in_put();
void modify_x();
void delayms(int xms) //延时函数
{
int i,j;
for(i=xms;i>0;i–)
for(j=845;j>0;j–);
}
void KBD() //独立按键 –基于三行代码
{
set(0xf0);
dat=get();
set(0x0f);
dat=(dat|get())^0xFF;
Trg=dat&(dat^Cont);
Cont=dat;
}
void main()
{
/初始化/
P2=0XA0;P0=0X00;P2=0;P2=0X80;P0=0XFF;P2=0;
P2=0XE0;P0=0XFF;P2=0;P2=0XC0;P0=0XFF;P2=0;
Timer0Init();
while(1)
{
in_put();
modify_x();
/按键处理/
if(key_flag)
{
key_flag=0;
KBD();
switch(Trg ^ 0xFF)
{
case 0x7e:num=0;f=1;break;
case 0x7d:num=4;f=1;break;
case 0x7b:num=8;f=1;break;
case 0xbe:num=1;f=1;break;
case 0xbd:num=5;f=1;break;
case 0xbb:num=9;f=1;break;
case 0xb7:
eliminate=1;
if(modify)
{
eliminate=0;
dis[0]=15;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=11;dis[5]=11;
dis[6]=11;dis[7]=11;
}
break;
case 0xde:num=2;f=1;break;
case 0xdd:num=6;f=1;break;
case 0xd7:
if(xiu_f1)
{
if(!modify) //修改密码
{
modify=1;
right=0;right_n=0;
P2=0X80;P0=0x7f;P2=0;
P2=0XA0;P0=0X00;P2=0;
dis[0]=15;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=11;dis[5]=11;
dis[6]=11;dis[7]=11;
}
if((dis[2]!=11)&&(modify==1)) //修改输入密码状态
{
modify=0;
right=1;right_n=0;
xiu_f=0;
write_2402(0x10,pwd[0]);delayms(10);
write_2402(0x20,pwd[1]);delayms(10);
write_2402(0x30,pwd[2]);delayms(10);
write_2402(0x40,pwd[3]);delayms(10);
write_2402(0x50,pwd[4]);delayms(10);
write_2402(0x60,pwd[5]);delayms(10);
dis[0]=10;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=0;dis[5]=12;
dis[6]=13;dis[7]=14;
P2=0XA0;P0=0X10;P2=0;
}
}
break;
case 0xee:num=3;f=1;break;
case 0xed:num=7;f=1;break;
case 0xe7:
input=1;f=0;
dis[0]=10;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=11;dis[5]=11;
dis[6]=11;dis[7]=11;
break;
}
}
}
}
/输入密码/
void in_put()
{
if(input1)
{
if((dis[7] == 11)&&(f))
{
f=0;
dis[7]=num;
mima[0]=dis[7];
}
else if((dis[6] == 11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=mima[0];
mima[1]=dis[7];
}
else if((dis[5] == 11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=mima[1];
dis[5]=mima[0];
mima[2]=dis[7];
}
else if((dis[4] == 11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=mima[2];
dis[5]=mima[1];
dis[4]=mima[0];
mima[3]=dis[7];
}
else if((dis[3] == 11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=mima[3];
dis[5]=mima[2];
dis[4]=mima[1];
dis[3]=mima[0];
mima[4]=dis[7];
}
else if((dis[2] == 11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=mima[4];
dis[5]=mima[3];
dis[4]=mima[2];
dis[3]=mima[1];
dis[2]=mima[0];
mima[5]=dis[7];
}
else if((dis[2] == 11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=mima[4];
dis[5]=mima[3];
dis[4]=mima[2];
dis[3]=mima[1];
dis[2]=mima[0];
mima[5]=dis[7];
}
}
if(eliminate)
{
eliminate=0;
dis[0]=10;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=11;dis[5]=11;
dis[6]=11;dis[7]=11;
}//输入按键下可清除
if(dis[2]!=11) //判断密码输满 为六位
{
input=0;right_n=0;
if((pwd[0]==mima[0])&&(pwd[1]==mima[1])&&(pwd[2]==mima[2])&&(pwd[3]==mima[3])&&(pwd[4]==mima[4])&&(pwd[5]==mima[5])) //密码正确open
{
P2=0X80;P0=0XFF;P2=0;
P2=0XA0;P0=0X10;P2=0;
xiu_f=1; //输入成功后,才可以按下修改按键,跳转至修改密码界面
dis[0]=0;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=0;dis[5]=12;
dis[6]=13;dis[7]=14;
right=1; //5s后关闭
}
else if(!modify) //密码error ,不为modify时 L1熄灭
{
P2=0X80;P0=0XFE;P2=0;
error=1;
}
}
}
/修改密码/
void modify_x()
{
if(modify1)
{
P2=0X80;P0=0X7F;P2=0;
if((dis[7]11)&&(f))
{
f=0;
dis[7]=num;
pwd[0]=dis[7];
}
else if((dis[6]11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=pwd[0];
pwd[1]=dis[7];
}
else if((dis[5]11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=pwd[1];
dis[5]=pwd[0];
pwd[2]=dis[7];
}
else if((dis[4]11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=pwd[2];
dis[5]=pwd[1];
dis[4]=pwd[0];
pwd[3]=dis[7];
}
else if((dis[3]11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=pwd[3];
dis[5]=pwd[2];
dis[4]=pwd[1];
dis[3]=pwd[0];
pwd[4]=dis[7];
}
else if((dis[2]11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=pwd[4];
dis[5]=pwd[3];
dis[4]=pwd[2];
dis[3]=pwd[1];
dis[2]=pwd[0];
pwd[5]=dis[7];
}
else if((dis[2]==11)&&(f))
{
f=0;
dis[7]=num;
dis[6]=pwd[4];
dis[5]=pwd[3];
dis[4]=pwd[2];
dis[3]=pwd[1];
dis[2]=pwd[0];
pwd[5]=dis[7];
}
}
}
/定时器处理/
u8 key_cnt, seg_cnt;
void timer0() interrupt 1
{
if(++key_cnt10)
{
key_cnt=0;
key_flag=1;
}
if(++seg_cnt3)
{
seg_cnt=0;
P2=0XE0;P0=0XFF;P2&=0;
P2=0XC0;P0=0X01<<com;P2=0;
P2=0XE0;P0=tab[dis[com]];P2&=0;
if(++com8)com=0;
}
if(right)
{
if(++right_n==5000) //5后关闭
{
right_n=0; right=0;
error=0;
modify=0;
P2=0X80;P0=0XFF;
P2=0XA0;P0=0X00;
dis[0]=11;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=11;dis[5]=11;
dis[6]=11;dis[7]=11;
input=0; //关闭输入按键
}
}
if(error)
{
if(++error_n==5000)
{
error_n=0;
error=0;
P2=0X80;P0=0XBF;P2=0;
dis[0]=10;dis[1]=11;
dis[2]=11;dis[3]=11;
dis[4]=11;dis[5]=11;
dis[6]=11;dis[7]=11;
input=1; //等待密码重新输入
}
}
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
/驱动程序=/
/==iic.c=/
include “reg52.h”
include “intrins.h”
include “iic.h”
define DELAY_TIME 40
define SlaveAddrW 0xA0
define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 /
sbit SCL = P2^0; / 时钟线 */
void IIC_Delay(unsigned char i)
{
do{nop();}
while(i–);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
unsigned char read_2402(uchar addr)
{
uchar temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_Stop();
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
void write_2402(uchar addr,uchar dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
/iic.h=/
ifndef _IIC_H
define _IIC_H
ifndef uchar
define uchar unsigned char
endif
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
unsigned char read_2402(uchar addr);
void write_2402(uchar addr,uchar dat);