程序.docx
《程序.docx》由会员分享,可在线阅读,更多相关《程序.docx(18页珍藏版)》请在冰豆网上搜索。
![程序.docx](https://file1.bdocx.com/fileroot1/2022-10/29/eb54de70-362d-4f26-90d0-23184079af49/eb54de70-362d-4f26-90d0-23184079af491.gif)
程序
/***************************************************
*标题:
密码锁
*日期:
2011-12-24
*作者:
郑海平
占用单片机口线状态:
占用了P0口和P3~0,P3~1,P3~5.
*************************************************
密码锁:
实现密码的修改,密码的存储,掉电后密码不丢失,使用的24c02模块,
根据液晶的提示便可进行操作,其中E键为确认键,输入密码后都要按确认键才能
确认,其中密码的长度为八位,
初始密码为88888888
超级密码为12345678
修改密码要输入初始密码或超级密码才能修改密码
占用口线为P3~3,P3~4.其中P3~3接SCL,P3~4接SDA.
***************************************************/
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineTa500//unsignedint
#defineOP_READ0xa1//器件地址以及读取操作
#defineOP_WRITE0xa0//器件地址以及写入操作
#defineMAX_ADDR0x7f//AT24C02最大地址
sbitSDA=P3^4;//24C02引脚的控制
sbitSCL=P3^3;
sbitLE=P3^6;
sbitrs=P3^0;//LCD引脚的控制
sbitrw=P3^1;
sbiten=P3^5;
ucharcommand0,data0,count=0;
ucharv=0;
bitf0=0;//f0,f1退出标志位参数
bitf1=0;
bityy=0;//f0,f1退出标志位参数
ucharsavein=0;
voidwrite(ucharcommand0);
ucharkeyscan(void);
ucharclick_0=0;//定时器1定时中断次数
ucharclick_1=0;
bittime=0;
//*****定义定时器TO时间常数和方式控制字******/
voidinit_sys(void)
{
TMOD=0x01;TH0=0x3c;TL0=0xb0;//设置时间初值
TR0=0;EA=1;ET0=1;TR1=0;//开启中断,关闭定时器
//IP=0x08;
}
/******************延时程序*********************/
voiddelay(uintm)
{
while(--m);
}
voiddelayms(ucharms)
//延时子程序
{
uchari;
while(ms--)
{
for(i=0;i<120;i++);
}
}
ucharcodeTable[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
ucharcodedis_code[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//0-9写入到AT24C01的数据串
ucharcodedis_code1[]={0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};//1-8超级密码
ucharyuanshimima[]={0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38};
ucharshuzu0[8];
ucharshuzu1[8];
ucharxiugai0[8];
ucharxiugai1[8];
voidstart()//开始位
{
SDA=1;
SCL=1;
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
voidstop()//停止位
{
SDA=0;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
}
ucharshin()//从AT24Cxx移入数据到单片机
{
uchari,read_data;
for(i=0;i<8;i++)
{
SCL=1;
read_data<<=1;
read_data|=(uchar)SDA;
SCL=0;
}
return(read_data);
}
bitshout(ucharwrite_data)//从单片机移出数据到AT24Cxx
{
uchari;
bitack_bit;
for(i=0;i<8;i++)//循环移入8个位
{
SDA=(bit)(write_data&0x80);
_nop_();
SCL=1;
_nop_();
_nop_();
SCL=0;
write_data<<=1;
}
SDA=1;//读取应答
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
ack_bit=SDA;
SCL=0;
returnack_bit;//返回AT24Cxx应答位
}
voidwrite_byte(ucharaddr,ucharwrite_data)//在指定地址addr处写入数据write_data
{
start();
shout(OP_WRITE);
shout(addr);
shout(write_data);
stop();
delayms(10);//写入周期
}
voidfill_byte(ucharfill_data)//填充数据fill_data到EEPROM内
{
uchari;
for(i=0;i{
write_byte(i,fill_data);
}
}
ucharread_current()//在当前地址读取
{
unsignedcharread_data;
start();
shout(OP_READ);
read_data=shin();
stop();
returnread_data;
}
ucharread_random(ucharrandom_addr)//在指定地址读取
{
start();
shout(OP_WRITE);
shout(random_addr);
return(read_current());
}
/******************LCD功能设置******************/
voidlcd_set(void)
{
command0=0x30;//功能设定,8位数据传送
write(command0);
command0=0x01;//清除显示
write(command0);
command0=0x06;//进入点设定,游标的移动方向,显示的移位
write(command0);
command0=0x0c;//显示状态,D=1,C=0,B=0
write(command0);
}
/*******************清屏程序*********************/
voidlcd_clear(void)
{
command0=0x01;
write(command0);
}
/*****************写指令程序********************/
voidwrite(ucharcommand0)
{
delay(100);
rs=0;
rw=0;
P0=command0;
en=1;
_nop_();
_nop_();
en=0;
}
/*****************写数据程序********************/
voidread(uchardata0)
{
delay(100);
rs=1;
rw=0;
P0=data0;
en=1;
_nop_();
_nop_();
en=0;
}
//===========字符显示============================
voiddisplay(uchary,ucharx,uchar*p)
{
switch(y)
{
case1:
write(0x7f+x);break;//X=1,液晶第一行第一个
case2:
write(0x8f+x);break;//0x90+(x-1)
case3:
write(0x87+x);break;
case4:
write(0x97+x);break;
default:
break;
}
while(*p)
read(*p++);
}
/******************键扫子程序*********************/
ucharkeyscan(void)
{
ucharscan,tmp;
P1=0xf0;//发全行0扫描码
if((P1&0xf0)!
=0xf0)//若有键按下
{delay(1000);//延时去抖
if((P1&0xf0)!
=0xf0)//延时再判键是否还按下
{scan=0xfe;
while((scan&0x10)!
=0)//逐行扫描
{
P1=scan;//输出行扫描码
if((P1&0xf0)!
=0xf0)//本行有键按下
{tmp=(P1&0xf0)|0x0f;
return((~scan)|(~tmp));}//还回键值
elsescan=(scan<<1)|0x01;//行扫描码左移一位
}
}
}
return(0);//无键按下,返回0
}
/**************密码锁菜单界面下的密码修改的密码存入24C02中************/
voidsave(void)
{uchari=0;
fill_byte(0xff);
for(i=0;i<8;i++)
write_byte(i,xiugai1[i]);//写入修改后的密码
write_byte(8,savein);//写入是否修改密码的标志
}
/********************密码锁菜单界面下的密码修改的密码******************/
voidchangemima(void)