AS608光学指纹模组编程和应用详解

您所在的位置:网站首页 发送指令是什么 AS608光学指纹模组编程和应用详解

AS608光学指纹模组编程和应用详解

2024-07-14 01:48| 来源: 网络整理| 查看: 265

AS608光学指纹模组编程和应用详解 一、前言

上次讲解了两个简单实用的传感器,反馈很多,能够帮助到大家,我也很开心。所以今天继续给大家介绍一个实用易上手的传感器,在这里有些同学可能就会质疑了,指纹识别哪里简单了?别急,容我细细道来,看完整篇文章,你可能就会觉得,不过如此嘛。 需要程序源码,原理图,数据手册等资料可以到文章底部的链接自行下载。因为这个是我大学做毕设时用到的一个模块,内容比较多,有些细节一时记不清了,所以有些地方可能讲的不是特别深入,如果你们有什么地方看不懂,可以留言和私信给我,我再给你们解答。 如果能够帮助到你,请点赞+关注,又快到做毕设的日子了,我后面也会继续写更多的博文,希望能够帮到你们。

二、芯片介绍

1、芯片简介 AS608是一个集成的光学指纹芯片,内部有指纹算法,其实指纹识别最难的地方在于算法,目前的算法是前人不断开发完善得到的,所以在前几年,算法都是某些大企业独有的技术,他们只卖芯片不卖算法。当然现在的话,光学指纹的算法也逐渐放出来了,因为现在用的更多的是半导体,超声波指纹识别,光学指纹他们已经玩腻了。说远了,回归正题,虽然AS608内部的算法我们是看不到的,但是它预留了一个串口和相关的串口指令集,我们可以用这些指令调用指纹算法,从而实现我们需要的功能。

2、引脚定义 在这里插入图片描述 在这里插入图片描述在这里插入图片描述

三、通讯原理和通讯的流程讲解

1、通讯方法 通过给AS608串口发送特定的指令,就可以调用里面的算法,进行相应的操作。这些指令有三种格式:命令包格式,数据包格式和接收包格式。命令包是用来控制AS608的,数据包和结束包只在导出(把模块里面的指纹导出到别的设备)和导入(把其他设备的数据导入模块)指纹数据的时候用到的。 在这里插入图片描述 我这里以命令包格式为例,给大家讲解一下,包头是2个字节的数据,固定为0xEF01;芯片地址4个字节,默认是0xFFFFFFFF,可以后面发送指令修改;包识别是用来区分指令的类型的,如命令包固定为0x01;包长度是指这一条指令有多少个重要的数据,包长度=包长度至校验和(指令、参数或数据)的总字节数,包含校验和,但不包含包长度本身的字节数;指令就是需要AS608执行的操作,具体的定义我后面再说;参数和具体的指令有关,不同的指令,参数的长度和数值都有所不同;校验和是为了确保串口通讯过程中出现错误,导致命令出错,校验和是从包标识至校验和之间所有字节之和。

