【精选】基于AS608与STC89C52的指纹密码锁 您所在的位置:网站首页 怎么破解考勤机的管理员指纹密码 【精选】基于AS608与STC89C52的指纹密码锁

【精选】基于AS608与STC89C52的指纹密码锁

2024-07-13 08:46| 来源: 网络整理| 查看: 265

AS608与STC89C52指纹密码锁 原理图与PCB图AS608模块的介绍录入图像生成特征对比两个指纹搜索指纹合成模板 24C02的代码12864的代码按键扫描仔细讲解一下录指纹附上实物图串口通讯失败的原因

原理图与PCB图

首先先附上原理图,如下图所示。为了方便制版,于是画了原理图进行PCB打板。 在这里插入图片描述 PCB的三维图如下图所示。看起来还是很不错的。由于指纹模块AS608的供电电压是3.3v,大家可以买AMS1117模块进行降压。我没有试过AS608接5V。大家可以试一下,如果可以用那还省事一点。 在这里插入图片描述

AS608模块的介绍 录入图像

首先肯定是要录入指纹的,录入指纹的指令与详解如下所示,我就不一 一赘述了。我直接讲解我写这个代码的思路叭。首先可以肯定的是串口初始化,串口初始化完成之后,我们可以将包头、芯片地址之类的生成一个不可改变的数组,通过调用数组去发送,会让代码看起来更容易理解一点。 在这里插入图片描述

生成特征

在这里插入图片描述

对比两个指纹

我的程序里并没有用到,所以导致录入指纹的时候会出现同一个手指录了两个不同指纹。我想应该是没有比对的原因。 在这里插入图片描述

搜索指纹

搜索指纹,由于AS608有内部flash,所以可以存好多枚指纹,于是大家在扫描指纹开锁的时候,可以采用搜索指纹的方式,看看是否内部存有指纹进行开锁。 在这里插入图片描述

合成模板

将录入的指纹合成特征模板 在这里插入图片描述 大概关键的指令就这些。

24C02的代码

另外在附录一下24C02的代码,大家可以借鉴学习一下。

/************************************************* D罗电子设计qq:1679960378 qq:672939453 ***************************************************/ #include #include #include "24C02.h" //#include"mytype.h" #include void nop() { _nop_(); _nop_(); } /24C02读写驱动程序 void delay1(unsigned int m) { unsigned int n; for(n=0;n sda=1; nop(); scl=1; nop(); sda=0; nop(); scl=0; nop(); } void stop() //停止I2C总线 { sda=0; nop(); scl=1; nop(); sda=1; nop(); } void writebyte(unsigned char j) //写一个字节 { unsigned char i,temp; temp=j; for (i=0;i unsigned char i,j,k=0; scl=0; nop(); sda=1; for (i=0;i unsigned char i=0; scl=1; nop(); while((sda==1)&&(i start(); writebyte(0xa0); clock(); writebyte(address); clock(); writebyte(info); clock(); stop(); delay1(5000); //这个延时一定要足够长,否则会出错。因为24c02在从sda上取得数据后,还需要一定时间的烧录过程。 } 12864的代码 /************************************************* D罗电子设计 ***************************************************/ #include #include #include"12864.h" /************************************************************** 这里采用串行方式控制,因为不要接数据传输的脚,为了省实物焊接过程。 **************************************************************/ unsigned char code AC_TABLE[]={ //坐标编码 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, }; /**************************************************************** 发送一个字节 *****************************************************************/ void SendByte(unsigned char Dbyte) { unsigned char i; for(i=0;i unsigned char i,temp1,temp2; temp1=temp2=0; for(i=0;i temp2=temp2 CS = 1; CheckBusy(); SendByte(0xf8); SendByte(0xf0&Cbyte); SendByte(0xf0&Cbyte WriteCommand(0x30); WriteCommand(0x03); WriteCommand(0x0c); WriteCommand(0x01); WriteCommand(0x06); } /******************************************************************************************************* 设定光标函数 ********************************************************************************************************/ void Location_xy_12864(unsigned char x,unsigned char y) { switch(x) { case 0: x=0x80;break; case 1: x=0x90;break; case 2: x=0x88;break; case 3: x=0x98;break; default: x=0x80; } y=y&0x07; WriteCommand(0x30); WriteCommand(y+x); WriteCommand(y+x); } /*********************************************************************************** 清除文本 ************************************************************************************/ void LcmClearTXT( void ) { unsigned char i; WriteCommand(0x30); WriteCommand(0x80); for(i=0;i if(col==8) { col=0; row++; } if(row==4) row=0; WriteCommand(AC_TABLE[8*row+col]); WriteData(*puts); puts++; if(*puts != '\0') { WriteData(*puts); puts++; col++; } } } 按键扫描 unsigned char Keycan(void) { unsigned char row,col,i; P1=0xf0; if((P1&0xf0)!=0xf0) { delay(50); delay(50); if((P1&0xf0)!=0xf0) { row=P1^0xf0; //确定行线 i=0; P1=a[i]; //精确定位 while(i col=~(P1&0xff); //确定列线 break; //已定位后提前退出 } else { i++; P1=a[i]; } } } else { return 0; } while((P1&0xf0)!=0xf0); return (row|col); //行线与列线组合后返回 } else return 0; //无键按下时返回0 } void KeyDeal(unsigned char Key) { //unsigned char n; if(Key!=0) { switch(Key) { case 0x11: K=1; break; case 0x21: K=2; break; case 0x41: K=3; break; case 0x81: break; case 0x12: K=4; break; case 0x22: K=5; break; case 0x42: K=6; break; case 0x82: break; case 0x14: K=7; break; case 0x24: K=8; break; case 0x44: K=9; break; case 0x84: break; case 0x18: break; case 0x28: K=0; break; case 0x48: K=11; break; case 0x88: K=34;break; default: break; } } } 仔细讲解一下录指纹

