找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2521|回复: 0
打印 上一主题 下一主题
收起左侧

基于avr单片机的ZAZ-010指纹识别电子密码锁设计资料

[复制链接]
跳转到指定楼层
楼主
本设计开发了一款基于单片机的指纹识别电子密码锁系统。该系统以ATmeg16单片机作为模块核心,通过串口通信控制ZAZ-010指纹模块实现录取指纹并存储指纹数据,并通过HS12864-15C液晶显示比对流程及比对结果,辅以直流继电器与发光二极管模拟开锁的动作。本系统具有体积小、性价比高、传输速度快、适合家庭及单位使用。

程序的巡检过程: 首先对各模块进行初始化,检测在有无按键按下,如果按下判断是那一个按键,并作出判断是否调用相应子程序;当按键1按下后,调用通信模块子程序,录入指纹并将其存入模块缓冲区,同理当按键2按下后,效果相同。
依次当按键3按下时,将指纹模块两缓冲区中的指纹特征文件合成特征模板并存储与指纹模板库中,当4按键按下后搜索指纹并比对.当指纹模块中有指纹存储时直接按4键同样也可进行比对。
程序关键的就是对指纹模块的通信控制, 考虑到处理过程太过冗长,限于篇幅只能将其省略,如需查看,可以看附录1。其它命令发送子函数因大部分的命令大体格式基本相同。



