AS608指纹模块高级功能实现(一):底层数据传输 您所在的位置:网站首页 as608程序 AS608指纹模块高级功能实现(一):底层数据传输

AS608指纹模块高级功能实现(一):底层数据传输

2024-03-11 15:05| 来源: 网络整理| 查看: 265

AS608指纹模块高级功能实现(一):底层数据传输——指纹特征库上传给上位机 一、写在前面 二、实现目标、主要难点 目标 难点 三、芯片通讯方式 四、实验流程 一、芯片配置 二、指纹录入,生成出该指纹的特征模板存放于Buffer1 三、模板保存于缓冲区并通过串口发送至上位机 五、主要实现代码 串口2:UART2.h AS608.h main.c 六、实验结果 七、后记

一、写在前面

最近突发其想,想利用两个AS608模块实现数据共享,也就是利用其中一个录入指纹,另外一个也能够读取到录入的指纹。但是笔者找遍全网,也只有实现了基本的录入、删除、验证功能的例程,以及一个具有全功能的上位机,如果要实现数据共享,那么必须要实现文件底层数据的传输,而上位机根本无法看到内部的具体实现。于是,笔者还是决定通过串口调试、翻阅手册,探究AS608数据传输的实现方法。

AS608作为一款比较成熟的指纹芯片,SoC已经封装好了各种指令,我们只要发送我们所需的指令包,便可完成一系列的操作。笔者使用了STC15系列单片机进行试验,加入了LCD辅助显示程序运行情况,本文主要目的还是在于探讨,对于一些交互并没有十分重视,对于AS608的基本操作也没有过多的介绍,希望大家理解。

二、实现目标、主要难点

目标

使用串口调试助手,获得芯片一份完整指纹特征模板,并生成.mb文件

难点

滤除包头包尾,UART串口通讯

三、芯片通讯方式

1、通讯方法

通过给AS608串口发送特定的指令,就可以调用里面的算法,进行相应的操作。这些指令有三种格式:命令包格式,数据包格式和接收包格式。命令包是用来控制AS608的,数据包和结束包只在导出(把模块里面的指纹导出到别的设备)和导入(把其他设备的数据导入模块)指纹数据的时候用到的。

上图介绍了芯片三种包的格式,其中数据包和结束包是本文重点用到的,也是最容易被大家忽略掉的。

四、实验流程

一、芯片配置

也可以自行设置,涉及到串口通信问题,笔者串口1连接上位机,串口2连接AS608模块。

二、指纹录入,生成出该指纹的特征模板存放于Buffer1

emmm自己画的,忽视水印

两次按指纹完成一次指纹录入。

三、模板保存于缓冲区并通过串口发送至上位机

关键在于滤除包头包尾,包头使用逐层判断,判断包头后开始接收数据,包头后面跟64字节有效+2字节校验和,所以我们只需要for循环接收64字节,后面2字节不管,完成后存放特征寄存数组,随后进入下一次数据包头判断。

五、主要实现代码