附上代码。

//不可改变与可以改变的数组如下所示 unsigned char code a[]={0xFE,0xFD,0xFB,0xF7}; //按键扫描数组 unsigned char code FPM10A_Pack_Head[6] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF}; //协议包头 unsigned char code FPM10A_Get_Img[6] = {0x01,0x00,0x03,0x01,0x00,0x05}; //获得指纹图像 unsigned char code FPM10A_Img_To_Buffer1[7]={0x01,0x00,0x04,0x02,0x01,0x00,0x08}; //将图像放入到BUFFER1 PageId+0x07 unsigned char code FPM10A_Img_To_Buffer2[7]={0x01,0x00,0x04,0x02,0x02,0x00,0x09}; //将图像放入到BUFFER2 PageId+0x07 unsigned char code FPM10A_Reg_Model[6]={0x01,0x00,0x03,0x05,0x00,0x09}; //将BUFFER1跟BUFFER2合成特征模版 unsigned char code FPM10A_Search[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x03,0xE7,0x00,0xF8}; //搜索指纹搜索范围0 - 999,使用BUFFER1中的特征码搜索 //起始页+页数+校验和 unsigned char code FPM10A_Delete_All_Model[6]={0x01,0x00,0x03,0x0d,0x00,0x11};//删除指纹模块里所有的模版 volatile unsigned char FPM10A_Delete_Finger[10]={0x01,0x00,0x07,0x0c,0x00,0x00,0x00,0x01,0x00,0x15};//删除指纹模块里的模版 volatile unsigned char FPM10A_Save_Finger[9]={0x01,0x00,0x06,0x06,0x02,0x00,0x0B,0x00,0x19};//将BUFFER1中的特征码存放到指定的位置

串口初始化代码如下:

