一共分为好几个文件
#include "delay.h"文件:
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
#include "eeprom.h"文件:
#include "delay.h"
void Start(void) //I2开始
{
SDA=1;
SCL=1;
NOP4();
SDA=0;
NOP4();
SCL=0;
}
void Stop(void) //I2C停止
{
SDA=0;
SCL=0;
NOP4();
SCL=1;
NOP4();
SDA=1;
}
void RACK(void) //读取应答
{
SDA=1;
NOP4();
SCL=1;
NOP4();
SCL=0;
}
void NO_ACK(void) //发送非应答信号
{
SDA=1;
SCL=1;
NOP4();
SCL=0;
SDA=0;
}
void Write_A_Byte(uchar b) //写一个字节数据
{
uchar i;
for(i=0;i<8;i++)
{
b<<=1;
SDA=CY; //CY进位程序状态字寄存器
_nop_();
SCL=1;
NOP4();
SCL=0;
}
RACK();
}
void Write_IIC(uchar addr,uchar dat) //向指写地地址写数据
{
Start();
Write_A_Byte(0xa0);
Write_A_Byte(addr);
Write_A_Byte(dat);
Stop();
DelayMs(10);
}
uchar Read_A_Byte(void) //读取一个字节
{
uchar i,b;
for(i=0;i<8;i++)
{
SCL=1;
b<<=1;
b|=SDA;
SCL=0;
}
return b;
}
uchar Read_Current(void) //从当前地址取数据
{
uchar d;
Start();
Write_A_Byte(0xa1);
d=Read_A_Byte();
NO_ACK();
Stop();
return d;
}
uchar Random_Read(uchar addr) //从任意地址读取数据
{
Start();
Write_A_Byte(0xa0);
Write_A_Byte(addr);
Stop();
return Read_Current();
}
#include "key.h"
unsigned char key_scan()
{
unsigned char temp,keyno;
P1=0x0f;
DelayMs(1);
temp=P1^0x0f;
switch(temp) //纵行
{
case1:keyno=1/*1*/;break; //第一纵行
case2:keyno=2/*2*/;break; //第二纵行
case4:keyno=3/*3*/;break; //第三纵行
case8:keyno=4/*3*/;break; //第四纵行
}
P1=0xf0;
DelayMs(1);
temp=P1>>4^0x0f;
switch(temp)
{ //横行
case 1:keyno+=0 /*A*/;break;//第一行横行
case 2:keyno+=4 /*B*/;break;//第一行横行
case 4:keyno+=8 /*C*/;break;//第一行横行
case 8:keyno+=12 /*D*/;break;//第一行横行
}
P1=0x0f;
return keyno;
}
#include"LCD.H"文件
void write_com(unsigned char com) //写命令
{
RS_CLR;
RW_CLR;
P0=com;
DelayMs(5);
EN_SET;
DelayMs(5);
EN_CLR;
}
void write_data(unsigned char date) //写一个字符
{
RS_SET;
RW_CLR;
P0=date;
DelayMs(5);
EN_SET;
DelayMs(5);
EN_CLR;
}
void init() //初始化
{
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsignedchar x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
write_com(0x80 + x);
}
else
{
write_com(0xC0+ x);
}
while (*s)
{
write_data( *s);
s ++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned charx,unsigned char y,unsigned char Data)
{
if (y == 0)
{
write_com(0x80+ x);
}
else
{
write_com(0xC0+ x);
}
write_data(Data);
}
主文件
#include <REGX52.H>
#include <intrins.h>
#include "lcd.h"
#include "key.h"
#include "delay.h"
#include "eeprom.h"
void int0(void);
unsigned char password[6]/*={0x01,0x01,0x01,0x01,0x01,0x01}*/;
unsigned char password1[6];
unsigned char code aa[]="Password ";
unsigned char code gg[]="New";
unsigned char code bb[]="ERROR ";
unsigned char code cc[]="OK ";
unsigned char code dd[]=" ";
unsigned char code ee[]="Next ";
unsigned char code ff[]="success ";
unsigned char keydata;
main()
{
unsigned char i,j,k,l,m,n,o,a1;
/*for(i=0;i<6;i++)
{
Write_IIC(i,password[ i]);
}*/
init();//LCD初始化
int0();
P3_6=0;
P3_7=0;
P1=0x0f;
LCD_Write_String(0,0,aa);
LCD_Write_String(1,1,dd);
write_com(0xc0+1);
while(1)
{
start: LCD_Write_String(0,0,aa);
LCD_Write_String(1,1,dd);
write_com(0xc0+1);
while(1)
{
if((0<keydata)&&(4>keydata)||(4<keydata)&&(8>keydata)||(8<keydata)&&(12>keydata)||keydata==14)
//在0-9之间的数字通过
{
password=keydata;//键盘值进行保存
keydata=0; //把键盘值置其它值,不被其它利用,以一样
i++;
write_data('*'); //在LCD上显示*这字符代表输入了一个密码
if(i==6) //这里限制了六位密码
{
i=0;
goto panduan;
}
}
if(keydata==33) //确定进入密码比较
{
keydata=0;
panduan: i=0;
for(j=0;j<6;j++)
{
l+=password[j];
k+=Random_Read(j);
}
if(l!=k) //密码不同进行处理
{
l=0;
k=0;
LCD_Write_String(0,0,bb);
DelayMs(1000);
a1+=1;
if(a1==2){while(1)P3_7=1;P3_6=0;}//两次错误发出报警
goto start; //第二次输入密码
}
if(l==k) //密码对了,进入运行状态,这里绿灯代表该状态
{
l=0;
k=0;
a1=0;
P3_6=1;
P3_7=0;
LCD_Write_String(0,0,cc);
LCD_Write_String(1,1,dd);
if(o==1)
{
o=0;
LCD_Write_String(0,0,gg);
LCD_Write_String(4,0,aa);
LCD_Write_String(1,1,dd);
write_com(0xc0+1);
goto text2;
}
goto yingxing; //跳到下面函数中,yingxing里
}
}
}
yingxing:while(1)
{
if(keydata==4) //锁定功能
{
P3_6=0;
goto start;
}
if(keydata==15) //修改密码
{
o++;
if(o==1) goto start;
text2: keydata=0;
while(1)
{
if((0<keydata)&&(4>keydata)||(4<keydata)&&(8>keydata)||(8<keydata)&&(12>keydata)||keydata==14)
//上面表达式0-9之间的数字通过
{
password[m]=keydata; //读取键盘值
keydata=0;
m++;
write_data('*');
if(m==6) //到密码输入到六位的时候进行判断是否再输入,或者判断前后两次密码是否一致
{
m=0;
n++;
if(n==2)goto panduan1; //输入第二次的时候进行前后两次密码进判断
for(i=0;i<6;i++) //储存前一次密码
{
password1=password[ i];
}
LCD_Write_String(1,1,dd);
LCD_Write_String(0,0,ee);
DelayMs(1000);
LCD_Write_String(0,0,aa);
write_com(0xc0+1);
}
}
if(keydata==13) //重新输入改密
{
text: m=0;
n=0;
LCD_Write_String(1,1,dd);
write_com(0xc0+1);
}
if(keydata==33) //退出不改密码
{
out: m=0;
n=0;
o=0;
LCD_Write_String(0,0,cc);
LCD_Write_String(1,1,dd);
goto yingxing;
}
if(keydata==33)
{
keydata=0;
panduan1: for(j=0;j<6;j++)//第一次与第二次密码比较
{
l+=password[j];
k+=password1[j];
}
if(l!=k) //第一次与第二次密码输入错误
{
l=0;
k=0;
LCD_Write_String(0,0,bb);
DelayMs(1000);
LCD_Write_String(0,0,aa);
goto text;
}
else
{
for(i=0;i<6;i++)
{
Write_IIC(i,password[ i]);
}
LCD_Write_String(0,0,ff);
DelayMs(1000);
goto out;
}
}
}
}
}
}
}
void int0(void)
{
EA=1;
EX0=1;
IT0=1;
}
void ISR_INT0(void) interrupt 0
{
keydata=key_scan();
}