基于STM32F103——AS608指纹模块+串口打印

慈云数据 2024-05-13 技术支持 71 0

STM32F103-AS608指纹模块+串口打印

  • 一: 基本介绍
    • AS608引脚描述
    • AS608模块地址
    • AS608波特率
    • AS608指令格式
    • AS608应答格式
    • 二: 指令集
      • 1.读取图像-PS_GetImage
      • 2.生成特征-PS_GenChar
      • 3.比对特征-PS_Match
      • 4.生成模板-PS_RegModel
      • 5.储存模板-PS_StoreChar
      • 6.删除模板-PS_DeletChar
      • 7.清空指纹库-PS_Empty
      • 8.高速搜索指纹-PS_HighSpeedSearch
      • 9.搜索指纹-PS_Search
      • 10.查有效模板个数-PS_ValidTempleteNum
      • 11.关于包长度和校验和
      • 三: 编写指令集代码
        • 0.预代码
        • 1.读取图像-PS_GetImage
        • 2.生成特征-PS_GenChar
        • 3.比对特征-PS_Match
        • 4.生成模板-PS_RegModel
        • 5.储存模板-PS_StoreChar
        • 6.删除模板-PS_DeletChar
        • 7.清空指纹库-PS_Empty
        • 8.高速搜索指纹-PS_HighSpeedSearch
        • 9.搜索指纹-PS_Search
        • 10.查有效模板个数-PS_ValidTempleteNum
        • 三: 指纹代码编写
          • 0.接收处理
          • 1.添加指纹
          • 2.验证指纹
          • 3.删除指纹
            • 1.删除单个或多个
            • 2.删除所有
            • 4.查询指纹个数
            • 四: 主程序代码
            • 五: 项目展示
            • 六: 总结

              最近用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
              		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;
              }
              
              	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;
              }
              
              	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;
              	
              }
              
              	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;
              }
              
              	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;
              }
              
              	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;
              }
              
              	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;
              }
              
              	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  
              

              五: 项目展示

              在这里插入图片描述

              六: 总结

              都看到这里了,不妨给我点个赞啥的哈,哈哈哈哈鼓励鼓励。

              ==问题:==指纹这个不难。按着手册写就行,然后我这里发现了一个问题,我不知道是不是我模块有问题,还是都这样的。

              就是WAK引脚,正常是不按是低电平,有手指按就是高电平,但是我发现,它不管你三七二十一,大概是每隔1分钟多点,它自动会高电平几次,然后恢复低电平。。。。。一开始以为我程序有问题,后来发现是这个模块就这样。。。。不知道大家的是不是也这样。

              如果我哪里写的有问题,或者不好,请大家多多指教

              #整个工程代码。
              printf("+meQ:844797079\n")
              

              如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈

              需要整个工程代码,欢迎大家打赏,请o( ̄︶ ̄)o

              继续加油!!!

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon