《51电子密码锁》由会员分享,可在线阅读,更多相关《51电子密码锁(7页珍藏版)》请在金锄头文库上搜索。
1、#include #include #include #define uchar unsigned char #define uint unsigned int #define COM XBYTE 0x7fff/8279 命令状态地址 #define DAT XBYTE 0x77fF/8279 数据地址 uchar code table= 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,/0,1,2,3,4,5,6,7 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71/8,9,A,B,C,D,E,F ;/共阳极数码管显示段码 uch
2、ar idata diss8;/显示用数据暂存器8 位数据 uchar idata mima6;/密码用数据暂存器6 位数据 sbit clflag=ACC7;/记录状态字 最高位 sbit SDA=P11;/24c02 数据端 sbit SCL=P10;/24c02 时钟端 sbit error=P12;/闭锁指示端 sbit right=P13;/开锁指示端 和开锁输出 uchar keyin();/8279 读键号子程序 uchar deky();/8279 监测有无按键按下子程序 void disp(uchar idata *d);/8279 显示子程序 void start_bit(
3、void);/2402 开始位 void stop_bit(void);/2402 停止位 void mast_ack(void);/2402 主答函数 bit write_8bit(uchar ch);/2402 写一个字节(8 位)数据 uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad); /2402 页面写函数 uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad); /页面读函数 void mimakey(void);/密码锁设置密码 输入密码子程序 ma
4、in()/主函数 uchar i; COM=0xd1;/11010001总清除命令 doACC=COM;/读状态字 直到清除完成 while(clflag=1);/读状态字 最高位 COM=0x00;/键盘/显示器工作方式 左端送入 88 显示双键锁定 编码扫描 COM=0x34;/时钟分频20 分频 right=0;error=1;/默认闭锁 /*以下测试用*/ for(i=0;i=0x0a); /不是取消键且输入键号不是 09 的数字键时 等待 1 位数字键输入 mimai=key;/密码数字存于 mima 暂存器中 dissi=15;/每输入一位密码数码管显示“F” disp(diss)
5、;/送显示 if(key!=0x0d)/6 位密码输入完成时看是否要确认;未完成 6 位输入 时返回 key=keyin();/等待按键输入 if (key=0x0d);/是取消键时 输入密码取消 else/不是取消键时 等待输入密码确认 if(key!=0x0c)while(keyin()!=0x0c);/等待确认键按下 while(page_rd(0,6,/在 2402 中读取密码 keyok=1;/把解锁标志位设为 1 解锁 for(i=0;i=0x0a); /不是取消键且输入键号不是 09 的数字键时 等 待 1 位数字键输入 mimai=key;/密码数字存于 mima 暂存器中 d
6、issi=14;/每输入一位密码数码管显示“E” disp(diss);/送显示 if(key!=0x0d)/6 位密码输入完成时看是否要确认;未完成 6 位 输入时返回 key=keyin();/读一位键 if (key=0x0d);/是取消键时 设置密码取消 else/不是取消键时 等待设置密码确认 if(key!=0x0c)while(keyin()!=0x0c);/等待确认键按下 while(page_wr(0,6,/密码写入 24lc02 /*以上为设置密码状态*/ void disp(uchar idata *d)/显示子程序 uchar j; COM=0x90;/写显示 RAM
7、自动加 1 for(j=0;j=0x0e);/只读取 09 和 AD 键 不读取 E 和 F 键 return(j);/返回键号 uchar deky(void)/监测有无按键按下 uchar k; k=COM;/读状态 return(k/只监测 2 行按键 有键返回 1 无键返回 0 /*- 调用方式:void start_bit(void) 函数说明:2402 开始位 在时钟端 SCL 为高电平时,数据端 SDA 发生由高到低的变化,为起始条件 启动 I2C 总线 -*/ void start_bit(void) SCL=1;/_nop_(); SDA=1;/_nop_(); SDA=0;
8、/_nop_(); SCL=0;/_nop_(); /*- 调用方式:void stop_bit(void) 函数说明:2402 停止位 在时钟端 SCL 为高电平时,数据端 SDA 发生由低到高的变化,为停止条件 停止 I2C 总线数据传输 -*/ void stop_bit(void) SDA=0;/_nop_(); SCL=1;/_nop_(); SDA=1;/_nop_(); /*- 调用方式:void mast_ack(void) 函数说明:2402 主答函数 主器件在收发每一个字节后产生一个时钟应答脉冲, 在这期间,发送器必须保证 SDA 为高,由接收器 SDA 拉低, 称为应答信
9、号(ACK) 。 -*/ void mast_ack(void) SCL=0;_nop_(); SDA=0;_nop_(); SCL=1;_nop_(); SCL=0;_nop_(); SDA=1;_nop_(); /*- 调用方式:write_8bit(uchar ch) 函数说明:2402 写一个字节(8 位)数据 -*/ bit write_8bit(uchar ch) uchar i=8; bit fan_w; SCL=0;_nop_(); while(i-) SDA=(bit)(ch /取字节的最高位 _nop_(); ch=1;/字节左移一位 SCL=1;_nop_();/上升沿锁
10、存数据 SCL=0;_nop_(); SDA=1;_nop_(); SCL=1;_nop_(); fan_w=SDA;/读应答信号 SCL=0;_nop_(); return(fan_w);/返回应答信号 /*- 调用方式:void page_wr(uint firstw_ad,uint counter,uint data *firstr_ad) 函数说明:2402 页面写函数,firstw_ad 为写入字节单元的首地址, *firstr-ad 为被写入数据所在首地址指针 counter 为写入数据字节数 -*/ uchar page_wr(uint firstw_ad,uint counte
11、r,uchar *firstr_ad) uchar data *ufirstr_ad; ufirstr_ad=firstr_ad; start_bit();/写开始位 if(write_8bit(0xA0)!=0)stop_bit();return(0);/写命令 if(write_8bit(firstw_ad)!=0)stop_bit();return(0);/写首地址 while(counter-)/写字节数减 1 if(write_8bit(*ufirstr_ad)!=0)stop_bit();return(0);/写 1 字节 ufirstr_ad+;/地址加 1 stop_bit()
12、;/写停止位 return(1); /*- 调用方式:void page_rd(uint firstrd_ad,uint count,uint firstwr_ad) 函数说明:2402 页面读函数,firstrd-ad 为所读字节首地址,count 为读字节数 *ufirstwr-ad 为读出数据存储首地址指针 -*/ uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad) uchar j=8; uchar data *ufirstwr_ad; ufirstwr_ad=firstwr_ad; start_bit();/写开始位
13、if(write_8bit(0xA0)!=0)stop_bit();return(0);/写命令 if(write_8bit(firstrd_ad)!=0)stop_bit();return(0);/写首地址 start_bit();/写开始位 if(write_8bit(0xA1)!=0)stop_bit();return(0);/读命令 while(count-)/读字节数减 1 uchar i=8; while(i-) (*ufirstwr_ad)=1;/读对应地址的数据左移 SCL=1;_nop_();/上升沿 if(SDA) (*ufirstwr_ad)|=0x01;/数据端为 1 时 存 1 SCL=0; _nop_(); ufirstwr_ad+;/地址加 1 mast_ack();/应答信号 while(j-) (*ufirstwr_ad)=1; SCL=0;_nop_();_nop_();SCL=1; if(SDA) (*ufirstwr_ad)|=0x01; stop_bit();/写停止位 return(1);