HOT-51电路图.pdf
(103.6 KB)
/********************************************************
*文件名:Password_clock
*功能:利用AT24c02,输入密码播放一段音乐,同时可以修改密码
*创建人:计算机科学与信息工程学院 米中勤 2011-9-5
*********************************************************/
#include <reg52.h>
#include <intrins.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
sbit lcd_rs=P2^5;//1602lcd数据/命令选择引脚
sbit lcd_rw=P2^6;//1602lcd读写引脚
sbit lcd_en=P2^7;//1602lcd使能端
sbit scl=P1^5; //24c08 SCL
sbit sda=P3^6; //24c08 SDA
sbit Int0=P3^2; //外部中断0
sbit In=P3^3;//输入密码键
sbit Ch=P3^4;//修改密码键
sbit d=P1^2;//蜂鸣器驱动引脚
uchar Count;
uchar m,tmp,lock_flag;
static uint kai=0;
uchar code Seg_table[]="0123456789ABCDEF";
uchar Enter[14]="Iput Password:";
uchar init_password[6]="123456";
uchar a[5]="RIGHT";
uchar b[16]="The new password";
/*以下数组是音符编码*/
unsigned char code pu[282]={
0x03,0xfb,0x05,0x00,0x00,0x04,
0x03,0xfb,0x02,0x03,0xfb,0x02,
0x43,0xfc,0x02,0x0b,0xfc,0x02,
0x8f,0xfb,0x02,0x8f,0xfb,0x02,
0x8f,0xfb,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x05,0x00,0x00,0x03,
0x43,0xfc,0x02,0x8f,0xfb,0x02,
0x43,0xfc,0x02,0x8f,0xfb,0x02,
0x43,0xfc,0x04,0x8f,0xfb,0x02,
0x03,0xfb,0x02,0x8f,0xfb,0x02,
0x03,0xfb,0x02,0x14,0xfa,0x02,
0x8f,0xfb,0x02,0x03,0xfb,0x05,
0x00,0x00,0x03,0x03,0xfb,0x05,
0x00,0x00,0x04,0x03,0xfb,0x02,
0x03,0xfb,0x02,0x43,0xfc,0x02,
0x0b,0xfc,0x02,0x8f,0xfb,0x02,
0x8f,0xfb,0x02,0x8f,0xfb,0x02,
0x03,0xfb,0x02,0x8f,0xfb,0x02,
0x00,0x00,0x03,0x43,0xfc,0x02,
0x8f,0xfb,0x02,0x43,0xfc,0x02,
0x8f,0xfb,0x02,0x43,0xfc,0x04,
0x8f,0xfb,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x08,0xfd,0x02,
0xab,0xfc,0x02,0x00,0x00,0x03,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x04,0xab,0xfc,0x02,
0x43,0xfc,0x02,0xab,0xfc,0x02,
0x43,0xfc,0x02,0x43,0xfc,0x04,
0x08,0xfd,0x04,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x08,0xfd,0x04,
0xab,0xfc,0x04,0xab,0xfc,0x02,
0x43,0xfc,0x02,0x43,0xfc,0x04,
0x43,0xfc,0x04,0x8f,0xfb,0x04,
0xab,0xfc,0x04,0x00,0x00,0x04,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x04,0xab,0xfc,0x02,
0x43,0xfc,0x02,0xab,0xfc,0x02,
0x43,0xfc,0x02,0x43,0xfc,0x02,
0x08,0xfd,0x04,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x08,0xfd,0x02,
0xab,0xfc,0x02,0xab,0xfc,0x05,
0x00,0x00,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0xab,0xfc,0x04,
0x43,0xfc,0x02,0x43,0xfc,0x05
};
/*******************************************************************
*名称:delay_music()
*功能:音乐节拍延时
*输入:a a=1,1/16/拍,a=2,1/8拍,a=4,1/4拍
*输出:无
********************************************************************/
void delay_music(unsigned char a)
{
unsigned int b;
while(a--)
{
for(b=10300;b>=1;b--);
}
}
/********************************************************************
* 名称 : delay1()
* 功能 : 短暂延时
* 输入 : x
* 输出 : 无
***********************************************************************/
void delay1(uchar x)
{
uint i;
for(i=0; i<x; i++);
}
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时,延时时间为 1ms * i
* 输入 : i(延时1ms的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)
{
uchar x, j;
for(j=0; j<i; j++)
for(x=0; x<=148; x++);
}
/********************************************************************
* 名称 : Delay_xMs()
* 功能 : 延时子程序,经过软件调试,测得延时程序大概为55us.
* 输入 : x
* 输出 : 无
***********************************************************************/
void Delay_xMs(uint x)
{
uint i,j;
for(i=0; i<x; i++)
{
for(j=0; j<3; j++);
}
}
/********************************************************************
* 名称 : flash()
* 功能 : 延时,时间为2个NOP,大概为2US
* 输入 : 无
* 输出 : 无
***********************************************************************/
void flash(void)
{
_nop_();
_nop_();
}
/********************************************
*名称:delay()
*功能:延时大概140us
*输入:无
*输出:无
*********************************************/
void delay()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++);
}
/*********************************************
*名称:lcd_writecom(uchar com)
*功能:向1602写入命令
*输入:命令
*输出:无
**********************************************/
void lcd_writecom(uchar com)
{
lcd_rs=0;
lcd_rw=0;
lcd_en=0;
P0=com;
delay();
lcd_en=1;
delay();
lcd_en=0;
}
/**********************************************
*名称:lcd_readdata(uchar dat)
*功能:向1602lcd写入数据
*输入:dat
*输出:无
***********************************************/
void lcd_writedata(uchar dat)
{
lcd_rs=1;
lcd_rw=0;
lcd_en=0;
P0=dat;
delay();
lcd_en=1;
delay();
lcd_en=0;
}
/*****************************************
*名称:lcd_init()
*功能:1602lcd初始化
*输入:无
*输出:无
******************************************/
void lcd_init()
{
lcd_writecom(0x38);
lcd_writecom(0x0c);
lcd_writecom(0x06);
lcd_writecom(0x01);
lcd_writecom(0x80);
}
/************************************************
*名称:lcd_char(uchar row ,uchar cloum,uchar dat)
*功能:在lcd的第row行,第cloum列,写入数据dat
*输入:row cloum dat
*************************************************/
void lcd_char(uchar row ,uchar cloum,uchar dat)
{
if(row==1)
{
lcd_writecom(0x80+cloum);
lcd_writedata(dat);
}
else
{
lcd_writecom(0x80+0x40+cloum);
lcd_writedata(dat);
}
}
/*********************************************
名称:lcd_string(uchar row,uchar cloum,uchar *p)
功能:从第row行 ,第cloum列,把一串字符写入lcd
输入:row cloum p
**********************************************/
void lcd_string(uchar row,uchar cloum, uchar *p)
{
uchar a;
if(row==1) a=0x80;
if(row==2) a=0xc0;
a=a+cloum-1;
lcd_writecom(a);
while(1)
{
if(*p=='\0') break;
lcd_writedata(*p);
p++;
}
}
/********************************************************************
* 名称 : x24c02_init()
* 功能 : 24c02初始化子程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void x24c02_init(void)
{
scl = 1;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : start(void)
* 功能 : 启动I2C总线
* 输入 : 无
* 输出 : 无
***********************************************************************/
void start(void)
{
sda = 1;
flash();
scl = 1;
flash();
sda = 0;
flash();
scl = 0;
flash();
}
/********************************************************************
* 名称 : stop()
* 功能 : 停止I2C总线
* 输入 : 无
* 输出 : 无
***********************************************************************/
void stop()
{
sda = 0;
flash();
scl = 1;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : writex()
* 功能 : 写一个字节
* 输入 : j(需要写入的值)
* 输出 : 无
***********************************************************************/
void writex(uchar j)
{
uchar i,temp;
temp = j;
for(i=0; i<8; i++)
{
temp = temp << 1;
scl = 0;
flash();
sda = CY;
flash();
scl = 1;
flash();
}
scl = 0;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : readx()
* 功能 : 读一个字节
* 输入 : 无
* 输出 : 读出的值
***********************************************************************/
uchar readx(void)
{
uchar i, j, k = 0;
scl = 0;
flash();
sda = 1;
for(i=0; i<8; i++)
{
flash();
scl = 1;
flash();
if(sda == 1)
{
j = 1;
}
else j = 0;
k = (k << 1) | j;
scl = 0;
}
flash();
return(k);
}
/********************************************************************
* 名称 : clock()
* 功能 : I2C总线时钟
* 输入 : 无
* 输出 : 无
***********************************************************************/
void clock(void)
{
uchar i = 0;
scl = 1;
flash();
while((sda == 1) && (i < 255))
{
i++;
}
scl = 0;
flash();
}
/********************************************************************
* 名称 : x24c02_read()
* 功能 : 从24c02中读出值
* 输入 : address(要在这个地址读取值)
* 输出 : 从24c02中读出的值
***********************************************************************/
uchar x24c02_read(uchar address)
{
uchar i;
start();
writex(0xa0);
clock();
writex(address);
clock();
start();
writex(0xa1);
clock();
i = readx();
stop();
delay1(10);
return(i);
}
/********************************************************************
* 名称 : x24c02_write()
* 功能 : 想24c02中写入数据
* 输入 : address(地址) , info(值)
* 输出 : 无
***********************************************************************/
void x24c02_write(uchar address, uchar info)
{
start();
writex(0xa0);
clock();
writex(address);
clock();
writex(info);
clock();
stop();
delay1(50);
}
/*******************************************************
*函数名:keyscan()
*功能:键盘扫描
*输入:无
*输出:键值
********************************************************/
uchar keyscan()
{
uchar temp,num,k;
P1=0xfe;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];
}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=5;
break;
case 0xdd:num=6;
break;
case 0xbd:num=7;
break;
case 0x7d:num=8;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];
}
}
P1=0xfb;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=9;
break;
case 0xdb:num=10;
break;
case 0xbb:num=11;
break;
case 0x7b:num=12;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=13;
break;
case 0xd7:num=14;
break;
case 0xb7:num=15;
break;
case 0x77:num=16;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];
}
}
return k;
}
/********************************************************************
*名称:play()
*功能:播放音乐《猪之歌》
*输入:无
*输出:无
*********************************************************************/
void play()
{
uchar xun=94;
kai=0;
TMOD=0x01;
EA=1;
ET0=1;
TH0=0xff;
TL0=0xf0;
while(xun>=1)
{
TR0=1;
if((pu[kai==0])&(pu[kai+1]==0))
TR0=0;
delay_music(pu[kai+2]);
TR0=0;
kai+=3;
xun--;
}
}
/*********************************************
*名称Input_password()
*功能:输入密码
*输入:无
*输出:无
**********************************************/
void Input_password()
{ uchar i,j,k=0,flag;
uchar input[6];
while(1)
{
if(lock_flag==5)break;
if(In==0)
{
Delay_1ms(5);
if(In==0)
{
lcd_init();
lcd_string(1,1,"Input Password");
while(!In);
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{
m=keyscan();
lcd_char(2,j,'*');
input[j]=m;
P1=0xf0;
j++;
if(j==6)
{
break;
}
}
if(j==6)
{
j=0;
break;
}
}
for(i=0;i<6;i++)
{
if(input==x24c02_read(i))
flag=1;
else
{
flag=0;lcd_init();
lcd_string(1,4,"Error!!!");lock_flag++;break;
}
}
if(flag==1)
{
lcd_init();
lcd_string(1,5,"MUSIC");
lcd_string(2,5,"A PIG'SONG");
while(1)
{
play();
}
}
}
}
}
}
/*********************************************
*名称:Change_Password()
*功能:改变密码
*输入:无
*输出:无
**********************************************/
void Change_Password()
{
uchar i,j,flag;
uchar input[6];
uchar input2[6],input1[6];
while(1)
{
if(Ch==0)
{
Delay_1ms(5);
if(Ch==0)
{
lcd_init();
lcd_string(1,1,"The old Password");
while(Ch);
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{
m=keyscan();
lcd_char(2,j,'*');
input[j]=m;
P1=0xf0;
j++;
if(j==6)
{
break;
}
}
if(j==6)
{
j=0;
break;
}
}
for(i=0;i<6;i++)
{
if(input==x24c02_read(i))
flag=1;
else
{
flag=0;
lcd_init();
lcd_string(1,4,"Error!!!");
break;
}
}
while(flag==1)
{
lcd_init();
lcd_string(1,1,"Password RIGHT!");
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
lcd_init();
lcd_string(1,1,"The new password");
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{
m=keyscan();
lcd_char(2,j,'*');
input1[j]=m;
P1=0xf0;
j++;
if(j==6)
{
//j=0;
break;
}
}
if(j==6)
{
j=0;
break;
}
}
lcd_init();
tmp=input1[5];
lcd_string(1,2,"Input again");
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{
m=keyscan();
lcd_char(2,j,'*');
input2[j]=m;
P1=0xf0;
j++;
if(j==6)
{
break;
}
}
if(j==6)
{
j=0;
break;
}
}
flag=0;
for(i=0;i<6;i++)
{
if(input1==input2) flag=1;
else
{
flag=0;
lcd_init();
lcd_string(1,1,"Don't agree!!");
break;
}
}
if(flag==1)
{
for(i=0;i<6;i++)
{
x24c02_write(i,input2);
Delay_1ms(100);
}
lcd_init();
lcd_string(1,6,"Modify");
lcd_string(2,2,"Successfully!");
tmp=input2[5];
Input_password();
}
}
}
}
}
}
/********************************************************************
* 名称 : Time0_Init()
* 功能 : 定时器的初始化,定时时间可用光碟中软件计算,11.0592MZ晶振,10ms
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Init()
{
TMOD = 0x01;
IE = 0x82;
TH0 = 0xDC;
TL0 = 0x00;
}
/********************************************************************
* 名称 : Time0_Int()
* 功能 : 定时器中断,中断中实现 长度加1
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Int() interrupt 1
{
TL0=pu[kai];
TH0=pu[kai+1];
d=~d; //长度加1
}
/********************************************************************
* 名称 : Main(void)
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{ uchar i;
x24c02_init() ;
lcd_init();
Time0_Init();
lcd_string(1,1,"Password Lock");
for(i=0;i<6;i++);
{
x24c02_write(i,init_password);
Delay_1ms(100);
}
while(1)
{ if(In==0)
{
Delay_1ms(5);
if(In==0)
Input_password();
if(lock_flag==5)
{
lcd_init();
lcd_string(1,3,"NOT ALlOW ");
lcd_string(2,5,"ACCESS!!!");
break;
}
}
if(Ch==0)
{
Delay_1ms(5);
if(Ch==0)
Change_Password();
}
}
while(1);
} |