串口2:UART2.h 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155#ifndef __UART2_H #include #include "uart.h" #define __UART2_H #define uchar unsigned char #define uint unsigned int #define S2RI 0x01           //串口2接收中断请求标志位 #define S2TI 0x02           //串口2发送中断请求标志位 #define S2RB8 0x04 #define S2TB8 0x08         #define UART2_MAX_RECV_LEN      768                 //最大接收缓存字节数 #define UART2_MAX_SEND_LEN      1028                    //最大发送缓存字节数 //串口接收缓存区     uchar  xdata UART2_RX_BUF[24];              //命令接收缓冲,不需要太大 uchar  xdata UART2_TX_BUF[UART2_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节 uchar  xdata CHAR_TEMP_BUF[64]; uchar  xdata CHARBUF[800]; uint   UART2_RX_STA = 0;             //命令接收缓冲指针 uint   CHAR_TEMP_STA = 0;            //数据包缓冲区临时指针 uint   CHARBUF_STA = 0;              //特征模板存储指针 uchar  Head_Flag = 0;                //数据包包头检测标志 //串口2初始化 void UART2_Init() {         TMOD |= 0x20;   // 0010 0000 定时器2工作于方式2(8位自动重装方式)     T2H  = 0xfd;    // 波特率:37600 /22.1184MHZ     T2L  = 0xc0;    // 波特率:37600 /22.1184MHZ     AUXR = 0x14;    // 使用定时器2作为波特率发生器     S2CON = 0x50;       // 设置中断     IE2 =0x01;         EA   = 1; } //串口2发送一个字节 void UART2_SendData(uchar c) {     S2BUF = c;     while(!(S2CON&S2TI));  //若S2TI=0,在此等待     S2CON&=~S2TI;          //S2TI=0 } void show_rx_buff(void) {     uint i=0;     for(i;i>24);     UART2_SendData(AS608Addr>>16);     UART2_SendData(AS608Addr>>8);     UART2_SendData(AS608Addr); } //发送包标识 static void SendFlag(uchar flag) {     UART2_SendData(flag); } //发送包长度 static void SendLength(int length) {     UART2_SendData(length>>8);     UART2_SendData(length); } //发送指令码 static void Sendcmd(uchar cmd) {     UART2_SendData(cmd); } //发送BuffID static void SendBuffID(uchar BuffID) {     UART2_SendData(BuffID); } //发送校验和 static void SendCheck(uint check) {     UART2_SendData(check>>8);     UART2_SendData(check); } //判断中断接收数组有没有应答包 //waittime为等待中断接收数组等待时间 //返回值:数据包首地址 static uchar *JudgeStr(uint waittime) { //  uint temp;     char *rdata;     uchar str[8];     str[0]=0xef;str[1]=0x01;str[2]=0xFF;     str[3]=0xFF;str[4]=0xFF;     str[5]=0xFF;str[6]=0x07;str[7]='\0';       UART2_RX_STA=0;     while(--waittime)     {         Delay_Ms(1000);         if(1)         {             UART2_RX_STA=0;             rdata=strstr((const char*)UART2_RX_BUF,(const char*)str);             if(rdata)                 return (uchar*)rdata;           }           }     return 0; } //按指纹,指令号:01 uchar PS_GetImage(void) {   uint temp;   uchar  ensure;     uchar  *rdata;     SendHead();     SendAddr();     SendFlag(0x01);     SendLength(0x03);     Sendcmd(0x01);   temp =  0x01+0x03+0x01;     SendCheck(temp);     rdata=JudgeStr(8000);     if(rdata)         ensure=rdata[9];     else         ensure=0xff;     return ensure; } //生成特征,指令号:02 uchar PS_GenChar(uchar BufferID) {     uint temp;   uchar  ensure;     uchar  *rdata;     SendHead();     SendAddr();     SendFlag(0x01);     SendLength(0x04);     Sendcmd(0x02);     UART2_SendData(BufferID);     temp = 0x01+0x04+0x02+BufferID;     SendCheck(temp);     rdata=JudgeStr(8000);     if(rdata)         ensure=rdata[9];     else         ensure=0xff;     return ensure; } //合成buffer1和buffer2中的特征,指令号:05 uchar PS_RegModel(void) {     uint temp;   uchar  ensure;     uchar  *rdata;     SendHead();     SendAddr();     SendFlag(0x01);     SendLength(0x03);     Sendcmd(0x05);     temp = 0x01+0x03+0x05;     SendCheck(temp);     rdata=JudgeStr(8000);     if(rdata)         ensure=rdata[9];     else         ensure=0xff;     return ensure;      } //上传特征函数,指令号:08 void PS_Upchar() {     uint temp;   //uchar  ensure;     //uchar  *rdata;     SendHead();     SendAddr();     SendFlag(0x01);     SendLength(0x04);     Sendcmd(0x08);     UART2_SendData(0x01);   temp = 0x01+0x04+0x08+0x01;     SendCheck(temp);     /*rdata=JudgeStr(8000);     if(rdata)         ensure=rdata[9];     else         ensure=0xff;     return ensure;*/ } //函数功能:完成两次录入指纹并生成特征模板存于Buffer1和Buffer2 void Create_FR_Char(void) {     uchar i,ensure ,processnum=0;     uint ID_NUM=0;     while(1)     {         switch (processnum)         {             case 0:                 i++;                 LCD_show(0x00,"please press1");                 ensure=PS_GetImage();                 if(ensure==0x00)                 {                     ensure=PS_GenChar(CharBuffer1);                     if(ensure==0x00)                     {                         Delay_Ms(1);                         LCD_show(0x00,"Press1 Finish");                         Delay_Ms(100);                         i=0;                         processnum=1;//跳到第二步                     }else {};                 }else {};             break;                                 case 1:                 i++;               LCD_show(0x00,"try again");                 Delay_Ms(100);                 ensure=PS_GetImage();                 if(ensure==0x00)                 {                     ensure=PS_GenChar(CharBuffer2);//????                     if(ensure==0x00)                     {                         Delay_Ms(1);                         LCD_show(0x00,"Press2 Finish");                         Delay_Ms(100);                         i=0;                         processnum=2;//跳往第三步                     }else {};                       }else {};                       break;                                         case 2:                 LCD_show(0x00,"Creating Press");                 Delay_Ms(500);                 ensure=PS_RegModel();                 if(ensure==0x00)                 {                     LCD_show(0x00,"Creat Success");                     return ;                 }                 else                     {                         LCD_show(0x00,"Cmp defeat");                         LCD_show(0x40,"Try again");                         processnum=0;//返回第一步                     }                 Delay_Ms(1000);                 break;                     }         Delay_Ms(400);         if(i==10)//超过5次未按手指退出             break;     }       } #endif main.c 12345678910111213141516171819202122232425262728293031323334353637383940414243444546#include "STC15W4k.h" #include "UART.h" #include "UART2.h" #include "AS608.h" #include "lcd.h" sbit key1 = P2^4; sbit key2 = P2^3; void port_mode()            //STC15系列引口有三种模式,此为设置成开漏模式 {     P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00;     P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00; } void main() {     port_mode();     Init_LCD();     UART_Init();     UART2_Init();     UART_Send_Str("初始化完毕");     LCD_show(0x00,"Init Success");     while(1)     {         if(key1==0)         {             Delay_Ms(5);             if(key1==0)             {             Create_FR_Char();             PS_Upchar();             }         }         if(key2==0)         {             Delay_Ms(5);             if(key2==0)             {                 LCD_show(0x00,"Sending");                 show_rx_buff();             }         }     } }

六、实验结果

为操作方便,加入了按键,按键1完成录入,显示Creat Success,在完成第一步后按下按键2,给串口调试助手发送特征模板数据。实验结果以及对比如图: 这是未剔除包头包尾的数据,可以看到包头结尾的0x42表示后面有64字节有效数据+2字节的校验和数据。 剔除后的串口数据。 为了更直观看到对比,笔者将原数据剔除包头包尾后进行对比,看一看到是完全一样的。 真的真的是一个个手动删除!(加鸡腿)

最后,对数据进行打包成.mb文件,使用上位机上传指纹特征到芯片,同时进行指纹验证。 对比通过,大功告成!

七、后记

本实验换言之就是把数据拎了出来又放回去,但是我们实现了在底层进行了数据操作,这样的操作对于我们进行文件转移、数据共享是非常有意义的。同时也加深了对文件组成原理、通信原理的理解。

本实验的代码也有不足的地方,算法有待优化,也有部分bug,希望借此抛砖引玉,欢迎大家提供意见。

最后还要感谢几位在本实验过程中给予过帮助的朋友。

源代码下载:https://pan.baidu.com/s/1hfwgWqE66ruNBTlR7FC3EQ 提取码:8fb7



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

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