#include<reg52.h>
#include<intrins.h>
#define NOP4() {_nop_();_nop_();_nop_();_nop_();}
#define uchar unsigned char
sbit SDA=P3^4;
sbit SCL=P3^3;
void Start(void);
void Stop(void);
void RACK(void);
void NO_ACK(void);
void DelayMs(unsigned char t);
void Write_A_Byte(uchar b);
void Write_IIC(uchar addr,uchar dat);//向指写地地址写数据
uchar Read_A_Byte(void);
uchar Read_Current(void);
uchar Random_Read(uchar addr); //从任意地址读取数据
sbit P3_6=P3^6;
sbit P3_7=P3^7;
void int0(void);
unsigned char key_scan();
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;
sbit SDA1=128;//串行数据输入,对应595的14脚SER
sbit SCL1=129;//移位寄存器时钟输入,对应595的11脚SCK
sbit SCL2=130;//存储寄存器时钟输入,对应595的12脚RCK
sbit SDA2=131;//串行数据输入,对应595的14脚SER
sbit SCL3=132;//移位寄存器时钟输入,对应595的11脚SCK
sbit SCL4=133;//存储寄存器时钟输入,对应595的12脚RCK
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
//X是地址,Y是行数,都是从0开始;
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);//写入字符串函数
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);//写入字符函数
void init(); //初始化
void write_com(unsigned char com);
void write_data(unsigned char date);
/*------------------------------------------------
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);
}
}
//以下是LCD1602驱动程序
void delay1000(unsigned int aaaaaa)
{
unsigned int bbbbbb,cccccc;
for(bbbbbb=aaaaaa;bbbbbb>0;bbbbbb--)
for(cccccc=110;cccccc>0;cccccc--);
}
void in(unsigned char dddddd)
{
unsigned char eeeeee;
for(eeeeee=0;eeeeee<8;eeeeee++) //循环8次,刚好移完8位
{
dddddd<<=1;
SCL1=CY;
SDA1=1; //先将移位寄存器控制引脚置为低
_nop_();
_nop_();
SDA1=0;
}
}
void out()
{
SCL2=0; //先将存储寄存器引脚置为低
_nop_();
SCL2=1; //再置为高,产生移位时钟上升沿,上升沿时移位寄存器的数据进入数据存储寄存器,更新显示数据。
_nop_();
SCL2=0;
}
void in1(unsigned char ffffff)
{
unsigned char gggggg;
for(gggggg=0;gggggg<8;gggggg++) //循环8次,刚好移完8位
{
ffffff<<=1;
SCL3=CY;
SDA2=1; //先将移位寄存器控制引脚置为低
_nop_();
_nop_();
SDA2=0;
}
}
void out1()
{
SCL4=0; //先将存储寄存器引脚置为低
_nop_();
SCL4=1; //再置为高,产生移位时钟上升沿,上升沿时移位寄存器的数据进入数据存储寄存器,更新显示数据。
_nop_();
SCL4=0;
}
void write_com(unsigned char hhhhhh)
{
in(248);//再传段码
out();
delay1000(2);//延迟时间2ms以内
in1(hhhhhh); //再传段码
out1();
delay1000(2); //延迟时间2ms以内
in(252);//再传段码
out();
delay1000(2);//延迟时间2ms以内
in(248);//再传段码
out();
delay1000(2);//延迟时间2ms以内
}
void write_data(unsigned char iiiiii)
{
in(249);//再传段码
out();
delay1000(2);//延迟时间2ms以内
in1(iiiiii); //再传段码
out1();
delay1000(2); //延迟时间2ms以内
in(253);//再传段码
out();
delay1000(2);//延迟时间2ms以内
in(249);//再传段码
out();
delay1000(2);//延迟时间2ms以内
}
//LCD1602液晶初始化子函数
void init()
{
write_com(56);
write_com(12);
write_com(6);
write_com(128);
write_com(1);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char 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++;
}
}
unsigned char key_scan()
{
unsigned char temp,keyno;
P1=0x0f;
DelayMs(1);
temp=P1^0x0f;
switch(temp) //纵行
{
case 1: keyno=1/*1*/;
break; //第一纵行
case 2: keyno=2/*2*/;
break; //第二纵行
case 4: keyno=3/*3*/;
break; //第三纵行
case 8: 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;
}
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();
}
void main()
{
unsigned char i,j,k,l,m,n,o,a1;
unsigned int aaaa=65536;
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[i]=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)
{
// aaaa--;
P3_7=1;
P3_6=0;
// if(aaaa==0)
{
// P3_7=0;
a1=0;
//aaaa=65536;
//goto start;
}
}
}//两次错误发出报警
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
- 2
前往页