一共分為好幾個文件
#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();
}