使用STM32驱动AS608指纹模块

一,硬件材料准备:
AS608模块,STM32最小系统等。
二,AS608简介
AS608 指纹识别模块主要是指采用了杭州晟元芯片技术有限公司(Synochip)的 AS608 指纹识别芯片而做成的指纹模块。指纹模块供电为3.3V,切记请勿使用5V供电,模块会烧坏!
模块引脚定义:
在这里插入图片描述
在这里插入图片描述
模块实物图:
在这里插入图片描述
1,模块口令与地址
指纹模块系统默认口令为 0,芯片的默认地址为 0Xffffffff,可通过指令修改,数据包的地址域必须与该地址相配,命令包/数据包才被系统接收。
2,系统资源
2.1.缓冲区与指纹库
系统内设有一个 72K 字节的图像缓冲区与二个 512bytes 大小的特征文件缓冲区,名字分别称为:ImageBuffer,CharBuffer1 和 CharBuffer2。用户可以通过指令读写任意一个缓冲区。CharBuffer1 或 CharBuffer2 既可以用于存放普通特征文件也可以用于存放模板特征文件。指纹库容量根据挂接的 FLASH 容量不同而改变,系统会自动判别。指纹模板按照序号存放,序号定义为:0—(N-1)(N 为指纹库容量)。用户只能根据序号访问指纹库内容。
2.2用户记事本
系统在 FLASH 中开辟了一个 512 字节的存储区域作为用户记事本,该记事本逻辑上被分成 16 页,每页 32 字节。上位机可以通过 PS_WriteNotepad 指令和 PS_ReadNotepad 指令访问任意一页。注意写记事本某一页的时候,该页 32 字节的内容被整体写入,原来的内容被覆盖。
2.3.随机数产生器
系统内部集成了硬件 32 位随机数生成器(不需要随机数种子),用户可以通过指令让模块产生一个随机数并上传给上位机。

3
指令格式如下:
在这里插入图片描述
注:包长度=包长度至校验和(指令、参数或数据)的总字节数,包含校验和,但
不包含包长度本身的字节数。 校验和是从包标识至校验和之间所有字节之和。
模块应答格式:
在这里插入图片描述

确认码定义:
00H:表示指令执行完毕或 OK;
01H:表示数据包接收错误;
02H:表示传感器上没有手指;
03H:表示录入指纹图像失败;
04H:表示指纹图像太干、太淡而生不成特征;
05H:表示指纹图像太湿、太糊而生不成特征;
06H:表示指纹图像太乱而生不成特征;
07H:表示指纹图像正常,但特征点太少(或面积太小)而生不成特征;
08H:表示指纹不匹配;
09H:表示没搜索到指纹;
0aH:表示特征合并失败;
0bH:表示访问指纹库时地址序号超出指纹库范围;
0cH:表示从指纹库读模板出错或无效;
0dH:表示上传特征失败;
0eH:表示模块不能接受后续数据包;
0fH:表示上传图像失败;
10H:表示删除模板失败;
11H:表示清空指纹库失败;
13H:表示口令不正确;
15H:表示缓冲区内没有有效原始图而生不成图像;
18H:表示读写 FLASH 出错;
19H:未定义错误;
1aH:无效寄存器号;
1bH:寄存器设定内容错误号;
1cH:记事本页码指定错误;
1dH:端口操作失败;
1eH:自动注册(enroll)失败;
1fH:指纹库满
29. 20—efH:Reserved。

4,开发指南
4.1.模块地址(大小:4bytes,属性:读写)
模块的默认地址为0xFFFFFFFF,可通过指令修改,数据包的地址域必须与该地址相配,命令包/数据包才被系统接收。注:与上位机通讯必须是默认地址0xFFFFFFFF!
4.2.模块口令(大小:4bytes,属性:写)
系统默认口令为 0,可通过指令修改。若默认口令未被修改,则系统不要求验证口令,上位机和 MCU 与芯片通讯;若口令被修改,则上位机与芯片通讯的第一个指令必须是验证口令,只有口令验证通过后,芯片才接收其它指令。
4.3.数据包大小设置(大小:1bytes,属性:读写)
发送数据包和接收数据包的长度根据该值设定。
4.4波特率系数 N 设置(大小:1bytes,属性:读写)
USART 波特率=N×9600,N=1~12。
4.5安全等级 level 设置(大小:1bytes,属性:读写)
系统根据安全等级设定比对阀值,level=1~5。安全等级为 1 时认假率最高,拒认率最低。安全等级为 5 时认假率最低,拒认率最高。
三,AS608指令详解
在这里插入图片描述

