AS608指纹模块高级功能实现(一):底层数据传输 | 您所在的位置:网站首页 › as608程序 › AS608指纹模块高级功能实现(一):底层数据传输 |
AS608指纹模块高级功能实现(一):底层数据传输——指纹特征库上传给上位机
一、写在前面
二、实现目标、主要难点
目标
难点
三、芯片通讯方式
四、实验流程
一、芯片配置
二、指纹录入,生成出该指纹的特征模板存放于Buffer1
三、模板保存于缓冲区并通过串口发送至上位机
五、主要实现代码
串口2:UART2.h
AS608.h
main.c
六、实验结果
七、后记
一、写在前面 最近突发其想,想利用两个AS608模块实现数据共享,也就是利用其中一个录入指纹,另外一个也能够读取到录入的指纹。但是笔者找遍全网,也只有实现了基本的录入、删除、验证功能的例程,以及一个具有全功能的上位机,如果要实现数据共享,那么必须要实现文件底层数据的传输,而上位机根本无法看到内部的具体实现。于是,笔者还是决定通过串口调试、翻阅手册,探究AS608数据传输的实现方法。 AS608作为一款比较成熟的指纹芯片,SoC已经封装好了各种指令,我们只要发送我们所需的指令包,便可完成一系列的操作。笔者使用了STC15系列单片机进行试验,加入了LCD辅助显示程序运行情况,本文主要目的还是在于探讨,对于一些交互并没有十分重视,对于AS608的基本操作也没有过多的介绍,希望大家理解。 二、实现目标、主要难点 目标使用串口调试助手,获得芯片一份完整指纹特征模板,并生成.mb文件 难点滤除包头包尾,UART串口通讯 三、芯片通讯方式 1、通讯方法 通过给AS608串口发送特定的指令,就可以调用里面的算法,进行相应的操作。这些指令有三种格式:命令包格式,数据包格式和接收包格式。命令包是用来控制AS608的,数据包和结束包只在导出(把模块里面的指纹导出到别的设备)和导入(把其他设备的数据导入模块)指纹数据的时候用到的。 上图介绍了芯片三种包的格式,其中数据包和结束包是本文重点用到的,也是最容易被大家忽略掉的。 四、实验流程 一、芯片配置也可以自行设置,涉及到串口通信问题,笔者串口1连接上位机,串口2连接AS608模块。 二、指纹录入,生成出该指纹的特征模板存放于Buffer1emmm自己画的,忽视水印 两次按指纹完成一次指纹录入。 三、模板保存于缓冲区并通过串口发送至上位机关键在于滤除包头包尾,包头使用逐层判断,判断包头后开始接收数据,包头后面跟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 实验室设备网 版权所有 |