找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 27076|回复: 62
收起左侧

单片机+电磁锁+AS608指纹锁设计源码与实物图分享 LCD12864显示

  [复制链接]
ID:247778 发表于 2018-11-25 21:00 | 显示全部楼层 |阅读模式
输入模块:AS608,矩阵键盘
处理器:STC90C52
输出设备:LCD12864,电磁锁,继电器

总流程:当AS608探测到有手指接触时,判断是否符合已储存的指纹数据,符合输出电平开锁,否则12864显示错误。或者当输入数字密码相符合也可开锁,内部存有开锁密码,和管理员密码(设置指纹库和开门密码),密码和指纹ID号存储在EEPROM中防止掉电丢失。

制作出来的实物图如下:

背面

背面

正面

正面

52单片机最小系统

52单片机最小系统

电磁锁

电磁锁

LCD12864

LCD12864

AS608

AS608

矩阵键盘

矩阵键盘


单片机程序源码:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include <string.h>
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define jzaj P1
  7. uchar x,Administrators,out=0,k=0,h,b,reset1=0;
  8. uchar password[6]={1,2,3,4,5,6};
  9. uchar password1[6];
  10. uchar password2[6]={1,2,3,4,5,6};
  11. uchar adminpassword[6]={6,6,6,6,6,6};
  12. uchar adminpassword1[6];
  13. uchar adminpassword2[6]={6,6,6,6,6,6};
  14. sbit kai=P0^5;
  15. sbit kai1=P0^6;
  16. sbit kai2=P0^7;
  17. uchar code  DIS1[] = {"    欢迎使用   "};                  //一个汉字占用两个字符空间,故汉字只能占用偶数地址
  18. uchar code  DIS2[] = {"  云部落指纹锁 "};
  19. uchar code  DIS3[] = {"    密码吻合   "};
  20. uchar code  DIS14[] = {"    密码错误   "};
  21. uchar code  DIS4[] = {"已识别  ID:   "};
  22. uchar code  DIS5[] = {"  没有找到     "};
  23. uchar code  DIS6[] = {"请输入管理员密码"};
  24. uchar code  DIS7[] = {"1.添加指纹     "};
  25. uchar code  DIS8[] = {"2.清空指纹     "};
  26. uchar code  DIS9[] = {"3.开锁密码     "};
  27. uchar code  DIS10[] = {"4.管理密码     "};
  28. uchar code  DIS11[] = {"  请输入指纹   "};
  29. uchar code  DIS12[] = {"  请再次输入指纹"};
  30. uchar code  DIS13[] = {"添加成功ID:   "};
  31. uchar code  DIS15[] = {"  清空成功     "};
  32. uchar code  DIS16[] = {"  清空失败     "};
  33. uchar code  DIS17[] = {"  确认清空?   "};
  34. uchar code  DIS18[] = {"  请输入新密码 "};
  35. uchar code  DIS19[] = {"  确认修改?   "};
  36. uchar code  DIS20[] = {"  修改成功     "};
  37. uchar code  DIS21[] = {"  复位成功     "};
  38. /************* 12864LCD引脚定义 *************/
  39. #define LCD_data  P2       //数据口
  40. sbit LCD_RS  =  P0^0;      //寄存器选择输入
  41. sbit LCD_RW  =  P0^1;      //液晶读/写控制
  42. sbit LCD_EN  =  P0^2;      //液晶使能控制
  43. sbit LCD_PSB =  P0^3;      //串/并方式控制
  44. sbit LCD_RST =  P0^4;      //液晶复位端口
  45. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
  46. void delay(int ms)
  47. {
  48.     while(ms--)
  49.         {
  50.       uchar i;
  51.           for(i=0;i<150;i++)  
  52.            {
  53.             _nop_();                           
  54.                 _nop_();
  55.                 _nop_();
  56.                 _nop_();
  57.            }
  58.         }
  59. }
  60. /*******************************************************************/
  61. /*                                                                 */
  62. /*检查LCD忙状态                                                    */
  63. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */
  64. /*                                                                 */
  65. /*******************************************************************/
  66. bit lcd_busy()
  67. {                          
  68.     bit result;
  69.     LCD_RS = 0;
  70.     LCD_RW = 1;
  71.     LCD_EN = 1;
  72.     delayNOP();
  73.     result = (bit)(LCD_data&0x80);
  74.     LCD_EN = 0;
  75.     return(result);
  76. }
  77. /*******************************************************************/
  78. /*                                                                 */
  79. /*写指令数据到LCD                                                  */
  80. /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */
  81. /*                                                                 */
  82. /*******************************************************************/
  83. void lcd_wcmd(uchar cmd)
  84. {                          
  85.    while(lcd_busy());
  86.     LCD_RS = 0;
  87.     LCD_RW = 0;
  88.     LCD_EN = 0;
  89.     _nop_();
  90.     _nop_();
  91.     LCD_data = cmd;
  92.     delayNOP();
  93.     LCD_EN = 1;
  94.     delayNOP();
  95.     LCD_EN = 0;  
  96. }
  97. /*******************************************************************/
  98. /*                                                                 */
  99. /*写显示数据到LCD                                                  */
  100. /*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */
  101. /*                                                                 */
  102. /*******************************************************************/
  103. void lcd_wdat(uchar dat)
  104. {                          
  105.    while(lcd_busy());
  106.     LCD_RS = 1;
  107.     LCD_RW = 0;
  108.     LCD_EN = 0;
  109.     LCD_data = dat;
  110.     delayNOP();
  111.     LCD_EN = 1;
  112.     delayNOP();
  113.     LCD_EN = 0;
  114. }
  115. /*******************************************************************/
  116. /*                                                                 */
  117. /*  LCD初始化设定                                                  */
  118. /*                                                                 */
  119. /*******************************************************************/
  120. void lcd_init()
  121. {
  122.     LCD_PSB = 1;         //并口方式
  123.    
  124.         LCD_RST = 0;                 //液晶复位
  125.     delay(3);                  
  126.     LCD_RST = 1;      
  127.     delay(3);
  128.    
  129.     lcd_wcmd(0x34);      //扩充指令操作
  130.     delay(5);
  131.     lcd_wcmd(0x30);      //基本指令操作
  132.     delay(5);
  133.     lcd_wcmd(0x0C);      //显示开,关光标
  134.     delay(5);
  135.     lcd_wcmd(0x01);      //清除LCD的显示内容
  136.     delay(5);
  137. }
  138. /*********************************************************/
  139. /*                                                       */
  140. /* 设定显示位置                                          */
  141. /*                                                       */
  142. /*********************************************************/
  143. void lcd_pos(uchar X,uchar Y)
  144. {                          
  145.    uchar  pos;
  146.    if (X==1)
  147.      {X=0x80;}
  148.    else if (X==2)
  149.      {X=0x90;}
  150.    else if (X==3)
  151.      {X=0x88;}
  152.    else if (X==4)
  153.      {X=0x98;}
  154.    pos = X+Y ;

  155.    lcd_wcmd(pos);     //显示地址
  156. }
  157. /*********************************************************
  158. *                                                        *
  159. * 清屏函数                                               *
  160. *                                                        *
  161. *********************************************************/
  162. void  clr_screen()
  163. {
  164.    lcd_wcmd(0x34);      //扩充指令操作
  165.    delay(5);   
  166.    lcd_wcmd(0x30);      //基本指令操作
  167.    delay(5);
  168.    lcd_wcmd(0x01);      //清屏
  169.    delay(5);     
  170. }
  171. //////////////////////////////////////////////////////////////////////////
  172. void kaisuo();
  173. //////////////////////////////////////////////////////////////////////////
  174. sfr ISP_DATA = 0xe2;
  175. sfr ISP_ADDRH = 0xe3;
  176. sfr ISP_ADDRL = 0xe4;
  177. sfr ISP_CMD = 0xe5;
  178. sfr ISP_TRIG = 0xe6;
  179. sfr ISP_CONTR = 0xe7;
  180. void  cc(uint addr);
  181. void  xcx(uint addr,uchar dat);
  182. uchar dcx(uint addr);
  183. void  Q0();
  184. /* ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  185. 函数:擦除某一扇区(每个扇区 512 字节)
  186. 入口: addr = 某一扇区首地址
  187. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ */
  188. void cc(uint addr)
  189. {
  190. // 打开 IAP 功能 (ISP_CONTR.7)=1: 允许编程改变 Flash, 设置 Flash 操作等待时间
  191. // 0x83( 晶振 <5M)  0x82(晶振 <10M)  0x81(晶振 <20M)  0x80(晶振 <40M)
  192.   ISP_CONTR = 0x81;
  193.   ISP_CMD  = 0x03;  // 用户可以对 "Data Flash/EEPROM区"进行扇区擦除
  194.   ISP_ADDRL = addr;  // ISP/IAP 操作时的地址寄存器低八位,
  195.   ISP_ADDRH = addr>>8;  // ISP/IAP 操作时的地址寄存器高八位。
  196.   EA =0;
  197.   ISP_TRIG = 0x46;  // 在 ISPEN(ISP_CONTR.7)=1 时,对 ISP_TRIG先写入 46h,
  198.   ISP_TRIG = 0xB9;  // 再写入 B9h,ISP/IAP命令才会生效。
  199.   _nop_();
  200.   Q0();  // 关闭 ISP/IAP
  201. }
  202. /* ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  203. 函数:写一字节
  204. 入口: addr = 扇区单元地址 , dat = 待写入数据
  205. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ */
  206. void xcx(uint addr,uchar dat)
  207. {
  208.   ISP_CONTR = 0x81;
  209.   ISP_CMD  = 0x02;  // 用户可以对 "Data Flash/EEPROM区"进行字节编程
  210.   ISP_ADDRL = addr;
  211.   ISP_ADDRH = addr>>8;
  212.   ISP_DATA = dat;  // 数据进 ISP_DATA
  213.   EA = 0;
  214.   ISP_TRIG = 0x46;
  215.   ISP_TRIG = 0xB9;
  216.   _nop_();
  217.   Q0();  // 关闭 ISP/IAP
  218. }
  219. /* ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  220. 函数:读一字节
  221. 入口: addr = 扇区单元地址
  222. 出口: dat  = 读出的数据
  223. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ */
  224. uchar dcx(uint addr)
  225. {
  226.   uchar dat;
  227.   ISP_CONTR = 0x81;
  228.   ISP_CMD  = 0x01;  // 用户可以对 "Data Flash/EEPROM区 "进行字节读
  229.   ISP_ADDRL = addr;
  230.   ISP_ADDRH = addr>>8;
  231.   EA = 0;
  232.   ISP_TRIG = 0x46;
  233.   ISP_TRIG = 0xB9;
  234.   _nop_();
  235.   dat = ISP_DATA;  // 取出数据
  236.   Q0();  // 关闭 ISP/IAP
  237.   return dat;
  238. }
  239. /* ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  240. 函数:关闭 ISP/IAP操作
  241. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ */
  242. void Q0()
  243. {
  244.   ISP_CONTR = 0;  // 关闭 IAP功能
  245.   ISP_CMD  = 0;  // 待机模式,无 ISP操作
  246.   ISP_TRIG = 0;  // 关闭 IAP功能 , 清与 ISP有关的特殊功能寄存器
  247. }
  248. void wolegequ()
  249. {
  250.   uchar i;
  251.   cc(0x2200); // 擦除第 2 个扇区
  252.   for(i=0;i<6;i++)
  253.   {
  254.     xcx(0x2200+i,password2[i]);  // 对 EEPROM区 2200h 写入
  255.   }
  256.   cc(0x2400); // 擦除第 2 个扇区
  257.   for(i=0;i<6;i++)
  258.   {
  259.     xcx(0x2400+i,adminpassword2[i]);  // 对 EEPROM区 2200h 写入
  260.   }
  261.   EA=1;
  262. }
  263. //////////////////////////////////////////////////////////////////////////
  264. volatile unsigned char FPM10A_RECEICE_BUFFER[32];
  265. unsigned int finger_id=0 ;

  266. code unsigned char FPM10A_Pack_Head[6] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF};  //协议包头
  267. code unsigned char FPM10A_Get_Img[6] = {0x01,0x00,0x03,0x01,0x00,0x05};    //获得指纹图像
  268. code unsigned char FPM10A_Img_To_Buffer1[7]={0x01,0x00,0x04,0x02,0x01,0x00,0x08}; //将图像放入到BUFFER1
  269. code unsigned char FPM10A_Img_To_Buffer2[7]={0x01,0x00,0x04,0x02,0x02,0x00,0x09}; //将图像放入到BUFFER2
  270. code unsigned char FPM10A_Reg_Model[6]={0x01,0x00,0x03,0x05,0x00,0x09}; //将BUFFER1跟BUFFER2合成特征模版
  271. code unsigned char FPM10A_Search[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x03,0xE7,0x00,0xF8}; //搜索指纹搜索范围0 - 999,使用BUFFER1中的特征码搜索
  272. code unsigned char FPM10A_Delete_All_Model[6]={0x01,0x00,0x03,0x0d,0x00,0x11};//删除指纹模块里所有的模版
  273. volatile unsigned char  FPM10A_Save_Finger[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0B,0x00,0x19};//将BUFFER1中的特征码存放到指定的位置

  274. //发送包头

  275. void Uart_Init(void)
  276. {
  277.     SCON=0x50;   //UART方式1:8位UART;   REN=1:允许接收
  278.     PCON=0x00;   //SMOD=0:波特率不加倍
  279.     TMOD=0x20;   //T1方式2,用于UART波特率
  280.     TH1=0xFD;
  281.     TL1=0xFD;   //UART波特率设置:FDFD,9600;FFFF,57600
  282.     TR1=1;         //允许T1计数
  283.     EA=1;
  284. }


  285. void Uart_Send_Byte(unsigned char c)//UART Send a byte
  286. {
  287.         SBUF = c;
  288.         while(!TI);                //发送完为1
  289.         TI = 0;
  290. }

  291. unsigned char Uart_Receive_Byte()//UART Receive a byteg
  292. {        
  293.         unsigned char dat;
  294.         while(!RI);         //接收完为1
  295.         RI = 0;
  296.         dat = SBUF;
  297.         return (dat);
  298. }

  299. void FPM10A_Cmd_Send_Pack_Head(void)
  300. {
  301.         int i;        
  302.         for(i=0;i<6;i++) //包头
  303.    {
  304.      Uart_Send_Byte(FPM10A_Pack_Head[i]);   
  305.     }               
  306. }

  307. //接收反馈数据缓冲
  308. void FPM10A_Receive_Data(unsigned char ucLength)
  309. {
  310.   unsigned char i;

  311.   for (i=0;i<ucLength;i++)
  312.      FPM10A_RECEICE_BUFFER[i] = Uart_Receive_Byte();

  313. }

  314. //FINGERPRINT_获得指纹图像命令
  315. void FPM10A_Cmd_Get_Img(void)
  316. {
  317.     unsigned char i;
  318.     FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头
  319.     for(i=0;i<6;i++) //发送命令 0x1d
  320.         {
  321.        Uart_Send_Byte(FPM10A_Get_Img[i]);
  322.         }
  323. }
  324. //讲图像转换成特征码存放在Buffer1中
  325. void FINGERPRINT_Cmd_Img_To_Buffer1(void)
  326. {
  327.          unsigned char i;
  328.         FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头      
  329.            for(i=0;i<7;i++)   //发送命令 将图像转换成 特征码 存放在 CHAR_buffer1
  330.      {
  331.       Uart_Send_Byte(FPM10A_Img_To_Buffer1[i]);
  332.              }
  333. }
  334. //将图像转换成特征码存放在Buffer2中
  335. void FINGERPRINT_Cmd_Img_To_Buffer2(void)
  336. {
  337.      unsigned char i;
  338.      for(i=0;i<6;i++)    //发送包头
  339.          {
  340.             Uart_Send_Byte(FPM10A_Pack_Head[i]);   
  341.             }
  342.      for(i=0;i<7;i++)   //发送命令 将图像转换成 特征码 存放在 CHAR_buffer1
  343.       {
  344.               Uart_Send_Byte(FPM10A_Img_To_Buffer2[i]);
  345.              }
  346. }
  347. void FPM10A_Cmd_Reg_Model(void)
  348. {
  349.        unsigned char i;           
  350.             
  351.                          FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头

  352.        for(i=0;i<6;i++)
  353.            {
  354.                   Uart_Send_Byte(FPM10A_Reg_Model[i]);   
  355.                       }


  356. }
  357. //搜索全部用户999枚
  358. void FPM10A_Cmd_Search_Finger(void)
  359. {
  360.        unsigned char i;                       
  361.                          FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头
  362.        for(i=0;i<11;i++)
  363.            {
  364.                   Uart_Send_Byte(FPM10A_Search[i]);   
  365.                       }
  366. }
  367. //保存指纹
  368. void FPM10A_Cmd_Save_Finger( unsigned int storeID )
  369. {
  370.        unsigned long temp = 0;
  371.                    unsigned char i;
  372.        FPM10A_Save_Finger[5] =(storeID&0xFF00)>>8;
  373.        FPM10A_Save_Finger[6] = (storeID&0x00FF);
  374.                    for(i=0;i<7;i++)   //计算校验和
  375.                               temp = temp + FPM10A_Save_Finger[i];
  376.                    FPM10A_Save_Finger[7]=(temp & 0x00FF00) >> 8; //存放校验数据
  377.                    FPM10A_Save_Finger[8]= temp & 0x0000FF;                  
  378.        FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头        
  379.        for(i=0;i<9;i++)  
  380.                       Uart_Send_Byte(FPM10A_Save_Finger[i]);      //发送命令 将图像转换成 特征码 存放在 CHAR_buffer1
  381. }
  382. //删除指纹模块里的所有指纹模版
  383. void FINGERPRINT_Cmd_Delete_All_Model(void)
  384. {
  385.      unsigned char i;   
  386.     for(i=0;i<6;i++) //包头
  387.       Uart_Send_Byte(FPM10A_Pack_Head[i]);   
  388.     for(i=0;i<6;i++) //命令合并指纹模版
  389.            {
  390.       Uart_Send_Byte(FPM10A_Delete_All_Model[i]);   
  391.                  }        
  392. }
  393. //搜索指纹
  394. void FPM10A_Find_Fingerprint()
  395. {
  396.   unsigned int find_fingerid = 0,i;
  397.   unsigned char id_show[3];
  398.   
  399.   
  400.   FPM10A_Cmd_Get_Img();                                         //获得指纹图像命令
  401.   FPM10A_Receive_Data(12);                                  //接收反馈数据缓冲
  402.   if(FPM10A_RECEICE_BUFFER[9]==0)                 //根据反馈回来的第9位数据来判断模块上有无指纹,有则继续执行无则退出
  403.   {
  404.     FINGERPRINT_Cmd_Img_To_Buffer1();          //讲图像转换成特征码存放在Buffer1中
  405.         FPM10A_Receive_Data(12);               
  406.         FPM10A_Cmd_Search_Finger();                                //搜索全部用户999枚
  407.         FPM10A_Receive_Data(16);
  408.         if(FPM10A_RECEICE_BUFFER[9] == 0) //搜索到  
  409.         {
  410.           clr_screen();
  411.           lcd_pos(2,0);             //设置显示“已识别”
  412.       for(i=0;i<16;i++)
  413.             {
  414.         lcd_wdat(DIS4[i]);
  415.             
  416.             }         
  417.           find_fingerid = FPM10A_RECEICE_BUFFER[10]*256 + FPM10A_RECEICE_BUFFER[11];
  418.           id_show[0]=find_fingerid/100+0x30;
  419.           id_show[1]=find_fingerid%100/10+0x30;
  420.           id_show[2]=find_fingerid%100%10+0x30;
  421.           lcd_pos(2,13);             //设置显示ID号
  422.       for(i=0;i<3;i++)
  423.             {
  424.         lcd_wdat(id_show[i]);
  425.             }
  426.           delay(1000);
  427.           kaisuo();
  428.         }
  429.         else
  430.         { clr_screen();
  431.           lcd_pos(2,0);             //设置显示“没有找到”
  432.       for(i=0;i<16;i++)
  433.             {
  434.         lcd_wdat(DIS5[i]);           
  435.             }
  436.           delay(1000);
  437.         }
  438.         clr_screen();
  439.   }
  440. }
  441. void HSjzaj();                                                         ///////////////////////////声明函数以便调用
  442. //删除所有存贮的指纹库
  443. void FPM10A_Delete_All_Fingerprint()
  444. {
  445.   char i;
  446.   clr_screen();
  447.   lcd_pos(1,0);             //
  448.   for(i=0;i<16;i++)
  449.   {
  450.     lcd_wdat(DIS17[i]);
  451.   }
  452.   delay(1000);
  453.   x=0;
  454.   HSjzaj();
  455.   if(x==1)
  456.   {
  457.     FINGERPRINT_Cmd_Delete_All_Model();
  458.     FPM10A_Receive_Data(12);
  459.     if(FPM10A_RECEICE_BUFFER[9]==0)
  460.     {
  461.       lcd_pos(2,0);             //设置显示位置为第一行
  462.             for(i=0;i<16;i++)
  463.             {
  464.                     lcd_wdat(DIS15[i]);
  465.             }
  466.           delay(1000);
  467.           finger_id=0;
  468.           cc(0x2000); // 擦除第 1 个扇区( 2000h~21FFh)
  469.       xcx(0x2002,finger_id);  // 对 EEPROM区 2002h 写入
  470.           EA=1;
  471.     }
  472.     else
  473.     {
  474.       lcd_pos(2,0);             //设置显示位置为第一行
  475.       for(i=0;i<16;i++)
  476.             {
  477.             lcd_wdat(DIS16[i]);
  478.                     
  479.            }
  480.           delay(1000);
  481.     }
  482.   }
  483.   clr_screen();
  484. }
  485. //添加指纹
  486. void FPM10A_Add_Fingerprint()
  487. {
  488.   uchar i;
  489.   volatile unsigned char id_show[3];
  490.   clr_screen();
  491.   lcd_pos(1,0);             //设置显示位置为第一行
  492.   for(i=0;i<16;i++)
  493.   {
  494.     lcd_wdat(DIS11[i]);
  495.   }
  496.   delay(2000);
  497.   FPM10A_Cmd_Get_Img(); //获得指纹图像
  498.   FPM10A_Receive_Data(12);
  499.   if(FPM10A_RECEICE_BUFFER[9]==0)
  500.   {
  501.     FINGERPRINT_Cmd_Img_To_Buffer1();
  502.         FPM10A_Receive_Data(12);
  503.     lcd_pos(2,0);             //设置显示位置为第一行
  504.     for(i=0;i<16;i++)
  505.     {
  506.       lcd_wdat(DIS12[i]);
  507.     }
  508.         delay(2000);
  509.         FPM10A_Cmd_Get_Img(); //获得指纹图像
  510.         FPM10A_Receive_Data(12);
  511.         if(FPM10A_RECEICE_BUFFER[9]==0)
  512.         {
  513.           FINGERPRINT_Cmd_Img_To_Buffer2();
  514.           FPM10A_Receive_Data(12);
  515.           FPM10A_Cmd_Reg_Model();//转换成特征码
  516.           FPM10A_Receive_Data(12);
  517.           id_show[0]=finger_id/100+0x30;                                         //加0x30,转换成字符串
  518.           id_show[1]=finger_id%100/10+0x30;
  519.           id_show[2]=finger_id%100%10+0x30;
  520.           clr_screen();
  521.           lcd_pos(1,0);             //设置显示位置为第一行
  522.       for(i=0;i<16;i++)
  523.       {
  524.               lcd_wdat(DIS13[i]);
  525.              delay(0);
  526.       }
  527.           lcd_pos(3,12);             //设置显示位置为第一行
  528.       for(i=0;i<3;i++)
  529.       {
  530.               lcd_wdat(id_show[i]);
  531.       }
  532.           delay(1000);
  533.           FPM10A_Cmd_Save_Finger(finger_id++);
  534.           cc(0x2000); // 擦除第 1 个扇区( 2000h~21FFh)
  535.       xcx(0x2002,finger_id);  // 对 EEPROM区 2002h 写入
  536.           EA=1;                                         
  537.           FPM10A_Receive_Data(12);
  538.         }

  539.   }
  540. }
  541. //确认指令
  542. void confirm()                                                         
  543. {
  544.   uchar i,p=0;
  545.   clr_screen();
  546.   for(i=0;i<6;i++)
  547.   {
  548.     if(password1[i]==password[i])
  549.         {
  550.           delay(0);
  551.         }
  552.     else
  553.         {
  554.           p=1;
  555.         }
  556.   }
  557.   if(p==0)
  558.   {
  559.     lcd_pos(2,0);            
  560.     for(i=0;i<16;i++)
  561.     {
  562.       lcd_wdat(DIS3[i]);                                   //密码正确      
  563.     }
  564.         delay(1000);
  565.         kaisuo();
  566.   }
  567.   else
  568.   {
  569.     lcd_pos(2,0);            
  570.     for(i=0;i<16;i++)
  571.     {
  572.       lcd_wdat(DIS14[i]);                                  //密码错误      
  573.     }
  574.         delay(1000);
  575.   }
  576.   for(i=0;i<6;i++)
  577.   {
  578.     password1[i]=0;                                                //将密码1寄存器置零
  579.   }
  580.   clr_screen();
  581. }

  582. //矩阵键盘
  583. void HSjzaj()
  584. {
  585.   uchar c=10;                                                                                                                        ///
  586.   jzaj=0x0f;
  587.   if(jzaj!=0x0f)
  588.   {
  589.     delay(50);
  590.         if(jzaj!=0x0f)
  591.         {
  592.           switch(jzaj)
  593.           {
  594.             case (0x07): b=0;break;
  595.                 case (0x0b): b=1;break;
  596.                 case (0x0d): b=2;break;
  597.                 case (0x0e): b=3;break;
  598.           }
  599.           jzaj=0xf0;
  600.           switch(jzaj)
  601.           {
  602.             case (0xe0): b=b+0;break;
  603.                 case (0xd0): b=b+4;break;
  604.                 case (0xb0): b=b+8;break;
  605.                 case (0x70): b=b+12;break;
  606.           }
  607.       switch(b)
  608.           {
  609.                 case (0): c=1;break;
  610.                 case (1): c=2;break;
  611.                 case (2): c=3;break;
  612.                 case (3): Administrators=1;break;
  613.                 case (4): c=4;break;
  614.                 case (5): c=5;break;
  615.                 case (6): c=6;break;
  616.                 case (7): out=1;break;
  617.                 case (8): c=7;break;
  618.                 case (9): c=8;break;
  619.                 case (10): c=9;break;
  620.                 case (11): reset1=1;break;
  621.                 case (12): c='*';break;
  622.                 case (13): c=0;break;
  623.                 case (14): c='#';break;
  624.                 case (15): x=1;break;                                                 //确认
  625.           }
  626.           if((0<=c&&c<=9)||c=='*'||c=='#')                                        //只有C为0~9或#,*方可进入
  627.           {
  628.                 if(h==0)
  629.                 {
  630.                   password1[k]=c;
  631.                 }
  632.                 else
  633.                 {
  634.                   adminpassword1[k]=c;
  635.                 }
  636.                 lcd_pos(4,k);             //云部落指纹锁
  637.         lcd_wdat('*');
  638.         delay(0);
  639.                 k++;
  640.                 if(k==7)
  641.                 {
  642.                   k=0;
  643.                   clr_screen();                         //显示6个*后清屏
  644.                 }
  645.           }
  646.         }
  647.   }
  648.   delay(50);
  649. }
  650. //修改管理员密码
  651. void HSadminpassword()
  652. {
  653.   uchar i=0;
  654.   x=0;
  655.   out=0;
  656.   h=1;
  657.   clr_screen();
  658.   while(out==0)
  659.   {
  660.     lcd_pos(1,0);             //请输入新密码
  661.     for(i=0;i<16;i++)
  662.     {
  663.       lcd_wdat(DIS18[i]);
  664.     }
  665.         HSjzaj();
  666.         lcd_pos(2,0);            
  667.     for(i=0;i<6;i++)
  668.     {
  669.       lcd_wdat(adminpassword1[i]+0x30);                                 
  670.     }
  671.         lcd_pos(3,0);            
  672.     for(i=0;i<16;i++)
  673.     {
  674.       lcd_wdat(DIS19[i]);
  675.     }
  676.         if(x==1)
  677.         {
  678.           for(i=0;i<6;i++)
  679.           {
  680.             adminpassword[i]=adminpassword1[i];
  681.           }
  682.           cc(0x2400); // 擦除第 3 个扇区
  683.       for(i=0;i<6;i++)
  684.           {
  685.             xcx(0x2400+i,adminpassword[i]);  // 对 EEPROM区 2400h 写入
  686.           }
  687.           EA=1;
  688.           clr_screen();
  689.           lcd_pos(2,0);            
  690.       for(i=0;i<16;i++)
  691.       {
  692.         lcd_wdat(DIS20[i]);      
  693.       }
  694.           delay(1000);
  695.           out=1;
  696.         }
  697.   }
  698.   for(i=0;i<6;i++)
  699.   {
  700.     adminpassword1[i]=0;                                                //将密码1寄存器置零
  701.   }
  702.   clr_screen();
  703. }

  704. //修改密码
  705. void HSpassword()
  706. {
  707.   uchar i=0;
  708.   x=0;
  709.   out=0;
  710.   h=0;
  711.   clr_screen();
  712.   
  713.   while(out==0)
  714.   {
  715.     lcd_pos(1,0);             //请输入新密码
  716.     for(i=0;i<16;i++)
  717.     {
  718.       lcd_wdat(DIS18[i]);
  719.     }
  720.         HSjzaj();
  721.         lcd_pos(2,0);            
  722.     for(i=0;i<6;i++)
  723.     {
  724.       lcd_wdat(password1[i]+0x30);                                 
  725.     }
  726.         lcd_pos(3,0);            
  727.     for(i=0;i<16;i++)
  728.     {
  729.       lcd_wdat(DIS19[i]);
  730.       delay(0);
  731.     }
  732.         if(x==1)
  733.         {
  734.           for(i=0;i<6;i++)
  735.           {
  736.             password[i]=password1[i];
  737.           }
  738.           cc(0x2200); // 擦除第 2 个扇区
  739.       for(i=0;i<6;i++)
  740.           {
  741.             xcx(0x2200+i,password[i]);  // 对 EEPROM区 2200h 写入
  742.           }
  743.           EA=1;
  744.           clr_screen();
  745.           lcd_pos(2,0);            
  746.       for(i=0;i<16;i++)
  747.       {
  748.         lcd_wdat(DIS20[i]);        
  749.       }
  750.           delay(1000);
  751.           out=1;
  752.         }
  753.   }
  754.   for(i=0;i<6;i++)
  755.   {
  756.     password1[i]=0;                                                //将密码1寄存器置零
  757.   }
  758.   clr_screen();
  759. }                        
  760.         
  761. //管理员模式
  762. void HSAdministrators()
  763. {
  764.   uchar i,p=0;
  765.   h=1;  
  766.   clr_screen();                                                                                                                   ///
  767.   while(out==0)
  768.   {
  769.     lcd_pos(2,0);             //请输入管理密码
  770.     for(i=0;i<16;i++)
  771.     {
  772.       lcd_wdat(DIS6[i]);
  773.     }
  774.     HSjzaj();
  775.         if(x==1)
  776.         {         
  777.           x=0;
  778.           k=0;         
  779.       for(i=0;i<6;i++)
  780.       {
  781.         if(adminpassword1[i]==adminpassword[i])
  782.             {
  783.               delay(0);
  784.             }
  785.         else
  786.             {
  787.               p=1;
  788.             }
  789.       }
  790.           if(p==0)
  791.       {
  792.         clr_screen();
  793.                 lcd_pos(2,0);            
  794.         for(i=0;i<16;i++)
  795.         {
  796.           lcd_wdat(DIS3[i]);                                   //管理密码正确         
  797.         }
  798.                 delay(1000);
  799.                 while(out==0)
  800.                 {
  801.                   clr_screen();
  802.                   lcd_pos(1,0);            
  803.           for(i=0;i<16;i++)
  804.           {
  805.             lcd_wdat(DIS7[i]);                                   //添加指纹
  806.             delay(0);
  807.           }
  808.                   lcd_pos(2,0);            
  809.           for(i=0;i<16;i++)
  810.           {
  811.             lcd_wdat(DIS8[i]);                                   //清空指纹
  812.             delay(0);
  813.           }
  814.                   lcd_pos(3,0);            
  815.           for(i=0;i<16;i++)
  816.           {
  817.             lcd_wdat(DIS9[i]);                                   //开锁密码
  818.             delay(0);
  819.           }
  820.                   lcd_pos(4,0);            
  821.           for(i=0;i<16;i++)
  822.           {
  823.             lcd_wdat(DIS10[i]);                                   //管理密码
  824.             delay(0);
  825.           }
  826.                   b='*';
  827.                   HSjzaj();
  828.                   switch(b)
  829.                   {
  830.                     case (0): FPM10A_Add_Fingerprint();break;                                                                //添加指纹
  831.                         case (1): FPM10A_Delete_All_Fingerprint();break;                                                //删除所有存贮的指纹库
  832.                         case (2): HSpassword();break;                                                                                        //修改开锁密码
  833.                         case (4): HSadminpassword();break;                                                                                //修改管理员密码
  834.                   }
  835.                 }
  836.           }
  837.       else
  838.       {
  839.         clr_screen();
  840.             lcd_pos(2,0);            
  841.         for(i=0;i<16;i++)
  842.         {
  843.           lcd_wdat(DIS14[i]);                                  //管理密码错误         
  844.         }
  845.                 delay(1000);
  846.       }
  847.           for(i=0;i<6;i++)
  848.       {
  849.         adminpassword1[i]=0;                                                //将密码1寄存器置零
  850.       }
  851.           clr_screen();
  852.     }
  853.   }
  854. }

  855. void kaisuo()
  856. {
  857.   kai=0;
  858.   kai1=0;
  859.   kai2=0;
  860.   delay(3000);
  861.   kai=1;
  862.   kai1=1;
  863.   kai2=1;
  864. }



  865. /*********************************************************
  866. *                                                        *
  867. * 主函数                                                 *
  868. *                                                        *
  869. *********************************************************/
  870. void main()
  871. {
  872.    uchar i;                                                                                                                                          ///
  873.    delay(100);                 //上电,等待稳定
  874.    lcd_init();                                  //初始化LCD
  875.    Uart_Init();                            //串口初始化
  876.    finger_id = dcx(0x2002);  // 开机读取 EEPROM区 2002h 数据 ,还原关电前                    
  877.    while(1)
  878.    {
  879.      for(i=0;i<6;i++)
  880.      {
  881.        adminpassword[i]=dcx(0x2400+i);                                        //从6个扇区取出6位管理员密码
  882.            password[i]=dcx(0x2200+i);                                                //从6个扇区取出6位开门密码
  883.      }         
  884.          out=0;
  885.          lcd_pos(2,0);             //欢迎使用
  886.      for(i=0;i<16;i++)
  887.      {
  888.        lcd_wdat(DIS1[i]);
  889.      }
  890.          lcd_pos(3,0);             //云部落指纹锁
  891.      for(i=0;i<16;i++)
  892.      {
  893.        lcd_wdat(DIS2[i]);
  894.      }
  895.          FPM10A_Find_Fingerprint();                 //对比指纹(重点)
  896.          HSjzaj();                                                                        //矩阵键盘输入
  897.          if(x==1)                                                                        //“确认”标志位,按下进行输入密码后对比
  898.          {
  899.            x=0;
  900.            h=0;
  901.            confirm();
  902.            k=0;
  903.          }
  904.          if(Administrators==1)                                                //“管理员模式”标志位,按下进行管理员模式
  905.          {
  906.            Administrators=0;
  907.            HSAdministrators();
  908.          }
  909.          if(reset1==1)                                                                //“复位”标志位,按下后管理员密码和开门密码还原
  910.          {
  911.            clr_screen();
  912.            reset1=0;
  913.            wolegequ();
  914.            lcd_pos(3,0);            
  915.        for(i=0;i<16;i++)
  916.        {
  917.          lcd_wdat(DIS21[i]);
  918.        }
  919.            delay(1000);
  920.            clr_screen();
  921. ……………………

  922. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

全部资料51hei下载地址:
成品2.zip (67.4 KB, 下载次数: 976)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:434175 发表于 2018-12-6 15:23 | 显示全部楼层
老哥老哥有原理图吗麻烦一下,我下了没有原理图不知道怎么接线。
回复

使用道具 举报

ID:247778 发表于 2018-12-7 19:41 | 显示全部楼层
wxddxw111 发表于 2018-12-6 15:23
老哥老哥有原理图吗麻烦一下,我下了没有原理图不知道怎么接线。

程序里有注释呀,AS608接P3.0和P3.1就行注意反接(3.3V供电),12864按程序里的分配接就行
回复

使用道具 举报

ID:144634 发表于 2018-12-11 14:11 | 显示全部楼层
老哥,请问下这个指纹模块具体是怎么使用的呢?萌新第一次搞这种模块不太认识。十分感谢!!
回复

使用道具 举报

ID:247778 发表于 2018-12-23 16:31 | 显示全部楼层
Johnny·JH 发表于 2018-12-11 14:11
老哥,请问下这个指纹模块具体是怎么使用的呢?萌新第一次搞这种模块不太认识。十分感谢!!

主要是串口调试,你先别管硬件,先捋一遍程序
回复

使用道具 举报

ID:265598 发表于 2018-12-25 13:08 | 显示全部楼层
老哥,你这个指纹模块,单片机晶振用12M还是11.059M的?
回复

使用道具 举报

ID:413080 发表于 2019-1-3 20:55 来自手机 | 显示全部楼层
请问12864是带字符的吗?有没有仿真图
回复

使用道具 举报

ID:247778 发表于 2019-2-17 20:01 | 显示全部楼层
布鲁斯。。。 发表于 2018-12-25 13:08
老哥,你这个指纹模块,单片机晶振用12M还是11.059M的?

11.0592
回复

使用道具 举报

ID:247778 发表于 2019-2-17 20:02 | 显示全部楼层
1337173140 发表于 2019-1-3 20:55
请问12864是带字符的吗?有没有仿真图

带字库,没有
回复

使用道具 举报

ID:247778 发表于 2019-3-13 20:32 | 显示全部楼层
77621516 发表于 2019-2-26 14:35
给个原理图可以吗,实在不会接线

程序初始化那块有各个引脚的位定义,指纹模块和串口反接就行
回复

使用道具 举报

ID:488047 发表于 2019-3-15 10:11 | 显示全部楼层
好东西,学习一下,谢谢!
回复

使用道具 举报

ID:435174 发表于 2019-3-17 09:39 | 显示全部楼层
画块底板和PCB吧,杜邦线看着我都替你慌
回复

使用道具 举报

ID:485674 发表于 2019-3-28 23:12 | 显示全部楼层
受益匪浅,感谢楼主
回复

使用道具 举报

ID:486097 发表于 2019-3-29 11:07 | 显示全部楼层
请问有没有PCB电路原理图呀
回复

使用道具 举报

ID:507630 发表于 2019-4-10 11:42 | 显示全部楼层
电磁锁在哪买的,可以发下链接吗?我一直找不到合适的
回复

使用道具 举报

ID:473121 发表于 2019-4-11 18:56 | 显示全部楼层
怎么获取
回复

使用道具 举报

ID:508348 发表于 2019-4-12 01:07 | 显示全部楼层
想问一下 指纹模块和pc能通讯 还可以获得指纹 但是和单片机就通讯不了  这个问题出在哪里 应该怎么调试 希望楼主能给与指导 十分感激
回复

使用道具 举报

ID:247778 发表于 2019-4-12 17:38 | 显示全部楼层
zappp 发表于 2019-4-12 01:07
想问一下 指纹模块和pc能通讯 还可以获得指纹 但是和单片机就通讯不了  这个问题出在哪里 应该怎么调试 希 ...

看看AS608的通信协议,各个寄存器配置好,单片机串口配置好就行,你看看我的初始化流程
回复

使用道具 举报

ID:458662 发表于 2019-4-20 20:39 来自手机 | 显示全部楼层
你好,不是还要发送口令吗?怎么你只要发送包头而且还不要接收模块发送过来的对比信息。
回复

使用道具 举报

ID:520900 发表于 2019-5-8 16:32 | 显示全部楼层
77621516 发表于 2019-2-28 21:48
AS608的WAK引脚接那里?

所以接在哪里解决了吗类似课题能否+QQ1690474716探讨探讨
回复

使用道具 举报

ID:442414 发表于 2019-5-8 17:40 | 显示全部楼层
点赞!佩服佩服
回复

使用道具 举报

ID:564892 发表于 2019-6-17 20:04 | 显示全部楼层
本帖最后由 wojiaolisen.123 于 2019-6-17 21:02 编辑

你好请问显示屏只能用12864的吗,用别的是不是得修改程序
回复

使用道具 举报

ID:564892 发表于 2019-6-17 20:08 | 显示全部楼层
大神问一下那个只能用12864吗,用别的是不是得修改程序
回复

使用道具 举报

ID:564892 发表于 2019-6-17 20:55 | 显示全部楼层
这个程序的矩阵用的是哪个接口,是p10-p17还是什么。
回复

使用道具 举报

ID:304358 发表于 2019-6-18 09:18 来自手机 | 显示全部楼层
可以记录一下开门人员和时间吗?拓展一下更好。
回复

使用道具 举报

ID:564892 发表于 2019-6-18 10:15 来自手机 | 显示全部楼层
我想问一下如果不用显示屏和密码解锁怎么改程序
回复

使用道具 举报

ID:355082 发表于 2019-6-21 14:04 | 显示全部楼层
矩阵插接没有反应啊
回复

使用道具 举报

ID:430746 发表于 2019-7-9 13:19 | 显示全部楼层
楼主有接线图吗?可以用LCD1602码
回复

使用道具 举报

ID:473471 发表于 2019-7-21 22:22 | 显示全部楼层
谢谢楼主。好资料,踩一脚下次来取!
回复

使用道具 举报

ID:399179 发表于 2019-7-22 21:00 来自手机 | 显示全部楼层
楼主能不能给个原理图啊?
回复

使用道具 举报

ID:128880 发表于 2019-7-31 14:01 | 显示全部楼层
刚好要学习这个 谢谢分享
回复

使用道具 举报

ID:74382 发表于 2019-8-23 15:43 | 显示全部楼层
矩阵插接在哪里呀。没有注解
回复

使用道具 举报

ID:342975 发表于 2019-9-10 16:02 | 显示全部楼层
借鉴学习
回复

使用道具 举报

ID:613538 发表于 2019-9-19 13:56 | 显示全部楼层
学习学习 谢谢楼主
回复

使用道具 举报

ID:367428 发表于 2019-10-4 15:18 | 显示全部楼层
感谢大佬
回复

使用道具 举报

ID:611643 发表于 2019-10-8 21:32 | 显示全部楼层
您好,我问一下能给一下那个继电器哪里的接线图吗?特别想学习一下
回复

使用道具 举报

ID:676417 发表于 2019-12-30 11:05 来自手机 | 显示全部楼层
不错,研究中,感谢分享
回复

使用道具 举报

ID:380068 发表于 2020-1-22 23:09 | 显示全部楼层
源码编译报错
回复

使用道具 举报

ID:380068 发表于 2020-1-22 23:10 | 显示全部楼层
下载完编译失败
回复

使用道具 举报

ID:208271 发表于 2020-1-23 16:00 | 显示全部楼层
a2569808500 发表于 2019-3-13 20:32
程序初始化那块有各个引脚的位定义,指纹模块和串口反接就行

51单片机需要串口通信时,晶振频率一般选择11.0592Mhz,这样波特率算出来才是整数倍,通信才准确,如果用12MHZ的话,可能会出错。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表