2、功能的实现及通讯的流程 我这里只详细讲解录入指纹、识别指纹和删除指纹这三个最常用的功能的实现和操作步骤。如果你们需要用到导出和导入指纹,可以留言或私信给我,我再详细讲解。 1)录入指纹 录入指纹有以下几个步骤: 第一,录入图像。当你的手指放在光学指纹窗口的时候执行这个指令,就可以把指纹的图像拍下来。 第二,生成特征。当你的指纹图像拍下来之后,调用这个指令就可以把图像中的指纹特征记录下来。AS608里面有2个缓存区可以存这个特征,我们这里先用第1个存。 第三,再次录入图像。把同一个手指放在光学指纹窗口,然后执行这个指令,再拍一个指纹图像。 第四,再次生成特征。把第二次录入的图像的指纹特征存到第2个缓存区。 第五.精确比对两枚指纹特征。录入指纹的时候为了增加准确性,最好是记录多次指纹特征,这个指令就是对录入的两个指纹特征进行比对,如果一致就说明是同一个人的同一个指纹。 第六,合并特征(生成模板)。当录入了两个指纹特征,并且两个特征是一致的时候,就可以把两个特征合并成一个指纹模板。这个指纹模板就是我们最终要录入的指纹。 第七,储存模板。当生成一个模板的时候,我们可以把这个模板存到AS608内部的Flash里面,存储的时候需要输入一个指纹ID号,这个ID其实是Flash的地址,不同的ID号,存储的位置不同,最多好像能存两三百个指纹。 2)识别指纹 第一,录入图像。这一步和录入指纹的第一步是一样的,目的是把指纹的图像拍下来。 第二,生成特征。这一步和录入指纹的第二步是一样的。指纹特征可以存到第一个缓存区也可以存到第二个缓存区。 第三,搜索指纹。调用这个指令就会将已经存在Flash里面的指纹模板和缓存区的指纹特征一一比对,如果有搜索到,会返回这个指纹的ID。要注意的是,调用的时候需要指明比对的特征是缓存区1还是缓存区2,你要选择第二步生成的特征所存储的缓存区。 3)删除指纹 删除指纹可以选择删除个别指纹或者删除所有指纹。 删除一个或几个:调用“删除模板”指令,调用的时候需要输入要删除的起始ID号和删除个数,调用之后就会把Flash里面ID号对应位置的数据清除掉。如:起始ID号是3,删除个数是4,那么就会把3,4,5,6这四个ID号对应的指纹删掉。 删除所有:调用“清空指纹库”指令即可。 4)导出指纹模板 第一,读出模板存到缓存区。 第二,上传特征或模板。 5)导入指纹模板 第一,下载特征或模板。 第二,储存模板。 6)导出图像 第一,录入图像。 第二,上传图像。 7)导入图像 第一,下载图像。 第二,生成特征。 第三,存储模板。

3、指令讲解 所有的指令在“AS60x指纹识别SOC用户手册V10”这个文件中都有说明,我这里只给大家讲解一些常用的指令。 1) 录入图像 这个指令你只需要按照下面指令包格式用串口给AS608发送数据就可以了,建议先用电脑串口助手发,理解这个通讯的过程之后再用单片机发。注意下面的数据是十六进制表示的,所以你如果用串口助手发的话要用“hex发送”。发送成功之后模块应该会有回复,根据回复的内容可以知道指令执行的状态。 如:发送:EF 01 FF FF FF FF 01 00 03 01 00 05 回复:EF 01 FF FF FF FF 07 00 03 00 00 0A 说明图像录入成功。 在这里插入图片描述 2) 生成特征 这个指令的发送和接收跟上面录入图像基本一致,唯一的区别是多了一个缓存区号,缓存区有两个,是用来暂存和比较两个指纹特征的。我们可以把第一次录入的图像生成特征存在缓存区1,把第二次录入的图像生成特征存在缓存区2。 在这里插入图片描述 3) 精确比对两枚指纹特征 这个指令可以比对2个缓存区的指纹特征。 在这里插入图片描述 4) 合并特征(生成模板) 把录入的指纹特征进行合并,生成模板以便于存储,合并之后的特征分别存在缓存区1和缓存区2。 在这里插入图片描述 5) 储存模板 当生成一个模板的时候,我们可以把这个模板存到AS608内部的Flash里面。存储的时候要选择缓存区号和指纹ID。缓存区号1和缓存区号2分别对应你两次录入的指纹,选择其中一个保存即可。ID是模块内部Flash的存储地址,不同的ID代表存储的位置不同,同一个位置只能存一个指纹,如果录入了两个不同的指纹,但是都存到同一个ID里面,那么第二次录入的指纹就会覆盖掉第一次录入的。 在这里插入图片描述 6) 搜索指纹 这个指令是用来识别指纹的。调用这个指令就会将已经存在Flash里面的指纹模板和缓存区的指纹特征一一比对,如果有搜索到,会返回这个指纹的ID。要注意的是,调用的时候需要指明比对的特征是在缓存区1还是缓存区2的,你在调用这个指令之前就应该把要识别的指纹的特征存到缓存区1或缓存区2。 在这里插入图片描述 7) 删除模板 调用的时候需要输入要删除的起始ID号和删除个数,调用之后就会把Flash里面ID号对应位置的数据清除掉。如:起始ID号是3,删除个数是4,那么就会把3,4,5,6这四个ID号对应的指纹删掉。 在这里插入图片描述

四、编程讲解

我这里以stm32驱动为例,我这个程序是做一个学生考勤系统的。上位机通过串口给单片机发对应的指令,单片机执行相应的操作,用到了OLED显示屏,语音播报模块,flash芯片等外设,因此里面会有一些外设相关的程序,可以忽略,你们可以只看录入指纹、识别指纹和清空指纹那部分。 1、 底层驱动

