目录

1.需要的硬件 编辑

2.EEPROM功能

3.主要功能

4.按键功能

5.数码管与LED与蜂鸣器与继电器功能

1.密码输入时

 2.密码输入正确

3.密码输入错误 时

6.修改密码功能

7.初始化

注意事项

8.代码 

main

iic.c

iic.h



1.需要的硬件 

说错密码锁IP java 密码锁输错_说错密码锁IP java


2.EEPROM功能

因为密码存取在单片机内存中,重启后密码又返回初始化的值,数据易丢失。

因为EEPROM的数据单片机关机重启后数据不会发生改变,永远存在内存之中。

可以用来存取密码修改后存取的位置。

只有重新写入当地址的数据才会改变。


3.主要功能

用按键输入密码,密码错误蜂鸣器响1S后关闭,

密码错误超过3次就不能再输入密码数码管显示on。

密码输入正确数码管显示open。输入密码正确后按下S19可以修改密码再次按下S19确定修改的密码。

EEPROM可以对密码进行保护和修改。


4.按键功能

                      S19只有密码输入正确才能使用

S4 (0)

S8 (4)

S12(8)

S16(减位)

S5 (1)

S9 (5)

S13(9)

S17(清除)

S6 (2)

S10(6)

S14(无)

S18(无)

S7 (3)

S11(7)

S15(无)

S19(修改密码)


5.数码管与LED与蜂鸣器与继电器功能

1.密码输入时

数码管显示数字一步步向左移,最右位显示刚刚按下的数字。

说错密码锁IP java 密码锁输错_单片机_02

 2.密码输入正确

LED灯隔个点亮,继电器吸合,数码管显示open

说错密码锁IP java 密码锁输错_制造_03

3.密码输入错误 时

前两次密码错误蜂鸣器响

第三次密码再次错误数码管显示on,密码无法再次输入。

说错密码锁IP java 密码锁输错_说错密码锁IP java_04


6.修改密码功能

输入密码正确后按下S19,进入修改密码再次按下S19确定修改的密码。

修改密码LED灯1亮。


7.初始化

1.初始密码为:888888。

2.蜂鸣器关闭,继电器关闭。

3.LED灯关闭。


注意事项

修改密码时候不能关机要不然无法存入密码,密码还没有初始值。导致输入什么密码都是错误的。

这样情况可以重新在EEPROM的0X08地址写入0,下载进去然后又下载原来的程序就行了。


8.代码 

main

#include <STC15F2K60S2.H>
#include "iic.h"
void  Delay(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;
	while(xms--)
	{
	
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
	}
}

void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x20;		//设置定时初始值
	T2H = 0xD1;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
    IE2 |=0x04;
    EA=1;
}
int ms;

void Device(unsigned char p2,unsigned char p0)//配置138锁存器
{
    P0=p0;
    P2=P2&0x1f|p2;
    P2=P2&0x1f;
}

void system()//初始化
{
    Device(0x80,0xff);//关闭LED灯
    Device(0xa0,0);//关闭蜂鸣器
}
//                                                                         P    E   n      k
unsigned char Nixie[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x73,0x79,0x54,0x70};

void smg(unsigned n,unsigned m)//配数码管显示函数
{
    int a;
    a=0x01<<n;
    Device(0xc0,0);
    Device(0xe0,~Nixie[m]);//显示内容
    Device(0xc0,a);//显示位置
}


long int i=0;//按键的值
int s=0;//按键按下次数

int k=0;//用于修改密码的变量
int q=0;//密码正确操作的变量
int m=0;//用于数码管显示
/*
*S4  0;   S5  1;    S6   2;S7    3
*S8  4;   S9  5;    S10  6;S11   7
*S12 8;   S13 9;    S14  无;S15 无   
*S16 减位;   S17  清除;    S18  无;S19    修改密码
*/
//三次密码错误后就不能输入密码了
//密码输入正确后按S19才能更改密码

void kby()//密码输入与修改
{    
    
    P3=0xff;P44=0;P42=1;//行扫描
	if(P33==0) {Delay(1);if(P33==0){i=i*10+0,s++;while(P33==0){}}}//4
	if(P32==0) {Delay(1);if(P32==0){i=i*10+1;s++;while(P32==0){}}}
	if(P31==0) {Delay(1);if(P31==0){i=i*10+2;s++;while(P31==0){}}}
	if(P30==0) {Delay(1);if(P30==0){i=i*10+3;s++;while(P30==0){}}}
	
	P3=0xff;P42=0;P44=1;
	if(P33==0) {Delay(1);if(P33==0){i=i*10+4;s++;while(P33==0){}}}//8
	if(P32==0) {Delay(1);if(P32==0){i=i*10+5;s++;while(P32==0){}}}
	if(P31==0) {Delay(1);if(P31==0){i=i*10+6;s++;while(P31==0){}}}
	if(P30==0) {Delay(1);if(P30==0){i=i*10+7;s++;while(P30==0){}}}
	
	P3=0xdf;P4=0xff;
	if(P33==0) {Delay(1);if(P33==0){i=i*10+8;s++;while(P33==0){}}}
	if(P32==0) {Delay(1);if(P32==0){i=i*10+9;s++;while(P32==0){}}}
	
	
	P3=0xef;P4=0xff;
	if(P33==0) {Delay(1);if(P33==0){i=i/10;s--;while(P33==0){}}}
	if(P32==0) {Delay(1);if(P32==0){i=0;s=0;while(P32==0){}}}
	      
}