确认码=00H 表示录入成功; 
确认码=01H 表示收包有错; 
确认码=02H 表示传感器上无手指; 
确认码=03H 表示录入不成功; 
sum 指校验和

在这里插入图片描述

确认码=00H 表示生成特征成功; 
确认码=01H 表示收包有错; 
确认码=06H 表示指纹图像太乱而生不成特征;
确认码=07H 表示指纹图像正常,但特征点太少而生不成特征; 
确认码=15H 表示图像缓冲区内没有有效原始图而生不成图像; 
sum 指校验和

在这里插入图片描述

确认码=00H 表示指纹匹配; 
确认码=01H 表示收包有错; 
确认码=08H 表示指纹不匹配; 
sum 指校验和

在这里插入图片描述

确认码=00H 表示搜索到; 
确认码=01H 表示收包有错; 
确认码=09H 表示没搜索到;此时页码与得分为 0 
sum 指校验和

在这里插入图片描述

确认码=00H 表示合并成功; 
确认码=01H 表示收包有错; 
确认码=0aH 表示合并失败(两枚指纹不属于同一手指); 
sum 指校验和

在这里插入图片描述

确认码=00H 表示储存成功; 
确认码=01H 表示收包有错; 
确认码=0bH 表示 PageID 超出指纹库范围; 
确认码=18H 表示写 FLASH 出错; 
sum 指校验和

⑺ 读出模板 PS_LoadChar
功能说明: 将 flash 数据库中指定 ID 号的指纹模板读入到模板缓冲
区 CharBuffer1 或 CharBuffer2
输入参数: BufferID(缓冲区号),PageID(指纹库模板号)
返回参数: 确认字
指令代码: 07H
在这里插入图片描述
在这里插入图片描述

确认码=00H 表示随后发数据包; 
确认码=01H 表示收包有错; 
确认码=0dH 表示指令执行失败; 
sum 指校验和 
应答之后发送后续数据包

⑼ 下载特征或模板 PS_DownChar
功能说明: 上位机下载特征文件到模块的一个特征缓冲区
输入参数: BufferID(缓冲区号)
返回参数: 确认字
指令代码: 09H
在这里插入图片描述

在这里插入图片描述

确认码=00H 表示接着发送后续数据包; 
确认码=01H 表示收包有错; 
确认码=0fH 表示不能发送后续数据包; 
sum 指校验和 
应答之后发送后续数据包 
UART 通讯一个字节含两个像素,每个像素占 4bits

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

确认码=00H 表示清空成功; 
确认码=01H 表示收包有错; 
确认码=11H 表示清空失败; 
sum 指校验和

在这里插入图片描述

确认码=00H 表示 OK; 
确认码=01H 表示收包有错; 
确认码=1aH 表示寄存器序号有误; 
sum 指校验和 
注:写系统寄存器(PS_WriteReg)指令执行时,先按照原配置进行应答,应
答之后修改系统设置,并将配置记录于 FLASH,系统下次上电后,将按照
新的配置工作。

