c51电子密码锁程序代码(终稿)学位论文.doc
超级密码锁、备份/*= 密码锁控制 =/*连接线图: -| LCM-51 | LCM-51|LCM-51 | - | DB0-P0.0 | DB4-P0.4 | RS-P2.0 | DB1-P0.1 | DB5-P0.5 | RW-P2.1 | DB2-P0.2 | DB6-P0.6 | E-P2.2 | DB3-P0.3 | DB7-P0.7 | VLCD接1K电阻到GND |-接口说明:1. P1口: 4x4矩阵键盘 2. P2.4 工作指示灯 3. P2.5 继电器控制端 4. P3.7 蜂鸣器控制端 5. P3.3 24c02时钟端SCL 6. P3.4 24c02数据端SDA/*接盘按键说明:- | 1 | 2 | 3 | A | - - - - - - - - - - - - - | 4 | 5 | 6 | B | - - - - - - - - - - - - - | 7 | 8 | 9 | C | - - - - - - - - - - - - - | * | 0 | # | D |-注:AT89S51使用12M晶振=定义与申明=*/#include "regx52.h"#include "string.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned int/* 引脚定义引脚#define LCM_RS P2_0 / 数据/命令选择信号 #define LCM_RW P2_1 / 读/写选择信号#define LCM_E P2_2 / 使能信号#define WLED P2_4 / 工作指示灯#define REL P2_5 / 继电器#define BELL P3_7 / 蜂鸣器#define SCL P3_3 / 模拟I2C串行时钟控制#define SDA P3_4 / 模拟I2C串行数据传输#define LCM_Data P0 / 显示数据端口#define AddWr 0xa0 / "1010 0000B"器件地址选择及写标志#define AddRd 0xa1 / "1010 0001B"器件地址选择及读标志/控制字格式:/*- - - - - - - - - - - 1 0 1 0 A2 A1 A0 R/W - - - - - - - - - - - */*注:1. 前4位为I2C总线特征编码:1010 2. A2 A1 A0为24c02的地址 3. R/W=0:表示写入;R/W=1:表示读出 */* 变量定义#define Busy 0x80 / 用于检测LCM状态字中的Busy标识uchar Count,num; / 计数器uint con_30m; / 30min计数器uchar con_20s; / 10s计数器bit flag,mark,sign,mark0;/ 常用标志位bit flag1; / Choice_menu()调用标志bit signx; / 循环标志bit markx;/* 数组定义uchar code O_Password=0x30,0x30,0x30,0x30,0x30,0x30;/ 原始密码 "000000"uchar data N_Password=0x00,0x00,0x00,0x00,0x00,0x00;/ 新密码uchar data T_Password=0x00,0x00,0x00,0x00,0x00,0x00;/ 输入密码暂存/* 函数声明void Start(void); / 开始总线函数void Stop(void); / 结束总线函数uchar Read(void); / 读一字节数据bit Send(uchar Data);/ 发送一字节数据uchar ReadCurrent(uchar Address);/ 从指定处读出一字节void WriteCurrent(uchar Data,uchar Address);/ 在指定地址处写入一字节void ReadFromROM(uchar Data,uchar Address,uchar Num);/ 从指定地址读出Num个数据void WriteToROM(uchar Data,uchar Address,uchar Num); / 从指定地址写入Num个数据uchar ReadStatusLCM(void); / 读状态void LCMInit(void); / LCM初始化void WriteDataLCM(uchar WDLCM); / 写数据void WriteCommandLCM(uchar WCLCM,BuysC); / 写指令void DisplayOneChar(uchar X, uchar Y, uchar DData); / 按指定位置显示一个字符void DisplayListChar(uchar X, uchar Y, uchar code *DData); / 按指定位置显示一串字符void PasswordComparison(bit mark);/密码比较void Scan_starnumber(void);void Delay5Ms(void); / 5ms延时void Delay400Ms(void); / 400ms延时void Delay1s(void); / 1s延时void Delay_bell(void); / 蜂鸣器发音延时void DelayMs(uchar ms); / 延时 uchar Key_scan(void); / 按键扫描uchar Key_switch(void); / 按键转换函数void Choice_menu(void); / 选择菜单界面void Reset_success(void); / 复位成功提示void Pass_face(void); / 密码输入提示void Password_OK(void); / 密码输入正确提示void Welcome_face(void); / 欢迎界面void Password_ERROR(void); / 密码输入错误提示void Password_importation(void); / 密码输入void NewPassword_face(void); / 输入新密码提示void NewPassword_again(void); / 再次输入新密码提示void NewPassword_set(void); / 新密码输入void NewPassword_set_again(void); / 再次输入新密码void Newpassword_OK(void); / 新密码设置成功提示void Newpassword_ERROR(void); / 新密码设置失败提示void Newpassword_comparison(void); / 新密码设置比较void Beep(void); / 蜂鸣器发音void Led_hint(void); / LED工作指示/= 主函数部分 =/* 函 数 名:void clearmen(void) 功 能:系统初始化 说 明:对系统用的标志位和定时器进行初始化 入口参数:无 返 回 值:无 */void clearmen(void) flag1= 1; / Choice_menu()调用标志 signx= 1; / 循环标志 flag = 1; / 调用输入新密码提示标志位 mark = 1; / 循环标志位 markx= 1; num = 0; / 按键错误计数器 WriteToROM(O_Password,0,6); TH0=0x3C;TL0=0xB0; / 50ms定时初值 TH1=0x3C;TL1=0xB0; / 50ms定时初值 TMOD=0x11;ET0=1;TR0=0;ET1=1;TR1=0;EA=1;/* 函 数 名:main() 功 能:主函数 说 明:对按键和显示进行控制 入口参数:无 返 回 值:无 */void main(void) uchar Key_value; Delay400Ms(); / 启动等待,等LCM讲入工作状态 LCMInit(); / LCM初始化 Delay400Ms(); clearmen(); / 系统初始化 while(1) P1=0xf0; if(P1&0xf0)!=0xf0)&(flag1=1)&(num<3) / 有键按下 Key_value=Key_switch(); / 按键扫描 if(Key_value!=0) / 的确有键按下 Choice_menu(); / 调用选择程序 flag1=0; / Choice_menu()调用标志 signx=1; / 循环标志 while(signx=1) TR0=0; / 定时器0关,从先开始计时 TR0=1; / 定时器0开 P1=0xf0; / P1口赋值,从而判断有无按键 if(P1&0xf0)!=0xf0) Key_value=Key_switch(); / 按键扫描 if(Key_value=65) / 如果按键是"A",则输入密码 markx=1; / 显示密码输入正确或错误提示 while(mark=1) Password_importation(); / 密码输入 flag1=1; / Choice_menu()调用标志 signx=0; / 循环标志 if(Key_value=66) / 如果按键是"B",则输入新密码 markx=0; / 不显示密码输入正确或错误提示 while(mark=1) / 输入前比较秘密,密码正确进入新密码设置 / 密码错误退出密码设置 Password_importation(); / 密码输入 /- if(mark0!=0) / mark0=1:密码比较正确可以输入新密码 / mark0=0:密码比较错误不能输入新密码 mark=1; / 进入循环标志 while(mark=1) NewPassword_set(); / 新密码设置函数 mark=1; / 进入循环标志 while(mark=1) NewPassword_set_again(); / 再次输入密码 flag1=1; / Choice_menu()调用标志 signx=0; / 循环标志 mark0=1;flag= 1; if(Key_value=67) / 如果按键是"C",则密码复位 markx=0; / 不显示密码输入正确或错误提示 mark=1; / 进入循环标志 while(mark=1) Password_importation(); if(mark0!=0) Reset_success(); Delay1s(); Delay1s(); WriteToROM(O_Password,0,6); sign=0; WriteCurrent(uchar)sign,10); / 存入标志位 Reset_success(); else Welcome_face(); / 欢迎界面mark = 1; / 循环标志mark0= 0; / 是否输入新密码标志位 flag1=1; / Choice_menu()调用标志WriteCommandLCM(0x0C,1); / 关光标显示sign=(bit)ReadCurrent(10); / 密码比较标志位 if(num=3) / 3次输入错误密码,系统锁定30min ET1=1;TR1=1; / 开定时器T1,定时30分钟 /= 24c02部分函数 =/* 函 数 名:void Start(void) 功 能:开始总线函数 说 明:启动I2C总线,即发送I2C起始条件 入口参数:无 返 回 值:无 */void Start(void)SDA = 1; / 发送起始条件的数据信号SCL = 1;_nop_();_nop_();SDA = 0; / 发送起始信号_nop_(); / 起始条件锁定时间大于4us_nop_();_nop_();_nop_();SCL = 0; / 钳住I2C总线准备发送或接受数据/* 函 数 名:void Stop(void) 功 能:结束总线函数 说 明:结束I2C总线,即发送I2C结束条件 入口参数:无 返 回 值:无 */void Stop(void)SDA = 0; / 发送结束条件的数据信号_nop_();_nop_();SCL = 1; / 发送I2C总线结束信号_nop_(); / 结束条件锁定时间大于4us_nop_();_nop_();_nop_();SDA = 1;/* 函 数 名:bit Send(uchar Data) 功 能:发送一字节数据 说 明:向24c02中写入数据 入口参数:Data 返 回 值:无 */bit Send(uchar Data)uchar i;bit ack_bit;for(i = 0; i < 8; i+)/ 循环移入8个位SDA = (bit)(Data & 0x80);_nop_();SCL = 1;_nop_();_nop_();SCL = 0;Data <<= 1;SDA = 1; / 读取应答_nop_();_nop_();SCL = 1;_nop_();_nop_();_nop_();_nop_();ack_bit = SDA;SCL = 0;return ack_bit;/ 返回AT24Cxx应答位/* 函 数 名:void WriteCurrent(uchar Data,uchar Address) 功 能:在指定地址Address处一个数据Data 说 明:在指定地址处写入一字节的数据 入口参数:Data,Address 返 回 值:无 */void WriteCurrent(uchar Data,uchar Address) Start();Send(AddWr);Send(Address);Send(Data);Stop();DelayMs(10);/ 写入周期 /* 函 数 名:void WriteToROM(uchar Data,uchar Address,uchar Num) 功 能:在指定地址Address处写入Num个数据Data 说 明:在指定地址处写入一字节的数据 入口参数:Data,Address,Num 返 回 值:无 */void WriteToROM(uchar Data,uchar Address,uchar Num) uchar i;uchar *PData; PData=Data;for(i=0;i<Num;i+)Start();Send(AddWr);Send(Address+i);Send(*(PData+i);Stop();DelayMs(10);/ 写入周期/* 函 数 名:uchar Read(void) 功 能:读一字节数据 说 明:从24c02中读出数据 入口参数:无 返 回 值:Read_data */uchar Read(void)unsigned char i,Read_data;Start();Send(AddRd);for(i = 0; i < 8; i+)SCL = 1;Read_data <<= 1;Read_data |= (uchar)SDA;SCL = 0; Stop();return(Read_data);/* 函 数 名:uchar ReadCurrent(uchar Address) 功 能:从指定地址读一字节数据 说 明:从24c02中读出数据 入口参数:Address 返 回 值:Read() */uchar ReadCurrent(uchar Address)Start();Send(AddWr);Send(Address);return Read();/* 函 数 名:void ReadFromROM(uchar Data,uchar Address,uchar Num) 功 能:从24C02中读出一字节的数据 说 明:在指定地址读取 入口参数:Data,Address,Num 返 回 值:无 */void ReadFromROM(uchar Data,uchar Address,uchar Num) uchar i;uchar *PData; PData=Data;for(i=0;i<Num;i+)Start();Send(AddWr);Send(Address+i);*(PData+i)=Read();/= 密码控制部分 =/* 函 数 名:void Newpassword_comparison(void) 功 能:第二次输入密码比较 说 明:对第一次输入的密码与第二次输入的密码进行比较 入口参数:无 返 回 值:无 */void Newpassword_comparison(void) uchar Number=0; while(T_PasswordNumber=N_PasswordNumber)&(Number<6)/ 密码比较 Number+; / 计数值加1 if(Number>=6) / 密码正确 Newpassword_OK(); / 新密码设置成功提示 WriteToROM(T_Password,0,6); / 密码设置成功,则把密码存入24c02中sign =1; / 比较新密码标志WriteCurrent(uchar)sign,10); / 存入标志位 Delay400Ms(); Beep(); / 正确提示音 Delay400Ms(); Beep(); mark=0; else / 密码错误,报警 Newpassword_ERROR(); / 新密码设置失败提示 num=0; sign =0; / 比较旧密码标志 Delay400Ms(); Beep();Beep();Beep(); / 错误提示音 Delay400Ms(); Beep();Beep();Beep(); Delay1s(); / 延时1s mark=0; /* 函 数 名:void NewPassword_set_again(void) 功 能:第二次输入密码 说 明:第二次输入密码并存入暂存器,再调用比较程序 入口参数:无 返 回 值:无 *