void smg_correct()//显示  open
{
    smg(4,0); Delay(1);
    smg(5,10);Delay(1);
    smg(6,11);Delay(1);
    smg(7,12);Delay(1);
}

void smg_show() //显示i的值
{
    //Delay(1)作用增加数码管显示亮度
    smg(2,i/100000);Delay(1);
    smg(3,i/10000%10);Delay(1);
    smg(4,i/1000%10);Delay(1);
    smg(5,i/100%10);Delay(1);
    smg(6,i/10%10);Delay(1);
    smg(7,i%10);Delay(1);

}

long int d,e,f,r,t,y;//用于接收EEPROM里面存取的数字
long int shong=0;

void smh()//读取EEPROM里面存取的数字
{

    d=ucRead_EEPROM(0x01)*100000;
    e=(long int)ucRead_EEPROM(0x02)*10000;
    f=ucRead_EEPROM(0x03)*1000;
    r=ucRead_EEPROM(0x04)*100;
    t=ucRead_EEPROM(0x05)*10;
    y=ucRead_EEPROM(0x06);
    shong=d+e+f+r+t+y;

}

int kl=1;//用于判断是否修改密码变量
long int o=888888;//初始值密码
int ccr=0;//密码错误1s后关闭蜂鸣器使用的变量
void main()
{
    system();
    Timer2Init();
    Write_EEPROM(0x07,0);

/*
修改密码时候不能关机要不然无法存入密码,密码还没有初始值。

这样情况可以重新在EEPROM的0X08地址写入0,下载进去然后又下载原来的程序就行了。
*/

//Write_EEPROM(0x08,0);

    //如果修改密码过0x08地址的值变成1
    if((ucRead_EEPROM(0x07)==0)&&(ucRead_EEPROM(0x08)==1))
    {
     kl=0;
    }
    
//判断需要不重新初始化密码
     if((k==0)&&(kl==1))
    {
    Write_EEPROM(0x01,o/100000);
    Write_EEPROM(0x02,o/10000%10);
    Write_EEPROM(0x03,o/1000%10);
    Write_EEPROM(0x04,o/100%10);
    Write_EEPROM(0x05,o/10%10);
    Write_EEPROM(0x06,o%10); 
    smh();
    }
    
while(1)   
{
    smh();  //不断获取最新密码值
   //显示i的值未输入正确密码的值 
    if(m!=1) 
    {
    smg_show();
    kby();
    }
    //S19第一次按下LED1亮
    if(k==1)
    {
        m=0;
        s=0;
       Device(0x80,~0x01);
     P3=0xef;P4=0xff;
    if(P30==0) {Delay(1);if(P30==0){k=2;while(P30==0){}}}      
    }
    
     
     //输入密码正确后操作   
    if((i==shong)&&(s==6)&&(k==0))
    {   
        i=0;
        q=1;   
        m=1;
        s=0;
           
    }
    
    
    //S19第二次按下密码的值发生改变
    if(k==2)
    {
    o=i;
    Write_EEPROM(0x01,o/100000);
    Write_EEPROM(0x02,o/10000%10);
    Write_EEPROM(0x03,o/1000%10);
    Write_EEPROM(0x04,o/100%10);
    Write_EEPROM(0x05,o/10%10);
    Write_EEPROM(0x06,o%10); 
    Write_EEPROM(0x08,1); 
    smh();   
    i=0;
    s=0;
    q=0;
    m=0;
    k=0;
    }

        //输入密码错误操作
    if((i!=shong)&&(s==6)&&(k==0))
    {
        Device(0xa0,0x40);
        i=0;
        s=0;
        ms=0;
        ccr++;
    }
    
    
}


}

void t2()   interrupt 12//中断入口
{
    
    ms++;
    
//密码输入错误1秒钟后关闭蜂鸣器
if((ms==1000)&&(ccr<3))
{
        Device(0xa0,0);
}
//输入密码错误超过三次的现象
if(ccr==3)
{
    m=1;
    smg(3,0);Delay(1);
    smg(4,12);Delay(1);
    Device(0xa0,0);
}

    //密码正确的操作
    if((q==1)&&(k==0))
    {
        
    smg_correct();
    Device(0xa0,0x10);
    Device(0x80,0xaa);
    P3=0xef;P4=0xff;
    if(P30==0) {Delay(1);if(P30==0){k=1;while(P30==0){}}}   
    }
   
   
}

iic.c

#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

void Delay_Ms(unsigned int ms)		//@12.000MHz
{
	unsigned char i, j;
while(ms--)
{
	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}
}


//总线引脚定义
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;    
}
 

//写入AT24C02     
void Write_EEPROM(unsigned char add, unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
	Delay_Ms(5);
}

//读取AT24C02
unsigned char  ucRead_EEPROM(unsigned char add)
{
	unsigned char dat;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	dat=IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return dat;
}

iic.h

#ifndef _IIC_H
#define _IIC_H

void Write_EEPROM(unsigned char add, unsigned char dat);
unsigned char  ucRead_EEPROM(unsigned char add);

#endif