void UART_Init() { SCON= 0x50; //串口方式1 //REN=1; 允许接收 PCON=0x00; //SMOD=0 TMOD= 0x20; //定时器1定时方式2 TH1= 0xFD; //11.0592MHz 模块默认波特率为9600bps TL1= 0xFD; TR1= 1; //启动定时器 EA=1; } /*********************************************************************************************** 串口发送函数 D罗电子设计qq:1679960378 qq:672939453 ***********************************************************************************************/ void Uart_Send_Byte(unsigned char c)//UART Send a byte { SBUF = c; while(!TI); TI = 0; } unsigned char Uart_Receive_Byte()//UART Receive a byteg { unsigned char dat; while(!RI); RI = 0; dat = SBUF; return (dat); }

大家还是不要看后面的注释哈,有的是最开始就注释了的,但是后面改了忘了修改注释。 在添加指纹代码之前,现将各种包头、与接收的数据写成函数

void FPM10A_Cmd_Send_Pack_Head(void) { int i; for(i=0;i unsigned char i; for (i=0;i Uart_Send_Byte(FPM10A_Get_Img[i]); } } //将图像转换成特征码存放在Buffer1中 void FINGERPRINT_Cmd_Img_To_Buffer1(void) { unsigned char i; FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头 for(i=0;i unsigned char i; for(i=0;i Uart_Send_Byte(FPM10A_Img_To_Buffer2[i]); } } //合成特征模板 void FPM10A_Cmd_Reg_Model(void) { unsigned char i; FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头 for(i=0;i unsigned long temp = 0; unsigned char i; FPM10A_Save_Finger[5] =(storeID&0xFF00)>>8; FPM10A_Save_Finger[6] = (storeID&0x00FF); for(i=0;i uchar IDa1,IDa2,IDa3; LcmClearTXT(); PutStr(1,2,"请按手指"); delayms(2000); FPM10A_Cmd_Get_Img(); //获得指纹图像 FPM10A_Receive_Data(12); while(FPM10A_RECEICE_BUFFER[9]!=0) { FPM10A_Cmd_Get_Img(); //获得指纹图像 FPM10A_Receive_Data(12); } if(FPM10A_RECEICE_BUFFER[9]==0) { FINGERPRINT_Cmd_Img_To_Buffer1(); FPM10A_Receive_Data(12); FPM10A_Cmd_Search_Finger(); FPM10A_Receive_Data(16); if(FPM10A_RECEICE_BUFFER[9] == 0) //搜索是否已经存储 { PageID = FPM10A_RECEICE_BUFFER[10]*256 + FPM10A_RECEICE_BUFFER[11]; IDa1=PageID/100; IDa2=PageID/10%10; IDa3=PageID%10; LcmClearTXT(); PutStr(0,1,"该指纹已存储"); PutStr(1,1,"编号为:"); WriteCommand(0x8D); WriteData(0x30+IDa1); WriteData(0x30+IDa2); WriteData(0x30+IDa3); PutStr(3,0," 按任意键继续"); while(Keycan()==0); } if(FPM10A_RECEICE_BUFFER[9] == 9) { LcmClearTXT(); PutStr(1,1,"请再次按指纹"); FPM10A_Cmd_Get_Img(); //获得指纹图像 FPM10A_Receive_Data(12); if(FPM10A_RECEICE_BUFFER[9] == 0) { FINGERPRINT_Cmd_Img_To_Buffer2(); FPM10A_Receive_Data(12); FPM10A_Cmd_Reg_Model(); FPM10A_Receive_Data(12); IDa1=PageID/100; IDa2=PageID/10%10; IDa3=PageID%10; LcmClearTXT(); PutStr(1,1,"指纹采集成功"); PutStr(2,1,"编号为:"); WriteCommand(0x8D); WriteData(0x30+IDa1); WriteData(0x30+IDa2); WriteData(0x30+IDa3); delay(1000); write24c02(116,PageID+1); FPM10A_Cmd_Save_Finger(PageID++); FPM10A_Receive_Data(12); } } PutStr(3,0," 按任意键继续"); while(Keycan()==0); } LcmClearTXT(); }

由于篇幅关系,只介绍录入指纹的代码,但是其余代码都大同小异,只要弄清楚指令就可以了。 另外将剩下的的代码都附录如下,以便大家学习借鉴。

/*********************************************************************************************** 管理员与开锁合集 D罗电子设计——邓工 ***********************************************************************************************/ void shuazhiwen() { LcmClearTXT(); PutStr(1,1,"请按手指开锁"); FPM10A_Find_Fingerprint(); } void gaimima() //修改用户密码 { uchar i,j=0,mima1[6],mima2[6]; uchar k,temp; LcmClearTXT(); PutStr(1,1,"请输入新密码"); for(i=0;i Key=Keycan(); KeyDeal(Key); delay(30); if(Key==0) { K=10; } if((K>=0)&&(K WriteCommand(0x89+j); //指定第三行显示位置 //WriteData(0x0f); WriteData(K+0x30); } ++j; if(j==7) j=6; } //显示LCD12864并行显示 if(K==34) //按了删除键 { if(j==0) { WriteCommand(0x89); //指定第三行显示位置 WriteData(0x20); } else { --j; WriteCommand(0x89+j); //指定第三行显示位置 WriteData(0x20); } } } LcmClearTXT(); j=0; PutStr(1,0,"请再次输入新密码"); for(i=0;i Key=Keycan(); KeyDeal(Key); delay(30); if(Key==0) { K=10; } if((K>=0)&&(K WriteCommand(0x89+j); //指定第三行显示位置 //WriteData(0x0f); WriteData(K+0x30); } ++j; if(j==7) j=6; } //显示LCD12864并行显示 if(K==34) //按了删除键 { if(j==0) { WriteCommand(0x89); //指定第三行显示位置 WriteData(0x20); } else { --j; WriteCommand(0x89+j); //指定第三行显示位置 WriteData(0x20); } } } LcmClearTXT(); if((mima1[0]==mima2[0])&&(mima1[1]==mima2[1])&&(mima1[2]==mima2[2])&&(mima1[3]==mima2[3])&&(mima1[4]==mima2[4])&&(mima1[5]==mima2[5])) { for(i=0;i write24c02(temp,UserPassword[k]); delayms(10); temp++; } // PutStr(0,1,"密码修改成功"); PutStr(3,0," 按任意键继续"); Member=0; //方便下次修改密码 while(Keycan()==0); } else { PutStr(0,0," 密码修改失败 "); PutStr(1,0,"两次输入的密码不"); PutStr(2,0,"一致,请重新操作"); PutStr(3,0," 按任意键继续"); while(Keycan()==0); } LcmClearTXT(); } void zhu() { LcmClearTXT(); PutStr(1,2,"门已打开"); jidianqi=0; delay(2500); jidianqi=1; PutStr(3,0," 按任意键继续"); while(Keycan()==0); } void guanliyuan() //管理员 { uchar i,j=0,x=1;uchar Right_flag; LcmClearTXT(); PutStr(1,1,"请输入密码:"); for(i=0;i Key=Keycan(); KeyDeal(Key); delay(30); if(Key==0) { K=10; } if((K>=0)&&(K WriteCommand(0x89+j); //指定第三行显示位置 WriteData(0x0f); } ++j; if(j==7) { j=6; } } //显示LCD12864并行显示 if(K==34) //按了删除键 { if(j==0) { WriteCommand(0x89); //指定第三行显示位置 WriteData(0x20); } else { --j; WriteCommand(0x89+j); //指定第三行显示位置 WriteData(0x20); } } } LcmClearTXT(); for(i=0;i Right_flag=PassWord_Chack(); } if (Right_flag==1) { Right_flag=0; Key=Keycan(); while(Key!=tuichu) { PutStr(0,0,"按键1 : 增加指纹"); PutStr(1,0,"按键2 : 删去指纹"); PutStr(2,0,"按键3 : 清空所有"); PutStr(3,0,"按键4 : 修改密码"); Key=Keycan(); KeyDeal(Key); switch(K) { case 1: FPM10A_Add_Fingerprint(); K=8; //仅录一次,如果不设置K=8(可以比4大就行),会一直录指纹 break; case 2: FPM10A_Delete_Fingerprint(); break; case 3: FPM10A_Delete_All_Fingerprint(); break; case 4: gaimima(); break; default: break; } } } else { alarm=0; PutStr(1,2,"密码错误"); PutStr(2,0," 请重新操作!"); PutStr(3,0," 按任意键继续"); delay(2500); alarm=1; while(Keycan()==0); } Key=0; LcmClearTXT(); } //功能介绍 void MEMU() { PutStr(0,2,"欢迎使用"); PutStr(1,1,"D罗电子设计"); PutStr(2,1,"qq1679960378"); PutStr(3,1,"qq:672939453"); Key=Keycan(); if(k2==1) //指纹刷机 { LcmClearTXT(); shuazhiwen(); LcmClearTXT(); } if(Key==0x81) //管理员操作 { LcmClearTXT(); guanliyuan(); LcmClearTXT(); } } void main() { UART_Init(); //串口初始化 x24c02_init(); //24C02初始化 LcmInit(); //LCD12864初始化 LcmClearTXT(); //LCD12864清屏 // write24c02(110,0x30); // write24c02(111,0x30);//24c02的第110到115地址单元作为密码存储区 // write24c02(112,0x30); // write24c02(113,0x30); // write24c02(114,0x30); // write24c02(115,0x30); // write24c02(116,0); PageID=read24c02(116); while(1) { MEMU(); delay(100); } } 附上实物图

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 图中所示的3.2是5v降压到3.3的显示屏,大家降压可以前文提到的AMS1117模块。

串口通讯失败的原因

1、串口初始化有问题,如果想知道初始化是否正确,用USB TO TTL串口下载器进行调试一下,如果不对,大家再多查一下串口的资料。 2、另外,最后最重要的是,AS608模块是有波特率的,一开始你不可能一下就能把波特率设置对。你可以自己用单片机串口初始化设置波特率。运用指纹上位机调试指纹模块波特率,与单片机一致就可以了。

指纹上位机去我的资源里下载,免费哈。 指纹模块波特率设置就是与下载器普通的连接就行了。RXD----TXD,TXD-----RXD。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有