⒂ 读系统基本参数 PS_ReadSysPara
功能说明:
读取模块的基本参数(波特率,包大小等)。
参数表前 16 个字节存放了模块的基本通讯和配置信息,称为模块的基本
参数
输入参数: none
返回参数: 确认字 + 基本参数(16bytes)
指令代码: 0fH
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(23) 端口控制 PS_Port_Control
功能说明:
在这里插入图片描述
在这里插入图片描述
(25) 读记事本 PS_ReadNotepad
功能说明: 读取 FLASH 用户区的 128bytes 数据
输入参数: none
返回参数: 确认字 + 用户信息
在这里插入图片描述
在这里插入图片描述
(27) 高速搜索 PS_HighSpeedSearch
功能说明:
以 CharBuffer1 或 CharBuffer2 中的特征文件高速搜索整个或部分指纹
库。若搜索到,则返回页码。
该指令对于的确存在于指纹库中,且登录时质量很好的指纹,会很快给
出搜索结果。
输入参数: BufferID, StartPage(起始页),PageNum(页数)
返回参数: 确认字,页码(相配指纹模板)
在这里插入图片描述
在这里插入图片描述
(29) 读有效模板个数 PS_ValidTempleteNum
功能说明: 读有效模板个数
输入参数: none
返回参数: 确认字,有效模板个数 ValidN
指令代码: 1dH
指令包格式:
在这里插入图片描述
在这里插入图片描述
(31) 读索引表 PS_ReadIndexTable(保留)
功能说明:读取录入模版的索引表。
输入参数: 索引表页码, 页码 0,1,2,3 分别对应模版从 0-256,256-512,
512-768,768-1024 的索引,每 1 位代表一个模版,1 表示对应存储区域
的模版已经录入,0 表示没录入。
返回参数:确认字 + 索引表信息
指令代码: 1FH
指令包格式:
在这里插入图片描述
在这里插入图片描述
(以上指令摘自芯片手册)
四程序源码:
(先以串口打印数据进行测试)
main.c部分函数:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include <string.h>
#include "delay.h" 	
#include "usart2.h"
#include "as608.h"
#include "key.h"
#include "beep.h"

#define usart2_baund  57600//串口2波特率,根据指纹模块波特率更改
#define usart1_baund  115200//串口1波特率

SysPara AS608Para;//指纹模块AS608参数

u16 flag;

void Add_FR(void);
void Del_FR(u8 num);
void Menu(void);
void press_FR(void);//刷指纹	

int main(void)
{	
	u8 keyvalue;
	delay_init_LDQ();	    //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组
	uart_init(usart1_baund);	//串口初始化为115200   
	
	PS_StaGPIO_Init();
	usart2_init(usart2_baund);
	KEY_Init();
	BEEP_Init();
	while(PS_HandShake(&AS608Addr))//与AS608模块握手
	{
		delay_ms(1000);  
		printf("未检测到指纹模块!!!\r\n");
		printf("尝试连接指纹模块!!!\r\n");
		delay_ms(1000);  	
	}
	
	printf("连接指纹模块成功!!!\r\n");
	AS608Para.flag=PS_ValidTempleteNum(&AS608Para.ValidN);//读库指纹个数
	AS608Para.id_update=AS608Para.ValidN;
	printf("flag= %d\r\n",flag);
	printf(" %d\r\n",AS608Para.flag);
	AS608Para.flag=PS_ReadSysPara(&AS608Para);  //读参数 
	printf(" %d\r\n",AS608Para.flag);
	Menu();
	delay_ms(1000);
	
	while(1)
	{
		Menu();
		
		keyvalue=KEY_Scan(1);
		if(keyvalue==1)
		{
			Add_FR();		//录指纹		
		}
		else if((keyvalue==2)||(keyvalue==3))
		{
			Del_FR(keyvalue);		//删指纹
		}
		if(PS_Sta)	 //检测PS_Sta状态,如果有手指按下
		{
			press_FR();//刷指纹			
		}	
	}
}

void Menu(void)
{
	static vu16 flag1=0;
	if(flag1==2000)
	{
		flag=0;
		printf("请选择功能:\r\n");
		delay_ms(10);
		printf("1:录入指纹\r\n");
		delay_ms(10);
		printf("2:删除指纹\r\n");
		delay_ms(10);
		printf("3:匹配指纹\r\n");
		delay_ms(10);
		printf("4:清空指纹库\r\n");	
		delay_ms(10);
		printf("5:进入正常功能模式:\r\n");
	}
	flag1++;
	delay_ms(1);
}

void ShowErrMessage(u8 infor)
{
	printf("模块返回信息: \" %s\"\r\n",EnsureMessage(infor));
	delay_ms(2);
}

