最近用STM32F103做一个智能门锁小玩意,其中用到指纹模块,我这里也单独的写一下笔记,不过我只是了解了基本的,就是我做门禁卡要用到的几个东西,其它还没了解。为了方便,做一下记录。我这里没有用到按键和显示屏,所以还是串口输出输入来控制了 哈哈哈哈
一: 基本介绍
这里就写一下我这次用到的而且觉得是重点的东西吧 毕竟手册还是内容很多的
AS608引脚描述
这里就留意前6个 其中WAK这个引脚 是可以检测手指是否按下的 当有手指按下 WAK引脚是输出高电平 没有手指则维持低电平
AS608模块地址
默认是 0XFFFFFFFF(共4个字节)
我这里就不改了,按默认的了。修改的话请看手册
AS608波特率
默认是57600
我这里也懒得改了,按默认了。修改的话请看手册
AS608指令格式
模块指令格式分为三种,命令包、数据包、结束包。如下图
AS608应答格式
正常是通过检测确认码来确定数据的反馈
比如:
0X00: OK
0X01: 数据包接收错误
0X02: 传感器没有手指
…
手册都有说。这里也就不细发了。
二: 指令集
指令集很多,很多,但是我这里就写一下我这次做门禁卡系统用到的一些指令集。最终能实现 增加指纹、删除指纹、验证指纹。
1.读取图像-PS_GetImage
功能: 读取指纹图像,然后把图像存放于ImageBuffer中。
参数: 无
返回: 确认字
指令代码: 01H
简述:
首先我们通过指令码包给AS608指纹模块让它读取图像,然后指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0003 (2个字节)
5、发送指令码: 0X01 (1个字节)
6、发送校验和: 0X0005 (2个字节)
包长度如何计算的?
我们可以看出来嘛 包长度这个表格是说3个。那么我看后面确实还剩3个字节。1字节的指令码+2字节的校验和 = 3字节。
结论:包长度: 提示了后面还有多少个字节数据
校验和如何计算的?
我们同样也可以看出来 它的校验和是说是5。那么我们很容易发现,校验和其实是 从 包标识 0x01 + 包长度 0x0003 + 指令码 0x01 = 5。
结论:校验和 = 包标识开始 + … 到校验和 但不含校验和。
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0003 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 录入成功
01H: 收包有误
02H: 没有检测到手指
03H: 录入不成功
SUM(校验和)
2.生成特征-PS_GenChar
功能: 将ImageBuffer中的原始图像生成指纹特征存放CharBuffer1 或者 CharBuffer2。
参数: BufferID(特征缓冲区号) CharBuffer1:01H CharBuffer2:02H
返回: 确认字
指令代码: 02H
简述:
首先我们通过指令码包给AS608指纹模块让它读取图像后如果读取到图像,然后我们发送生成特征指令包,然后指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0004 (2个字节)
5、发送指令码: 0X02 (1个字节)
6、发送缓冲区号: 0x01/0X02 (1个字节)
7、发送校验和: SUM (2个字节)
SUM(校验和的计算):
校验和 = 包标识 + 包长度 + 指令码 + 缓冲区号(BufferID)。
1:当你发送的缓冲区号是0x01时: 校验和 = 0x08
0x01 + 0x0004 + 0x02 + 0x01 = 0x08
2:当你发送的缓冲区号是0x02时: 校验和 = 0x09
0x01 + 0x0004 + 0x02 + 0x02 = 0x09
包长度如何计算的?
我们可以看出来嘛 包长度这个表格是说3个。那么我看后面确实还剩3个字节。1字节的指令码+2字节的校验和 = 3字节。
结论:包长度: 提示了后面还有多少个字节数据
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0003 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 生成特征成功
01H: 收包有误
06H: 指纹太乱
07H: 特征点太少
15H: 没有图像生成
SUM(校验和)
3.比对特征-PS_Match
功能: 将CharBuffer1 和 CharBuffer2 的特征文件比对。
参数: 无
返回: 确认字,对比得分
指令代码: 03H
简述:
首先我们通过指令码包给AS608指纹模块让它对比然后CharBuffer1 和 CharBuffer2 的特征文件,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0003 (2个字节)
5、发送指令码: 0X03 (1个字节)
6、发送校验和: 0X07 (2个字节)
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0003 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 指纹匹配成功
01H: 收包有误
08H: 指纹不匹配
SUM(校验和)
4.生成模板-PS_RegModel
功能: 将CharBuffer1 和 CharBuffer2 的特征文件合并生成模板,结果存放在CharBuffer1 与 CharBuffer2
参数: 无
返回: 确认字
指令代码: 05H
简述:
首先我们通过指令码包给AS608指纹模块让它将CharBuffer1 和 CharBuffer2 的特征文件合并生成模板,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0003 (2个字节)
5、发送指令码: 0X05 (1个字节)
6、发送校验和: 0X09 (2个字节)
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0003 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 合并成功
01H: 收包有误
0AH: 合并失败(不是同一个手指)
SUM(校验和)
5.储存模板-PS_StoreChar
功能: 将CharBuffer1 和 CharBuffer2 的模板文件,存放到PageID号flash数据库位置
参数: BufferID(缓冲区号 0x01/0x02),PageID(指纹库位置号)
返回: 确认字
指令代码: 06H
简述:
首先我们通过指令码包给AS608指纹模块让它将CharBuffer1 和 CharBuffer2 生成的模板进行储存模板,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0006 (2个字节)
5、发送指令码: 0X06 (1个字节)
6、发送缓冲区号: BufferID (1个字节)
7、发送位置号: PageID (2个字节)
7、发送校验和: SUM (2个字节)
SUM(校验和) = 包标识+包长度+指令码+BufferID+PageID;
SUM(校验和) = 0X01+0X06+0X06+BufferID+PageID;
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0003 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 储存模板成功
01H: 收包有误
0BH: PageID超出指纹库范围
18H: 写FLASH出错
SUM(校验和)
你都看到这里了,那么你添加指纹的操作就可以完成了。
6.删除模板-PS_DeletChar
功能: 删除flash数据库中指定ID号开始的N个指纹模板。
参数: PageID(指纹库模板号),N(删除的模板个数)
返回: 确认字
指令代码: 0CH
简述:
首先我们通过指令码包给AS608指纹模块让它删除模板,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0007 (2个字节)
5、发送指令码: 0X0C (1个字节)
6、发送位置号: PageID (2个字节)
7、发送删除个数: N (2个字节)
7、发送校验和: SUM (2个字节)
SUM(校验和) = 包标识+包长度+指令码+PageID+N;
SUM(校验和) = 0X01+0X07+0X0C+PageID+N;
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0003 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 删除模板成功
01H: 收包有误
10H: 删除模板失败
SUM(校验和)
7.清空指纹库-PS_Empty
功能: 删除flash数据库所有指纹模板
参数: 无
返回: 确认字
指令代码: 0DH
简述:
首先我们通过指令码包给AS608指纹模块让它清空所有模板,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0003 (2个字节)
5、发送指令码: 0X0D (1个字节)
6、发送校验和: 0X0011 (2个字节)
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0003 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 清空所有成功
01H: 收包有误
10H: 清空所有失败
SUM(校验和)
你都看到这里了,那么你删除指纹的操作就可以完成了。
8.高速搜索指纹-PS_HighSpeedSearch
功能: 以CharBuffer1 或 CharBuffer2中的特征文件高速搜索整个或部分指纹库。如果搜索到,返回页码。
参数: BufferID(0x01/0x02),StartPage(起始页),PageNum(页数)
返回: 确认字,页码(匹配的指纹模板)
指令代码: 1BH
简述:
首先我们通过指令码包给AS608指纹模块让它高速搜索是否和咱这个指纹一样,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0008 (2个字节)
5、发送指令码: 0X1B (1个字节)
6、发送缓冲区号: BufferID (1个字节)
7、发送起始页: StartPage (2个字节)
7、发送页数: PageNum (2个字节)
7、发送校验和: SUM (2个字节)
StartPage(起始页):开始搜索的页码
PageNum(页数): 搜索多少页
SUM(校验和) = 包标识+包长度+指令码+BufferID+StartPage+PageNum;
SUM(校验和) = 0x01+0x08+0x1B+BufferID+StartPage+PageNum;
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0007 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到页码: PageID (2个字节)
7、接收到得分: MatchScore (2个字节)
8、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 搜索到
01H: 收包有误
09H: 没有搜索到 页码和得分也会是 0
SUM(校验和)
9.搜索指纹-PS_Search
功能: 以CharBuffer1 或 CharBuffer2中的特征文件搜索整个或部分指纹库。如果搜索到,返回页码。
参数: BufferID(0x01/0x02),StartPage(起始页),PageNum(页数)
返回: 确认字,页码(匹配的指纹模板)
指令代码: 04H
简述:
首先我们通过指令码包给AS608指纹模块让它搜索是否和咱这个指纹一样,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0008 (2个字节)
5、发送指令码: 0X04 (1个字节)
6、发送缓冲区号: BufferID (1个字节)
7、发送起始页: StartPage (2个字节)
7、发送页数: PageNum (2个字节)
7、发送校验和: SUM (2个字节)
StartPage(起始页):开始搜索的页码
PageNum(页数): 搜索多少页
SUM(校验和) = 包标识+包长度+指令码+BufferID+StartPage+PageNum;
SUM(校验和) = 0x01+0x08+0x04+BufferID+StartPage+PageNum;
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0007 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到页码: PageID (2个字节)
7、接收到得分: MatchScore (2个字节)
8、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 搜索到
01H: 收包有误
09H: 没有搜索到 页码和得分也会是 0
SUM(校验和)
这两个都是搜索。。一个高速一个不是 我估计就是高速更快,但是估计没不高速那个那么精确吧。个人感觉。
你都看到这里了,那么你验证指纹的操作就可以完成了。
10.查有效模板个数-PS_ValidTempleteNum
功能: 读取有效模板个数(查询当前一共有多少个指纹)
参数: 无
返回: 确认字,有效模板个数ValidN
指令代码: 1DH
简述:
首先我们通过指令码包给AS608指纹模块让它清空所有模板,指纹模块会返回应答包给我们。我们通过应答包的确认字去判断这次的结果。
指令包格式:
首先我们是我们给指纹模块发送的内容 可以结合上图指令包格式
1、发送包头: 0XEF01 (2个字节)
2、发送芯片地址: 0XFFFFFFFF (4个字节)
3、发送包标识: 0X01 (1个字节)
4、发送包长度: 0X0003 (2个字节)
5、发送指令码: 0X1D (1个字节)
6、发送校验和: 0X0021 (2个字节)
应答包格式
发送完指令包给指纹模块 我们则会收到它发的应答包 可以结合上图应答包格式
1、接收到包头: 0XEF01 (2个字节)
2、接收到芯片地址 0XFFFFFFFF (4个字节)
3、接收到包标识: 0X07 (1个字节)
4、接收到包长度: 0X0005 (2个字节)
5、接收到确认码: xxH (1个字节)
6、接收到模板数: ValidN (2个字节)
7、接收到校验和: SUM (2个字节)
xxH(确认码):
00H: 读取成功
01H: 收包有误
SUM(校验和)
你都看到这里了,那么你查询当前有多少个指纹就可以完成了。
11.关于包长度和校验和
指令包格式:
包长度如何计算的?
我们可以看出来嘛 包长度这个表格是说3个。那么我看后面确实还剩3个字节。1字节的指令码+2字节的校验和 = 3字节。
结论:包长度: 提示了后面还有多少个字节数据
校验和如何计算的?
我们同样也可以看出来 它的校验和是说是5。那么我们很容易发现,校验和其实是 从 包标识 0x01 + 包长度 0x0003 + 指令码 0x01 = 5。
结论:校验和 = 包标识开始 + … 到校验和 但不含校验和。
三: 编写指令集代码
0.预代码
看到这里了你也知道了发送指令包其实很多都是一样的,比如发送包头,发送芯片地址…等。我们现在打包成一个个函数。这样方便我们后面编写各个功能指令函数。
预定义:
#define CharBuffer1 0x01
#define CharBuffer2 0x02
uint16_t AS608_HEAD = 0XEF01; //包头
uint32_t AS608_ADDR = 0XFFFFFFFF; //芯片地址
然后下面就是一些打包的函数
/***************************************************************************
描述: 发送包头
****************************************************************************/
static void as608_send_head(void)
{
USART2_SendData(AS608_HEAD>>8);
USART2_SendData(AS608_HEAD);
}
/***************************************************************************
描述: 发送芯片地址
****************************************************************************/
static void as608_send_address(void)
{
USART2_SendData(AS608_ADDR>>24);
USART2_SendData(AS608_ADDR>>16);
USART2_SendData(AS608_ADDR>>8);
USART2_SendData(AS608_ADDR);
}
/***************************************************************************
描述: 发送包标识
****************************************************************************/
static void as608_send_logo(uint8_t logo)
{
USART2_SendData(logo);
}
/***************************************************************************
描述: 发送包长度
****************************************************************************/
static void as608_send_length(uint16_t length)
{
USART2_SendData(length>>8);
USART2_SendData(length);
}
/***************************************************************************
描述: 发送指令码
****************************************************************************/
static void as608_send_cmd(uint8_t cmd)
{
USART2_SendData(cmd);
}
/***************************************************************************
描述: 发送校验和
****************************************************************************/
static void as608_send_checksum(uint16_t checksum)
{
USART2_SendData(checksum>>8);
USART2_SendData(checksum);
}
/***************************************************************************
描述: 发送BufferID
****************************************************************************/
static void as608_send_BufferID(uint8_t BufferID)
{
USART2_SendData(BufferID);
}
/***************************************************************************
描述: 发送StartPage
****************************************************************************/
static void as608_send_StartPage(uint16_t StartPage)
{
USART2_SendData(StartPage>>8);
USART2_SendData(StartPage);
}
/***************************************************************************
描述: 发送PageNum
****************************************************************************/
static void as608_send_PageNum(uint16_t PageNum)
{
USART2_SendData(PageNum>>8);
USART2_SendData(PageNum);
}
/***************************************************************************
描述: 发送PageID号
****************************************************************************/
static void as608_send_PageID(uint16_t PageID)
{
USART2_SendData(PageID>>8);
USART2_SendData(PageID);
}
/***************************************************************************
描述: 发送个数
****************************************************************************/
static void as608_send_N(uint16_t N)
{
USART2_SendData(N>>8);
USART2_SendData(N);
}
好了封装了一下 这下子就方便多了
1.读取图像-PS_GetImage
/***************************************************************************
描述: 获取手指指纹图像 存放于图像缓冲区
参数: 无 指令代码:02H
返回: 00H: 录入指纹成功 01H:收包错误 02H:无手指 03H:录入不成功
****************************************************************************/
uint8_t PS_GetImage(void)
{
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x03); //发送包长度
as608_send_cmd(0x01); //发送指令码
as608_send_checksum(0x05); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,NULL); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
2.生成特征-PS_GenChar
/***************************************************************************
描述: 生成特征
参数: BufferID(特征缓冲区号) 指令代码:02H
CharBuffer1 的 BufferID: 01H CharBuffer2的 BufferID: 02H
返回: 00H: 生成特征成功 01H:收包错误 06H:指纹图像太乱生成失败
07H: 特征太少 15H:图像缓冲区没图像
****************************************************************************/
uint8_t PS_GenChar(uint8_t BufferID)
{
uint16_t checksum; //存放校验和
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x04); //发送包长度
as608_send_cmd(0x02); //发送指令码
as608_send_BufferID(BufferID); //发送BufferID
checksum = 0x01 + 0x04 + 0x02 + BufferID;
as608_send_checksum(checksum); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,NULL); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
3.比对特征-PS_Match
/***************************************************************************
描述: 精确比对两枚指纹特征
参数: 无 指令代码:03H
返回: 00H: 指纹匹配成功 08H:指纹不匹配 01H:收包错误
****************************************************************************/
uint8_t PS_Match(void)
{
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x03); //发送包长度
as608_send_cmd(0x03); //发送指令码
as608_send_checksum(0x07); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,NULL); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
4.生成模板-PS_RegModel
/***************************************************************************
描述: 合并特征 将CharBuffer1 和 CharBuffer2 中的 特征合并生成模板
结果存在CharBuffer1 和 CharBuffer2
参数: 无 指令代码:05H
返回: 00H: 合并成功 01H:收包错误 0AH:合并失败(两枚手指不是同一个)
****************************************************************************/
uint8_t PS_RegModel(void)
{
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x03); //发送包长度
as608_send_cmd(0x05); //发送指令码
as608_send_checksum(0x09); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,NULL); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
5.储存模板-PS_StoreChar
/***************************************************************************
描述: 储存模板 将CharBuffer1和CharBuffer2的模板文件存到PageID号Flash数据库位置
参数: BufferID: 01H/02H PageID:指纹库位置号 指令代码:06H
返回: 00H: 储存成功 01H:收包错误 0BH:PageID超出指纹库范围 18H:写Flash出错
****************************************************************************/
uint8_t PS_StoreChar(uint8_t BufferID,uint16_t PageID)
{
uint16_t checksum; //存放校验和
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x06); //发送包长度
as608_send_cmd(0x06); //发送指令码
as608_send_BufferID(BufferID); //发送BufferID
as608_send_PageID(PageID); //发送指纹库位置号
checksum = 0x01+0x06+0x06+BufferID+PageID;
as608_send_checksum(checksum); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,0); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
6.删除模板-PS_DeletChar
/***************************************************************************
描述: 删除模板 删除Flash数据库中指定的ID号开始的N个指纹模板
参数: PageID:指纹库模板号 N:删除的模板个数 指令代码:0CH
返回: 00H: 删除模板成功 01H:收包错误 10H:删除模板失败
****************************************************************************/
uint8_t PS_DeletChar(uint16_t PageID,uint16_t N)
{
uint16_t checksum; //存放校验和
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x07); //发送包长度
as608_send_cmd(0x0C); //发送指令码
as608_send_PageID(PageID); //发送指纹库位置号
as608_send_N(N); //发送删除模板的个数
checksum = 0x01+0x07+0x0C+PageID+N;
as608_send_checksum(checksum); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,NULL); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
7.清空指纹库-PS_Empty
/***************************************************************************
描述: 清空Flash数据库中所有指纹模板
参数: 无 指令代码:0DH
返回: 00H: 清空成功 01H:收包错误 11H:清空失败
****************************************************************************/
uint8_t PS_Empty(void)
{
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x03); //发送包长度
as608_send_cmd(0x0D); //发送指令码
as608_send_checksum(0X11); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,NULL); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
8.高速搜索指纹-PS_HighSpeedSearch
/***************************************************************************
描述: 高速搜索 以CharBuffer1或CharBuffer2的特征文件高速搜索整个或者部分指纹库
参数: BufferID: 01H/02H StartPage:起始页 PageNum:页数 指令代码:1BH
ID: 存放搜索到的指纹ID号 否则为0
返回: 确认字00H: 搜索到 01H:收包错误 09H:没有搜索到(页码就是0) 和 对应页码
****************************************************************************/
uint8_t PS_HighSpeedSearch(uint8_t BufferID,uint16_t StartPage,uint16_t PageNum,uint16_t *ID)
{
uint16_t checksum; //存放校验和
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x08); //发送包长度
as608_send_cmd(0x1B); //发送指令码
as608_send_BufferID(BufferID); //发送BufferID
as608_send_StartPage(StartPage);//发送起始页
as608_send_PageNum(PageNum); //发送页数
checksum = 0x01+0x08+0x1B+BufferID+StartPage+PageNum;
as608_send_checksum(checksum); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,&ID); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
9.搜索指纹-PS_Search
/***************************************************************************
描述: 搜索指纹 指令代码:04H
参数: BufferID: 01H/02H StartPage:起始页 PageNum:页数
ID: 存放搜索到的指纹ID号 否则为0
返回: 00H: 搜索到 09H:没有搜索到 01H:收包错误
****************************************************************************/
uint8_t PS_Search(uint8_t BufferID,uint16_t StartPage,uint16_t PageNum,uint16_t *ID)
{
uint16_t checksum; //存放校验和
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x08); //发送包长度
as608_send_cmd(0x04); //发送指令码
as608_send_BufferID(BufferID); //发送BufferID
as608_send_StartPage(StartPage);//发送起始页
as608_send_PageNum(PageNum); //发送页数
checksum = 0x01+0x08+0x04+BufferID+StartPage+PageNum;
as608_send_checksum(checksum); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,&ID); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
10.查有效模板个数-PS_ValidTempleteNum
/***************************************************************************
描述: 读取模板个数
参数: NUM:个数会保存在NUM中 指令代码:1DH
返回: 00H: 注册成功 01H:收包错误 NUM也会返回
****************************************************************************/
uint8_t PS_ValidTempleteNum(uint16_t *NUM)
{
uint8_t result; //存放结果
CLEAR_BUFFER; //清空缓冲区
as608_send_head(); //发送包头
as608_send_address(); //发送芯片地址
as608_send_logo(0x01); //发送包标识
as608_send_length(0x03); //发送包长度
as608_send_cmd(0x1D); //发送指令码
as608_send_checksum(0X21); //发送校验和
OPEN_USART2_RECEIVE; //开启串口接收
result = as608_detection_data(300,&NUM); //检测指纹模块数据 3秒时间
if(result == 0XFF) result = 0x01;
return result;
}
三: 指纹代码编写
0.接收处理
我思路是这样的 返回的指令包都有一个固定的格式的,我们通过是否和这个固定的格式匹配,如果匹配再进行下一步,为了数据准确性,我这里还校验一下这个校验和,如果是找到这个数据格式头,但是校验和是错的,那数据也是有问题的。
第一步:匹配固定数据格式
第二步:校验和验证
第三步:返回确认码(如果有ID,或者模板个数,则需要传变量过去进行存放)
匹配固定数据格式
/***************************************************************************
描述: 检测串口返回的数据
参数: wait_time:等待的时间 一次:10ms
ID_OR_NUM: 如果不是搜索指令或者查找模板个数设置为NULL 否则存放ID号或者NUM个数
返回: 无效数据返回0XFF 否则返回结果
****************************************************************************/
uint8_t as608_detection_data(uint16_t wait_time,uint16_t **ID_OR_NUM)
{
char *data;
uint8_t result = 0XFF; //存放结果
while(wait_time--)
{
delay_ms(10);
//匹配数据帧头
data = strstr((char *)as608_receive_data,(char *)check_head);
if(data != NULL)
{
result = as608_detection_checknum(data,&*ID_OR_NUM);
break;
}
}
CLOSE_USART2_RECEIVE; //禁止串口接收
return result;
}
验证校验和是否准确
/***************************************************************************
描述: 校验数据是否正确
参数: data:数据包
ID_OR_NUM: 如果不是搜索指令或者查找模板个数设置为NULL 否则存放ID号或者NUM个数
返回: 数据错误返回0XFF 否则 返回接收结果
****************************************************************************/
uint8_t as608_detection_checknum(char *data , uint16_t **ID_OR_NUM)
{
//包标识位置:6 包长度位置:7、8
uint8_t packet_length; //包长度
uint8_t checksum1 = 0; //数据包校验和
uint8_t checksum2 = 0; //计算出的校验和
uint8_t i;
packet_length = (data[7]*10) + data[8]; //获取数据包长度
if(packet_length == 0) return 0XFF; //如果无长度 返回错误
checksum1 = (data[6+packet_length+1]*10) + data[6+packet_length+2]; //数据包校验和
//自己校验的校验和
for(i=0;i<packet_length+1;i++)
{
checksum2 += data[i+6];
}
//匹配校验和是否准确
if(checksum1 == checksum2)
{
//如果是搜索指令 ID进行保存 如果是查找模板个数 NUM进行保存
if(*ID_OR_NUM != NULL)
**ID_OR_NUM = (data[10]*10) + data[11]; //获取指纹ID号/模板个数
printf("数据校验和匹配 数据位:%#X\r\n",data[9]);
return data[9]; //返回结果
}
printf("数据校验和错误\r\n");
return 0XFF;
}
检测手指是否在
/***************************************************************************
描述: 检测手指是否在模块中
参数: wait_time:等待的时间 一次:10ms
返回: 0:手指在 1:不在
****************************************************************************/
uint8_t as608_detection_finger(uint16_t wait_time)
{
finger_status = FINGER_NO_EXIST;
//检测手指是否在模块中
while(wait_time--)
{
delay_ms(10);
if(finger_status == FINGER_EXIST)
{
finger_status = FINGER_NO_EXIST;
return 0;
}
}
return 1;
}
1.添加指纹
首先添加指纹需要的步骤:
第一步:读取指纹图像
第二步:生成特征(存放在CharBuffer1)
第三步:再次读取指纹图像
第四步:生成特征(存放在CharBuffer2)
第五步:比对两个特征是否一样
第六步:合并特征生成模板
第七步:存储模板(我这里是CharBuffer2,以及设置存放的位置:PageID)
/***************************************************************************
描述: 添加指纹 函数
返回: 0: 录入指纹成功 1: 录入指纹失败
****************************************************************************/
uint8_t as608_add_fingerprint(uint16_t PageID)
{
uint8_t result; //录入的结果
uint8_t add_stage = 1; //录入的阶段
while(add_stage != EXIT)
{
switch(add_stage)
{
//第一阶段 获取第一次指纹图像 并且生成特征图
case 1:
printf("请放置手指\r\n");
if(as608_detection_finger(800)) return 0x02; //等待手指按下
result = PS_GetImage(); //获取指纹图像
if(result) return 1;
result = PS_GenChar(CharBuffer1);//生成特征图
if(result) return 1;
add_stage = 2; //跳转到第二阶段
break;
//第二阶段 获取第二次指纹图像 并且生成特征图
case 2:
printf("请再放置手指\r\n");
if(as608_detection_finger(800)) return 0x02; //等待手指按下
result = PS_GetImage(); //获取指纹图像
if(result) return 1;
result = PS_GenChar(CharBuffer2);//生成特征图
if(result) return 1;
add_stage = 3; //跳转到第三阶段
break;
//第三阶段 比对两枚指纹特征
case 3:
result = PS_Match();//比对两枚指纹特征
if(result) return 1;
add_stage = 4; //跳转到第四阶段
break;
//第四阶段 特征合并生成模板
case 4:
result = PS_RegModel();//特征合并生成模板
if(result) return 1;
add_stage = 5; //跳转到第五阶段
break;
//第五阶段 储存模板
case 5:
result = PS_StoreChar(CharBuffer2,PageID);//储存模板
if(result) return 1;
add_stage = EXIT;
break;
}
}
return 0;
}
2.验证指纹
首先验证指纹的步骤:
第一步:读取指纹图像
第二步:生成特征(存放在CharBuffer1)
第三步:高速搜索
/***************************************************************************
描述: 验证指纹 函数
返回: 返回ID号 如果没有该指纹则ID是0
****************************************************************************/
uint16_t as608_verify_fingerprint(void)
{
uint8_t result; //存放结果
uint8_t verify_stage = 1; //验证的阶段
uint16_t ID = 0; //存放指纹的ID号
while(verify_stage != EXIT)
{
switch(verify_stage)
{
//第一阶段 获取指纹图像
case 1:
printf("请放置手指\r\n");
if(as608_detection_finger(800)) return 0x02; //等待手指按下
result = PS_GetImage(); //获取指纹图像
if(result) verify_stage = EXIT;
verify_stage = 2;
break;
//第二阶段 生成特征图
case 2:
result = PS_GenChar(CharBuffer1);//生成特征图
if(result) verify_stage = EXIT;
verify_stage = 3;
break;
//第三阶段 高速搜索
case 3:
result = PS_HighSpeedSearch(CharBuffer1,0,99,&ID);
if(result) ID = 0;
verify_stage = EXIT;
break;
}
}
if(ID == 0x00)
printf("验证指纹失败 ID:%d\r\n",ID);
else
printf("验证指纹成功 ID:%d\r\n",ID);
return ID;
}
3.删除指纹
1.删除单个或多个
我这里只是删除一个 删除多个修改PS_DeletChar()第二参数即可
步骤:
第一步:先验证是否有这个指纹,如果没有就那删除啥是吧,直接返回就行。
第二步:把验证到的指纹ID给到删除指纹函数执行即可。
/***************************************************************************
描述: 删除指纹 函数
返回: 0: 删除指纹成功 1: 删除指纹失败
****************************************************************************/
uint8_t as608_delete_fingerprint(void)
{
uint8_t result; //存放结果
uint16_t ID; //存放ID号
//1-识别要删除的指纹 如果没有这个指纹 则返回1
ID = as608_verify_fingerprint();
if(ID == 0X00)
{
printf("删除指纹失败-没有该指纹\r\n");
return 1;
}
//2-针对ID号码进行删除
result = PS_DeletChar(ID,1); //删除指纹 ID号
if(result)
printf("删除指纹失败 ID:%d\r\n",ID);
else
printf("删除指纹成功 ID:%d\r\n",ID);
return 0;
}
2.删除所有
这个比较简单
/***************************************************************************
描述: 清空所有指纹 函数
返回: 0: 清空所有指纹成功 1: 清空所有指纹失败
****************************************************************************/
uint8_t as608_empty_all_fingerprint(void)
{
uint8_t result; //存放结果
result = PS_Empty(); //删除所有指纹
switch(result)
{
case 0x00:
printf("清空所有指纹成功\r\n");
break;
case 0x01:
printf("清空所有指纹失败-收包错误\r\n");
break;
case 0x11:
printf("清空所有指纹失败-清空失败\r\n");
break;
}
if(result) result = 1;
return result;
}
4.查询指纹个数
/***************************************************************************
描述: 查找 指纹个数 函数
返回: 查找到的个数
****************************************************************************/
uint8_t as608_find_fingerprints_num(void)
{
uint8_t result;
uint16_t NUM; //存放指纹个数(模板个数)
result = PS_ValidTempleteNum(&NUM);
if(result)
printf("查找指纹个数失败 NUM:%d\r\n",NUM);
else
printf("查找指纹个数成功 NUM:%d\r\n",NUM);
return NUM;
}
代码基本就是这些啦
四: 主程序代码
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "as608.h"
uint8_t handler_flag;
/**************************************************************
描述:菜单
***************************************************************/
void menu(void)
{
printf("=============================\r\n");
printf("\t1-添加指纹\r\n");
printf("\t2-验证指纹\r\n");
printf("\t3-删除指纹\r\n");
printf("\t4-查询指纹个数\r\n");
printf("=============================\r\n");
}
int main()
{
uint8_t ID = 0;
usart1_init(115200); //串口1初始化 用于打印信息和输入信息
usart2_init(57600); //串口2初始化 用于和指纹模块通信
as60x_wak_init(); //指纹模块初始化
printf(" --指纹模块小Demo--\r\n");
menu();
while(1)
{
switch(handler_flag)
{
//添加指纹
case 1:
SCANF:
printf("\t添加指纹\r\n");
handler_flag = 0;
ID = 0;
printf("请输入ID号(1~9)\r\n");
while(ID == 0)
{
ID = handler_flag;
}
if(ID >0 && ID < 10) printf("ID号:%d\r\n",ID);
else goto SCANF;
if(as608_add_fingerprint(ID)) printf("添加指纹失败\r\n");
else printf("添加指纹成功\r\n");
handler_flag = 0;
menu();
break;
//验证指纹
case 2:
printf("\t验证指纹\r\n");
as608_verify_fingerprint();
handler_flag = 0;
menu();
break;
//删除指纹
case 3:
printf("\t删除指纹\r\n");
as608_delete_fingerprint();
handler_flag = 0;
menu();
break;
//查询模板个数
case 4:
printf("\t查看指纹个数\r\n");
as608_find_fingerprints_num();
handler_flag = 0;
menu();
break;
}
}
}
五: 项目展示
六: 总结
都看到这里了,不妨给我点个赞啥的哈,哈哈哈哈鼓励鼓励。
==问题:==指纹这个不难。按着手册写就行,然后我这里发现了一个问题,我不知道是不是我模块有问题,还是都这样的。
就是WAK引脚,正常是不按是低电平,有手指按就是高电平,但是我发现,它不管你三七二十一,大概是每隔1分钟多点,它自动会高电平几次,然后恢复低电平。。。。。一开始以为我程序有问题,后来发现是这个模块就这样。。。。不知道大家的是不是也这样。
如果我哪里写的有问题,或者不好,请大家多多指教
#整个工程代码。
printf("+meQ:844797079\n")
如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈
需要整个工程代码,欢迎大家打赏,请o( ̄︶ ̄)o文章来源:https://www.toymoban.com/news/detail-407849.html
继续加油!!!文章来源地址https://www.toymoban.com/news/detail-407849.html
到了这里,关于基于STM32F103——AS608指纹模块+串口打印的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!