#include #include "delay.h" #include "usart2.h" #include "as608.h" u32 AS608Addr = 0XFFFFFFFF; //默认地址 //初始化PA6为下拉输入 //读摸出感应状态(触摸感应时输出高电平信号) void PS_StaGPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟 //初始化读状态引脚GPIOA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//输入下拉模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO GPIO_ResetBits(GPIOA,GPIO_Pin_6); //输出低 } //串口发送一个字节 static void MYUSART_SendData(u8 data) { while((USART2->SR&0X40)==0); USART2->DR = data; } //发送包头 static void SendHead(void) { MYUSART_SendData(0xEF); MYUSART_SendData(0x01); } //发送地址 static void SendAddr(void) { MYUSART_SendData(AS608Addr>>24); MYUSART_SendData(AS608Addr>>16); MYUSART_SendData(AS608Addr>>8); MYUSART_SendData(AS608Addr); } //发送包标识, static void SendFlag(u8 flag) { MYUSART_SendData(flag); } //发送包长度 static void SendLength(int length) { MYUSART_SendData(length>>8); MYUSART_SendData(length); } //发送指令码 static void Sendcmd(u8 cmd) { MYUSART_SendData(cmd); } //发送校验和 static void SendCheck(u16 check) { MYUSART_SendData(check>>8); MYUSART_SendData(check); } //判断中断接收的数组有没有应答包 //waittime为等待中断接收数据的时间(单位1ms) //返回值:数据包首地址 static u8 *JudgeStr(u16 waittime) { char *data; u8 str[8]; str[0]=0xef;str[1]=0x01;str[2]=AS608Addr>>24; str[3]=AS608Addr>>16;str[4]=AS608Addr>>8; str[5]=AS608Addr;str[6]=0x07;str[7]='\0'; USART2_RX_STA=0; while(--waittime) { delay_ms(1); if(USART2_RX_STA&0X8000)//接收到一次数据 { USART2_RX_STA=0; data=strstr((const char*)USART2_RX_BUF,(const char*)str); if(data) return (u8*)data; } } return 0; } //录入图像 PS_GetImage //功能:探测手指,探测到后录入指纹图像存于ImageBuffer。 //模块返回确认字 u8 PS_GetImage(void) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x03); Sendcmd(0x01); temp = 0x01+0x03+0x01; SendCheck(temp); data=JudgeStr(1500); if(data) ensure=data[9]; else ensure=0xff; return ensure; } //生成特征 PS_GenChar //功能:将ImageBuffer中的原始图像生成指纹特征文件存于CharBuffer1或CharBuffer2 //参数:BufferID --> charBuffer1:0x01 charBuffer1:0x02 //模块返回确认字 u8 PS_GenChar(u8 BufferID) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x04); Sendcmd(0x02); MYUSART_SendData(BufferID); temp = 0x01+0x04+0x02+BufferID; SendCheck(temp); data=JudgeStr(1500); if(data) ensure=data[9]; else ensure=0xff; return ensure; } //精确比对两枚指纹特征 PS_Match //功能:精确比对CharBuffer1 与CharBuffer2 中的特征文件 //模块返回确认字 u8 PS_Match(void) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x03); Sendcmd(0x03); temp = 0x01+0x03+0x03; SendCheck(temp); data=JudgeStr(1500); if(data) ensure=data[9]; else ensure=0xff; return ensure; } //搜索指纹 PS_Search //功能:以CharBuffer1或CharBuffer2中的特征文件搜索整个或部分指纹库.若搜索到,则返回页码。 //参数: BufferID @ref CharBuffer1 CharBuffer2 //说明: 模块返回确认字,页码(相配指纹模板) u8 PS_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x08); Sendcmd(0x04); MYUSART_SendData(BufferID); MYUSART_SendData(StartPage>>8); MYUSART_SendData(StartPage); MYUSART_SendData(PageNum>>8); MYUSART_SendData(PageNum); temp = 0x01+0x08+0x04+BufferID +(StartPage>>8)+(u8)StartPage +(PageNum>>8)+(u8)PageNum; SendCheck(temp); data=JudgeStr(2000); if(data) { ensure = data[9]; p->pageID =(data[10]>8)+(u8)PageID; SendCheck(temp); data=JudgeStr(2000); if(data) ensure=data[9]; else ensure=0xff; return ensure; } //删除模板 PS_DeletChar //功能: 删除flash数据库中指定ID号开始的N个指纹模板 //参数: PageID(指纹库模板号),N删除的模板个数。 //说明: 模块返回确认字 u8 PS_DeletChar(u16 PageID,u16 N) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x07); Sendcmd(0x0C); MYUSART_SendData(PageID>>8); MYUSART_SendData(PageID); MYUSART_SendData(N>>8); MYUSART_SendData(N); temp = 0x01+0x07+0x0C +(PageID>>8)+(u8)PageID +(N>>8)+(u8)N; SendCheck(temp); data=JudgeStr(2000); if(data) ensure=data[9]; else ensure=0xff; return ensure; } //清空指纹库 PS_Empty //功能: 删除flash数据库中所有指纹模板 //参数: 无 //说明: 模块返回确认字 u8 PS_Empty(void) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x03); Sendcmd(0x0D); temp = 0x01+0x03+0x0D; SendCheck(temp); data=JudgeStr(2000); if(data) ensure=data[9]; else ensure=0xff; return ensure; } //写系统寄存器 PS_WriteReg //功能: 写模块寄存器 //参数: 寄存器序号RegNum:4\5\6 //说明: 模块返回确认字 u8 PS_WriteReg(u8 RegNum,u8 DATA) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x05); Sendcmd(0x0E); MYUSART_SendData(RegNum); MYUSART_SendData(DATA); temp = RegNum+DATA+0x01+0x05+0x0E; SendCheck(temp); data=JudgeStr(2000); if(data) ensure=data[9]; else ensure=0xff; if(ensure==0) printf("\r\n设置参数成功!"); else printf("\r\n%s",EnsureMessage(ensure)); return ensure; } //读系统基本参数 PS_ReadSysPara //功能: 读取模块的基本参数(波特率,包大小等) //参数: 无 //说明: 模块返回确认字 + 基本参数(16bytes) u8 PS_ReadSysPara(SysPara *p) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x03); Sendcmd(0x0F); temp = 0x01+0x03+0x0F; SendCheck(temp); data=JudgeStr(2000); if(data) { ensure = data[9]; p->PS_max = (data[14]PS_addr=(data[18]PS_N*9600); } else printf("\r\n%s",EnsureMessage(ensure)); return ensure; } //设置模块地址 PS_SetAddr //功能: 设置模块地址 //参数: PS_addr //说明: 模块返回确认字 u8 PS_SetAddr(u32 PS_addr) { u16 temp; u8 ensure; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(0x07); Sendcmd(0x15); MYUSART_SendData(PS_addr>>24); MYUSART_SendData(PS_addr>>16); MYUSART_SendData(PS_addr>>8); MYUSART_SendData(PS_addr); temp = 0x01+0x07+0x15 +(u8)(PS_addr>>24)+(u8)(PS_addr>>16) +(u8)(PS_addr>>8) +(u8)PS_addr; SendCheck(temp); AS608Addr=PS_addr;//发送完指令,更换地址 data=JudgeStr(2000); if(data) ensure=data[9]; else ensure=0xff; AS608Addr = PS_addr; if(ensure==0x00) printf("\r\n设置地址成功!"); else printf("\r\n%s",EnsureMessage(ensure)); return ensure; } //功能: 模块内部为用户开辟了256bytes的FLASH空间用于存用户记事本, // 该记事本逻辑上被分成 16 个页。 //参数: NotePageNum(0~15),Byte32(要写入内容,32个字节) //说明: 模块返回确认字 u8 PS_WriteNotepad(u8 NotePageNum,u8 *Byte32) { u16 temp; u8 ensure,i; u8 *data; SendHead(); SendAddr(); SendFlag(0x01);//命令包标识 SendLength(36); Sendcmd(0x18); MYUSART_SendData(NotePageNum); for(i=0;i8); MYUSART_SendData(StartPage); MYUSART_SendData(PageNum>>8); MYUSART_SendData(PageNum); temp = 0x01+0x08+0x1b+BufferID +(StartPage>>8)+(u8)StartPage +(PageNum>>8)+(u8)PageNum; SendCheck(temp); data=JudgeStr(2000); if(data) { ensure=data[9]; p->pageID =(data[10]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3