void Normal_Function(void)
{
	printf("请验证指纹!!\r\n");
	Normal_Function_Menu();
	
}
//录指纹
void Add_FR(void)
{
	u8 i,ensure,processnum=0;
	u16 ID;
	while(1)
	{
		switch (processnum)
		{
			case 0:
				i++;	
				printf("请按指纹:\r\n");
				ensure=PS_GetImage();
				if(ensure==0x00) 
				{
					BEEP=1;
					ensure=PS_GenChar(CharBuffer1);//生成特征
					BEEP=0;
					if(ensure==0x00)
					{
						printf("指纹正常\r\n");
						i=0;
						processnum=1;//跳到第二步						
					}
					else
						ShowErrMessage(ensure);				
				}
				else; 
					ShowErrMessage(ensure);						
				break;
			
			case 1:
				i++;
			
				printf("请按再按一次指纹\r\n");
				ensure=PS_GetImage();
				if(ensure==0x00) 
				{
					BEEP=1;
					ensure=PS_GenChar(CharBuffer2);//生成特征
					BEEP=0;
					if(ensure==0x00)
					{
						printf("指纹正常\r\n");
						i=0;
						processnum=2;//跳到第三步
					}
					else 
						ShowErrMessage(ensure);	
				}
				else 
					ShowErrMessage(ensure);		
				break;

			case 2:			
				printf("对比两次指纹\r\n");
				ensure=PS_Match();
				if(ensure==0x00) 
				{			
					printf("对比成功,两次指纹一样\r\n");
					processnum=3;//跳到第四步
				}
				else 
				{			
					printf("对比失败,请重新录入指纹\r\n");
					ShowErrMessage(ensure);
					i=0;
					processnum=0;//跳回第一步		
				}
				delay_ms(1200);
				break;

			case 3:		
				printf("生成指纹模板\r\n");
				ensure=PS_RegModel();
				if(ensure==0x00) 
				{	
					printf("生成指纹模板成功\r\n");
					processnum=4;//跳到第五步
				}
				else 
				{
					processnum=0;
					ShowErrMessage(ensure);
				}
				delay_ms(1200);
				break;
				
			case 4:	
				ID=AS608Para.id_update;
				if(ID>299)
					ID=0;
				printf("自动设置ID= %d \r\n",ID);
				while(!(ID<AS608Para.PS_max));//输入ID必须小于指纹容量的最大值	
				ensure=PS_StoreChar(CharBuffer2,ID);//储存模板
				if(ensure==0x00) 
				{			
					printf("录入指纹成功\r\n");
					ensure=PS_ValidTempleteNum(&AS608Para.ValidN);//读库指纹个数
					AS608Para.id_update=AS608Para.ValidN;
					printf("下一次ID为: %d\r\n",AS608Para.id_update);
					delay_ms(1500);
					return ;
				}
				else 
				{
					processnum=0;
					ShowErrMessage(ensure);
				}					
				break;				
		}
		delay_ms(1000);
		if(i==5)//超过5次没有按手指则退出
		{
			printf("没有手指按下,已自动取消录指纹操作!!!\r\n");
			delay_ms(100);
			break;	
		}				
	}
}

//刷指纹
void press_FR(void)
{
	SearchResult seach;
	u8 ensure;
	ensure=PS_GetImage();
	if(ensure==0x00)//获取图像成功 
	{	
		BEEP=1;//打开蜂鸣器	
		ensure=PS_GenChar(CharBuffer1);
		if(ensure==0x00) //生成特征成功
		{		
			BEEP=0;//关闭蜂鸣器	
			ensure=PS_HighSpeedSearch(CharBuffer1,0,AS608Para.PS_max,&seach);
			if(ensure==0x00)//搜索成功
			{				
				printf("刷指纹成功\r\n");	
			}
			else 
				ShowErrMessage(ensure);					
	  }
		else
			ShowErrMessage(ensure);
	 BEEP=0;//关闭蜂鸣器
	 delay_ms(600);
	}
		
}