液晶键盘测试程序见附录2:
液晶键盘测试程序结果如图 4-3所示:

  1. #include<avr/io.h>
  2. #include<util/delay.h>
  3. //#include<avr/pgmspace.h>                 
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define key1 0x01
  7. #define key2 0x02
  8. #define key3 0x04
  9. #define key4 0x08
  10. static uchar k=0;
  11. uchar name00[]={"                "};
  12. uchar name01[]={"    欢迎使用    "};
  13. uchar name02[]={"单片机指纹密码锁"};
  14. uchar name03[]={"                "};
  15. uchar name04[]={"  指纹采集开始  "};
  16. uchar name05[]={"  指纹对比开始  "};
  17. uchar name06[]={"  指纹存储开始  "};
  18. uchar name07[]={"    一次采集    "};
  19. uchar name08[]={"    二次采集    "};
  20. uchar name09[]={"    录入成功    "};
  21. uchar name10[]={"    录入失败    "};
  22. uchar name11[]={"    收包有错    "};
  23. uchar name12[]={"传感器上无手指  "};
  24. uchar name13[]={"  生成特征成功  "};
  25. uchar name14[]={"图想乱生不成特征"};
  26. uchar name15[]={"图象正常特征点少"};
  27. uchar name16[]={"指纹模板合并成功"};
  28. uchar name17[]={"指纹模板合并失败"};
  29. uchar name18[]={"  非同一手指    "};
  30. uchar name19[]={"    存储成功    "};
  31. uchar name20[]={"  写指纹库出错  "};
  32. uchar name21[]={"    指纹匹配    "};
  33. uchar name22[]={"  指纹不匹配    "};
  34. uchar name23[]={"    密码正确    "};
  35. uchar name24[]={"    密码不正确    "};
  36. uchar FP_1[6]={};
  37. uchar FP_2[6]={};
  38. uchar FP_Pack_Head[6]={0xEF,0x01,0xFF,0xFF,0xFF,0xFF};  //协议包头
  39. uchar FP_Get_Img[6]={0x01,0x00,0x03,0x01,0x0,0x05};    //获得指纹图像
  40. uchar FP_Search_0_9[11]={0x01,0x0,0x08,0x04,0x01,0x0,0x0,0x0,0x13,0x0,0x21}; //搜索0-9号指纹
  41. uchar FP_Img_To_Buffer1[7]={0x01,0x0,0x04,0x02,0x01,0x0,0x08}; //将图像放入到BUFFER1
  42. uchar FP_Img_To_Buffer2[7]={0x01,0x0,0x04,0x02,0x02,0x0,0x09}; //将图像放入到BUFFER2
  43. uchar FP_Reg_Model[6]={0x01,0x0,0x03,0x05,0x0,0x09}; //将BUFFER1跟BUFFER2合成特征模版
  44. volatile uchar  FP_Save_Finger1[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0B,0x00,0x19};//将BUFFER1中的特征码存放到指定的位置
  45. volatile uchar  FP_Save_Finger2[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0C,0x00,0x1A};//将BUFFER1中的特征码存放到指定的位置
  46. volatile uchar  FP_Save_Finger3[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0D,0x00,0x1B};//将BUFFER1中的特征码存放到指定的位置
  47. uchar yb=0x80;
  48. //初始化 UART 子程序
  49. void UART_Init(void)
  50. {
  51.     UCSRB  =  0x00;     //disable while setting baud rate
  52.     UCSRA  =  0x00;     //Bit1为1则倍速发送
  53.     UCSRC  =  0x06;     //传送一桢数据位为8位
  54.     UBRRL  =  0x07;     //波特率:57600 Bps
  55.     UBRRH  =  0x00;     //误差率:0.000%
  56.     UCSRB  =  0x18;     
  57. }
  58. //发送八位数据
  59. void UART_Send_Byte( uchar ucData)

  60. {
  61.   while(!(UCSRA&(1<<UDRE))); //等待缓冲区为空
  62.   UDR = ucData;
  63. }

  64. //接收八位数据
  65. uchar  UART_Receive_Byte(void)
  66. {

  67.   while(!(UCSRA&(1<<RXC)));//等待缓冲区为空
  68.    
  69. return UDR;
  70. }
  71. //_获得指纹图像命令
  72. void Cmd_Get_Img(void)
  73. {
  74.     uchar i,j;
  75.     for(i=0;i<6;i++) //发送包头与模块地址
  76.     UART_Send_Byte(FP_Pack_Head[i]);
  77.     for(i=0;i<6;i++) //发送命令 0x1d
  78.     UART_Send_Byte(FP_Get_Img[i]);
  79.     for(i=0;i<6;i++)
  80.     FP_1[i]=UART_Receive_Byte();
  81.         for(i=0;i<6;i++)
  82.     FP_2[i]=UART_Receive_Byte();
  83.     j=FP_2[3];
  84.    if (j==0x00)
  85.   {_delay_ms(100000);
  86.    reset ();
  87.    display6();}
  88.    if (j==0x01)
  89.    {reset();
  90.     wr_com(yb);
  91.    outChinese(0x90,8,name11);}
  92.    if (j==0x02)
  93.    {_delay_ms(100000);
  94.     reset();
  95.     display7();}
  96.         if (j==0x03)
  97.    { reset();
  98.     wr_com(yb);
  99.    outChinese(0x90,8,name10);}
  100. }
  101. //讲图像转换成特征码存放在Buffer1中
  102. void Cmd_Img_To_Buffer1(void)
  103. {
  104.                 uchar i,j;
  105.                for(i=0;i<6;i++)    //发送包头与模块地址
  106.                  {
  107.                    UART_Send_Byte(FP_Pack_Head[i]);   
  108.                         }
  109.            
  110.                         for(i=0;i<7;i++)   //发送命令 将图像转换成 特征码 存放在 CHAR_buffer1
  111.              {
  112.                          UART_Send_Byte(FP_Img_To_Buffer1[i]);
  113.                         }
  114.             for(i=0;i<6;i++)
  115.             {
  116.                         FP_1[i]=UART_Receive_Byte();}
  117.                         for(i=0;i<6;i++)
  118.           {
  119.                     FP_2[i]=UART_Receive_Byte();}
  120.            j=FP_2[3];
  121.          if (j==0x00)
  122.     {_delay_ms(100000);
  123.       reset ();
  124.       display8();}
  125.            if (j==0x06)
  126.           {_delay_ms(100000);
  127.       reset ();
  128.       display9();}
  129.           if (j==0x07)
  130.           {_delay_ms(100000);
  131.       reset ();
  132.       display10();}
  133. }
  134. //将图像转换成特征码存放在Buffer2中
  135. void Cmd_Img_To_Buffer2(void)
  136. {
  137.            uchar i,j;
  138.            for(i=0;i<6;i++)    //发送包头
  139.                  {
  140.                    UART_Send_Byte(FP_Pack_Head[i]);   
  141.                         }
  142.            
  143.                       for(i=0;i<7;i++)   //发送命令 将图像转换成 特征码 存放在 CHAR_buffer2
  144.              {
  145.                          UART_Send_Byte(FP_Img_To_Buffer2[i]);
  146.                         }
  147.             for(i=0;i<6;i++)
  148.            {
  149.                         FP_1[i]=UART_Receive_Byte();}
  150.                         for(i=0;i<6;i++)
  151.           {
  152.                     FP_2[i]=UART_Receive_Byte();}  
  153.                   j=FP_2[3];
  154.          if (j==0x00)
  155.     {_delay_ms(100000);
  156.       reset ();
  157.       display8();}
  158.            if (j==0x06)
  159.           {_delay_ms(100000);
  160.       reset ();
  161.       display9();}
  162.           if (j==0x07)
  163.           {_delay_ms(100000);
  164.       reset ();
  165.       display10();}

  166. }

  167. //将BUFFER1 跟 BUFFER2 中的特征码合并成指纹模版
  168. void Cmd_Reg_Model(void)
  169. {
  170.     uchar i,j;
  171.     for(i=0;i<6;i++) //发送包头与模块地址
  172.     {
  173.       UART_Send_Byte(FP_Pack_Head[i]);   
  174.     }

  175.     for(i=0;i<6;i++) //命令合并指纹模版
  176.     {
  177.       UART_Send_Byte(FP_Reg_Model[i]);   
  178.     }
  179.     for(i=0;i<6;i++)
  180.            {
  181.                         FP_1[i]=UART_Receive_Byte();}
  182.         for(i=0;i<6;i++)
  183.           {
  184.                     FP_2[i]=UART_Receive_Byte(); }
  185.                   j=FP_2[3];
  186. if (j==0x00)
  187. {_delay_ms(400000);
  188.       reset ();
  189.       display11();}
  190. if (j==0x0a)
  191. {_delay_ms(400000);
  192.       reset ();
  193.       display12();
  194.            while(1);}





  195. }
  196. //将并成后的指纹模版存储到指纹模块flash模板库中
  197. void  Store_Char_Model(void)
  198. {   uchar i,j;
  199.     for(i=0;i<6;i++) //发送包头与模块地址
  200.     {
  201.       UART_Send_Byte(FP_Pack_Head[i]);   
  202.     }
  203.    if(k==0)
  204.   { for(i=0;i<9;i++) //命令存储指纹模版
  205.     {
  206.       UART_Send_Byte( FP_Save_Finger1[i]  );
  207.        }
  208.     }
  209.         if(k==1)
  210.    { for(i=0;i<9;i++) //命令存储指纹模版
  211.     {
  212.       UART_Send_Byte( FP_Save_Finger2[i]  );
  213.         }
  214.     }
  215.         if(k==2)
  216.    { for(i=0;i<9;i++) //命令存储指纹模版
  217.     {
  218.       UART_Send_Byte( FP_Save_Finger3[i]  );
  219.   
  220.        }
  221.         }


  222.     for(i=0;i<6;i++)
  223.           {
  224.                         FP_1[i]=UART_Receive_Byte();}
  225.         for(i=0;i<6;i++)
  226.           {
  227.                     FP_2[i]=UART_Receive_Byte(); }
  228.                   j=FP_2[3];

  229. if(j==0x00)
  230. {_delay_ms(400000);
  231.       reset ();
  232.       display13();}
  233. if(j==0x18)

  234. {_delay_ms(300000);
  235.       reset ();
  236.       display14();}





  237. }



  238. //搜索与BUFFER1中特征码相符合的指纹模版
  239. void  search_Char_Mode(void)   
  240. {   uchar i,j;
  241.     for(i=0;i<6;i++) //发送包头与模块地址
  242.     {
  243.       UART_Send_Byte(FP_Pack_Head[i]);   
  244.     }
  245.     for(i=0;i<11;i++) //命令搜索指纹模版
  246.     {
  247.       UART_Send_Byte(FP_Search_0_9[i]);
  248.   
  249.     }
  250. for(i=0;i<6;i++)
  251.            {
  252.                         FP_1[i]=UART_Receive_Byte();}
  253.         for(i=0;i<10;i++)
  254.           {
  255.                     FP_2[i]=UART_Receive_Byte(); }
  256.                   j=FP_2[3];
  257. if(j==0x00)
  258. {_delay_ms(100000);
  259.       reset ();
  260.       display15();}

  261. if(j==0x09)
  262. {_delay_ms(100000);
  263.       reset ();
  264.       display16();}


  265. void keyboard( void)
  266. {  unsigned char Keyvalue;//键盘值
  267. //端口初始化
  268. DDRC=~_BV(PC0)& ~_BV(PC1)& ~_BV(PC2)& ~_BV(PC3);
  269. while(1)
  270. {  Keyvalue=(PINC&0x0F);
  271. if (Keyvalue!=0x0f)
  272. {//有键按下
  273. _delay_ms(20);
  274. Keyvalue=(PINC&0x0F);
  275. if (Keyvalue==0X0F)
  276.   break;//如果延时去抖后,没有检测到键按下,退出本次循环
  277. //如果有按键
  278. if(! (Keyvalue& key1))
  279. {reset ();
  280. display2();
  281. UART_Init();
  282. Cmd_Get_Img();
  283. Cmd_Img_To_Buffer1();
  284. }//按键1的处理部分
  285. if(! (Keyvalue& key2))
  286. { reset ();
  287.   display3();
  288. UART_Init();
  289. Cmd_Get_Img();
  290. Cmd_Img_To_Buffer2();
  291. }//按键2的处理部分
  292. if(! (Keyvalue& key3))
  293. { reset ();
  294. display4();
  295. UART_Init();

  296. Cmd_Reg_Model();
  297. Store_Char_Model();
  298. k++;         }//按键3的处理部分
  299. if(! (Keyvalue& key4))
  300. { reset ();
  301. display5();
  302. UART_Init();
  303. Cmd_Get_Img();
  304. Cmd_Img_To_Buffer1();
  305. search_Char_Mode();


  306.           }//按键4的处理部分
  307.        }
  308. _delay_ms(20);

  309.      }
  310. }

  311. void check_busy (void)                  //读取忙碌状态
  312. {
  313.   DDRA=0;
  314.   PORTA=0xff;
  315.   PORTB&=0xfb;                          //RS=0
  316.   PORTB|=0x02;                          //RW=1;
  317.   PORTB|=0x01;PORTB|=0x01;              //E=1;
  318.   while((PINA&0x80)==0x80);
  319.   PORTB&=0xfe;
  320.                                         //E =0;
  321. }

  322. void wr_com(unsigned char value)        //写指令,写指令时必须为RS=0;RW=0;
  323. {check_busy();
  324. PORTB&=0xfe;                           //E=0;
  325. PORTB&=0xfb;                           //RS=0
  326. PORTB&=0xfd;                           //RW=0;
  327. DDRA=0xff;
  328. PORTA=value;
  329. PORTB|=0x01;                           //E=1;
  330. _delay_us(20);                          //如果没有延时就必须要加查忙指令
  331. PORTB&=0xfe;
  332. DDRA=0x00;                            //E=0;
  333. }

  334. void wr_data(unsigned char sj)          //写数据,写数据时必须为 RS=1;RW=0;
  335. {check_busy();
  336. PORTB&=0xfe;                           //E=0;
  337. PORTB|=0x04;                           //RS=1;
  338. PORTB&=0xfd;                           //RW=0;
  339. DDRA=0xff;
  340. PORTA=sj;
  341. PORTB|=0x01;                           //E=1;
  342. _delay_us(20);                          //如果没有延时就必须要加查忙指令
  343. PORTB&=0xfe;
  344. DDRA=0x00;                            ////E=0;
  345. }

  346. void reset (void)
  347. {
  348. wr_com(0x01);//清屏
  349. wr_com(0x08);//关显示
  350. wr_com(0x03);//归位
  351. wr_com(0x30);//功能设置
  352. wr_com(0x0f);//开显示
  353. wr_com(0x01);//清屏
  354. }
  355. //******************************************************************/
  356. //outChinese 为函数名
  357. //place 为显示地址的首地址
  358. //unit  字符长度
  359. //charcode[]  要显示数据的内容
  360. void outChinese(unsigned char place,unsigned char unit,unsigned char charcode[] )
  361. {
  362. unsigned char i;
  363. wr_com(place);
  364. for(i=0;i<unit*2;i++)//一个汉字为两个字符
  365. wr_data(charcode[i]);
  366. }
  367. void display1(void)
  368. {wr_com(yb);
  369. //ydgb();
  370. outChinese(0x80,8,name00);//第一行:80-87H
  371. outChinese(0x90,8,name01);//第二行:90-97H
  372. outChinese(0x88,8,name02);//第三行:88-8FH
  373. outChinese(0x98,8,name03);//第四行:98-9FH

  374. }
复制代码
以上的Word格式文档51黑下载地址:
设计文档.doc (1.27 MB, 下载次数: 14)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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