一,硬件材料准备:
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
#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
#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