//删除指纹
void Del_FR(u8 num)
{
	static u16 delNum=0;
	static u8 delFlag=0;
	static u8 finish=0;
	u8 ensure;
	
	printf("即将删除指纹!!!\r\n");
	delay_ms(50);
	if(num==2)
	{
		printf("是否清除指纹库?请再次按相同键清除!!\r\n");
		delay_ms(10);
		while(1)
		{
			if(KEY_Scan(1)==2)
			{
				delay_ms(10);
				if(KEY1==0) 
				{
					ensure=PS_Empty();//清空指纹库
					printf("已清除指纹库!!!\r\n");
					return ;
				}
			}
			else if(KEY_Scan(1)==1)
			{
				delay_ms(10);
				if(KEY0==0) 
				{					
					printf("取消清除指纹库!!!\r\n");
					return ;
				}
			}
			else;
			delay_ms(1000);
		}
	}
	else if(num==3)
	{
		while(!finish)
		{
			delFlag=KEY_Scan(1);
			switch(delFlag)
			{
L1:			    case 1:
					if(delNum<299)
						delNum++;//删除id+=1的指纹
					else
						delNum=299;
					printf("id=%d\r\n",delNum);
					break;
				case 2:
					if(delNum<290)
						delNum+=10;//删除id+=10的指纹break;
					else
						goto L1;
					printf("id=%d\r\n",delNum);
					break;
				case 3:
					if(delNum>0)
						delNum--;//删除id-=1的指纹
					else
						delNum=0;
					printf("id=%d\r\n",delNum);
					break;
				case 4:
					finish=1;
	//				if(delNum>=10)
	//					delNum-=10;//删除id-=10的指纹
	//				else
	//					delNum=0; //删除id=0的指纹
					break;
				default:delNum=0;break;
			}
		}
		ensure=PS_DeletChar(delNum,1);//删除单个指纹
		delNum=0;
	}
	else
	{
		printf("非法按键!!!\r\n");
		return ;
	}
	if(AS608Para.flag==0)
	{
		printf("删除指纹成功\r\n");	
	}
	else
		ShowErrMessage(ensure);	
	PS_ValidTempleteNum(&AS608Para.ValidN);//读库指纹个数
	delay_ms(50);
}

AS608头文件部分

#ifndef __AS608_H
#define __AS608_H

#include <stdio.h>
#include "stm32f10x.h" 

#define PS_Sta   PAin(6)//读指纹模块状态引脚
#define CharBuffer1 0x01
#define CharBuffer2 0x02

extern u32 AS608Addr;//模块地址

typedef struct  
{
	u16 pageID;//指纹ID
	u16 mathscore;//匹配得分
}SearchResult;

typedef struct
{
	u16 PS_max;		//指纹最大容量
	u8  PS_level;	//安全等级
	u32 PS_addr;
	u8  PS_size;	//通讯数据包大小
	u8  PS_N;		//波特率基数N
	u16 id_update;	//存储id值
	u8  flag;       //执行成功标志
	u16 ValidN;		//模块内有效指纹个数
}SysPara;
void PS_StaGPIO_Init(void);//初始化PA6读状态引脚	
u8 PS_GetImage(void); //录入图像  
u8 PS_GenChar(u8 BufferID);//生成特征 
u8 PS_Match(void);//精确比对两枚指纹特征 
u8 PS_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p);//搜索指纹  
u8 PS_RegModel(void);//合并特征(生成模板)  
u8 PS_StoreChar(u8 BufferID,u16 PageID);//储存模板 
u8 PS_DeletChar(u16 PageID,u16 N);//删除模板 
u8 PS_Empty(void);//清空指纹库   
u8 PS_ValidTempleteNum(u16 *ValidN);//读有效模板个数 
u8 PS_HandShake(u32 *PS_Addr); //与AS608模块握手
const char *EnsureMessage(u8 ensure);//确认码错误信息解析
void Normal_Function_Menu(void);
#endif

发布了17 篇原创文章 · 获赞 12 · 访问量 3892

猜你喜欢

转载自blog.csdn.net/liuxianfei0810/article/details/105297109