基于STM32F401RET6的指纹模块MG200实现指纹注册、识别、删除、查询所存指纹数量的功能

1.产品概述

 MG200 指纹识别模块是一种触摸式指纹识别设备,由以下两部分组成:
  MG200 指纹识别模块
  电容式指纹传感器
MG200 指纹识别模块具有耐磨、耐腐蚀、耐静电等优势,模块中集成了铭光正讯科技
自主研发的指纹识别算法,该算法在行业内处于领先地位,长期应用于银行金融业、公
安、智能指纹锁等领域,各项性能指标均位于市场同类产品前列。
MG200 指纹识别模块的处理器包含FLASH和SRAM,指纹的采集、存储和比对全部在芯片
内部处理完成,处理速度快,开发接口简单

1.1产品特点

 1.2产品外观

1.3技术指标

1.3.1产品介绍

MG200电容指纹识别模块使用电容指纹传感器,可完成指纹的采集、 比对、储存
以及相关的扩展功能。模块包含硬件和软件(核心算法及管理程序)两部分。
MG200 电容指纹识别模块的管理程序,通过 TTL 电平的 RS232 串行总线接口与主控单元 MCU (或上位机) 连接,采集器接收来自主控单元 MCU (或上位机)的指令,并执行该指令对应的操作,操作完成后再将执行结 果通过 RS232 接口返回给主控单元 MCU (或上位机);从而实现指纹处理模块的管理平台。管理程序的通信接 口由若干指令组合而成,模块的每个功能由主控单元 MCU (或上位机) 发送独立的指令来执行,执行状态通过 串口反馈给主控单元MCU 进行逻辑交互。通过合理的组合使用接口指令,可以适用于指纹识别的各种应用场景, 如何实现功能逻辑则完全由主控单元 MCU (或上位机)决定。

1.3.2硬件

指纹模块的硬件包含指纹传感器和指纹识别模块。MG200电容指纹识别模块的主芯片采
用高性能Cortex内核120M主频,稳定可靠并能够快速运行指纹识别算法。

1.3.3软件(核心算法及管理程序)

指纹模块的软件包括指纹识别核心算法和管理程序两部分。

2.硬件接口定义

2.1 通讯接口

标准 UART TTL 电平
UART 通信中的参数设置如下:
1 ) 波特率( Baud rate ): 115200bps (缺省,可通过指令更改)
2 ) 奇偶校验( Parity ): None
3 ) 停止位( Stop bits ): 1 bits
4 ) 数据位长度( Data bits ): 8bits

2.2管脚说明

串口为 3.3V 的 TTL 电平。如需与 PC 机的串口连接,则需接上 TTL-RS232 转接板后
才可通信。
注意: 1 脚(触控电路电源)需要一直供电。

2.3指纹模块触控信号(手指接触感应)原理说明

 采用单触摸键检测芯片,功耗低,工作电压范围宽。
无手指触摸状态下,Detect信号线为低电平,当手指触摸指纹传感器时该信号触发
成高电平,直到手指离开时再变为低电平。
使用Detect信号进行二次开发时需要注意以下事项:
在MG200指纹识别模块休眠状态下,作为唤醒信号使用。当手指接触指纹传感器时,
触控信号会被激发,继而唤醒系统(给指纹模块上电)。此时二次开发者可无视该
信号,并等待指纹模块的正常操作(采集、注册、比对等)完毕后,对3.3V
进行掉电(对3.3V电源的控制可参考下文3.3V电源控制电路部分),再次触摸指纹
模块时,可重复使用该信号。
降低模块功耗方法通过控制 3.3V 电源是否工作来降低功耗,左上部电路作用是通过外部的MCU的PWR_ON/OFF信号控制Q2三极管导通关断时间,从而降低电路功耗。当3.3V电源被切断时,整个模块只有(手指接触)触控信号输出电路在工作,且功耗为2μA左右

3.MG200 指纹采集器工作流程

3.1指纹采集器通信包数据接口

1) 发送包数据结构

① 起始码:表示发送包的开始字节,固定为 6Ch
② 发送地址:表示发送地址(主控单元 MCU 地址),参数为 63h
③ 接收地址:表示接收地址(指纹模块地址),参数为 62h
④ 指令码:表示指令类型。
⑤ 参数:按照指令码的不同,可能存在的参数(数据)。
⑥ 预留:预留字节,后续扩展使用;目前未使用,默认为 00h
⑦ 校验和:为了确认发送数据包的正确性而设,是除去起始码之外的所有字节按照 8bit 单位相加的结
果(溢出部分将被无视)。

2) 接收包数据结构

① 起始码:表示接收包的开始,固定为 6Ch
② 发送地址:发送地址参数为 62h
③ 接收地址:接收地址参数为 63h
④ 应答码:对指令码的应答。
⑤ 返回值:表示对主控单元 MCU 发送指令的处理结果。
⑥ 参数:按照指令码的不同,可能存在的参数(数据)。
⑦ 预留:预留字节,后续扩展使用;目前未使用,默认为 00h
⑧ 校验和:为了确认接收数据包的正确性而设,是除去起始码之外的所有字节按照 8bit 单位相加的结
果(溢出部分将被无视)。

3)指纹采集器指令通信集

17.2 :指纹采集器功能指令指令目录如下:
17.3 :指纹采集器应答指令应答指令目录如下:
17.4 :错误返回值

 3.2通信指令具体说明

a) 抓取指纹图像和提取特征点 CaptureAndExtract

ReqCaptureAndExtract
指令码 51h
参数
00h, 01h, 02h, 03h, 04h (可在 3~5 次之间,自定义选择注册指纹的次数)
预留
00h
方向
主控 MCU — 指纹模块
说明
主控单元 MCU 用该指令控制指纹模块采集指纹并对采集到的指纹进行特征提取;
指纹模块执行完该指令后将结果用 AckCaptureAndExtract 发送给主控单元 MCU;
该指令在用户注册和指纹比对时被使用;
指纹比对时,执行该指令 1 次,对应的参数为 00h;
用户注册时,可根据产品需求以及实际使用场景的需要,在 3 至 5 次之间自定义
选择注册指纹的次数。执行该指令 3~5 次,按照需要注册指纹的采集次数参数分
别为:
00h, 01h, 02h(注册 3 次指纹);
00h, 01h, 02h, 03h(注册 4 次指纹);
00h, 01h, 02h, 03h, 04h(注册 5 次指纹);

AckCaptureAndExtract

应答码 51h
返回值
00h: 抓取指纹图像及特征量提取成功
B1h : 指纹过小(small finger)
B2h : 无指纹 (no finger)
B3h : 指纹位置过于靠左,需要将手指靠右边摁按(left finger)
B4h : 指纹位置过于靠右,需要将手指靠左边摁按(right finger)
B5h : 指纹位置过于靠上,需要将手指靠下边摁按(up finger)
B6h : 指纹位置过于靠下,需要将手指靠上边摁按 (down finger)
B7h : 湿手指 (指纹表面出汗或者水渍过多)(wet finger)
B8h : 干燥手指(dry finger)
C0h: 特征提取错误
C2h: 特征提取错误 (图像质量差)
其他: 抓取指纹图像及特征量提取错误
参数
00h
预留
00h
方向
指纹模块-   MCU单片机
说明
指纹模块通过该应答向主控单元发送抓取指纹图像及特征量提取的结果

b) 注册用户 Enroll

ReqEnroll AckEnroll
ReqEnroll
指令码 7Fh
参数
注册的 ID 号 (ID 范围 1~100,最大用户数为 100;当该参数为 00h 时,模块
注册成功的 ID 号是模块内部自动分配的)
预留
00h
方向
主控 MCU -   指纹模块
说明
主控单元 MCU 通过该指令操作指纹模块进行新用户注册,指纹模块将根据接收到
的用户 ID 和用户数据结合提取的指纹特征量实现用户注册。
指纹模块执行该指令后将结果用 AckEnroll 发送给主控单元。
用户注册时使用该指令。
主控单元 MCU 在使用该注册用户指令前必须先执行 3~5 次(执行次数可根据用户
需求定制) ReqCaptureAndExtract 指令,提取要注册用户指纹的特征量;

AckEnroll

应答码 7Fh
返回值
00h: 注册成功
83h: ID 错误(ID < 0 或者 ID > 最大用户数)或者通信错误
91h: 注册失败(用户区域已满)
93h: 已经注册的 ID
94h: 指纹提取次数 < 3
参数
00h
预留
00h
方向
主控 MCU 指纹模块
说明
指纹模块通过该应答向主控单元 MCU 发送用户注册的结果

c) 1:N 比对 Match1N

ReqMatch1N -  AckMatch1N
ReqMatch1N
指令码 71h
参数
00h
预留
00h
方向
主控 MCU 指纹模块
说明
主控单元 MCU 通过该指令对上次发送的特征提取指令执行后所得的特征量和模块
内的所有用户的特征量进行比对。
执行该指令后,指纹模块以 AckMatch1N 应答,将结果返回给主控单元 MCU。

AckMatch1N
应答码 71h
返回值
00h: 比对成功
92h: 比对失败
参数
成功(返回值 = 00h)时 参数字节内容表示比对成功的用户 ID 号。
失败时参数字节内容为 00h。
预留
00h
方向
主控 MCU -   指纹模块
说明
指纹模块通过该应答将 ReqMatch1N 指令的执行结果返回给主控单元 MCU。
以上这三个为这个指纹模块常用的指令数据包详解,剩下的还有查询注册个数的、删除某一个指纹数据等等,在这里我就不一一介绍了

代码详解

/*硬件接口
1.MG200-TXD----PC6
2.MG200-RXD----PC7
3.MG200_DETECT-PC0
4.MG200_PWR----PC1
*/
/*
****************************************************************************************
* Function: MG200UsartInit
* Description: MG200串口接口初始化
* Input: bound波特率
* Output: None
* Return: None
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
void MG200UsartInit(u32 bound)
{
	float USARTDIV;uint16_t DIV_Man;uint16_t DIV_Fra;
	
	//GPIO初始化:
	//PC6---复用成USART6_TX模式
	//PC7--复用成USART6_RX模式
	RCC->AHB1ENR |=0x01<<2;//端口C时钟使能
	
	MG200_USART_PORT->MODER &=~(0x03<<(MG200_USART_TXD_PIN*2) | 0x03<<(MG200_USART_RXD_PIN*2));//清零
	MG200_USART_PORT->MODER |=(0x02<<(MG200_USART_TXD_PIN*2) | 0x02<<(MG200_USART_RXD_PIN*2));//PC6和PC7复用功能
	MG200_USART_PORT->OTYPER &=~(0x01<<MG200_USART_TXD_PIN);//PC6复用功能推挽输出
	MG200_USART_PORT->OSPEEDR &=~(0x03<<(MG200_USART_TXD_PIN*2));//PC6低速2Mhz
	MG200_USART_PORT->PUPDR &=~(0x03<<(MG200_USART_TXD_PIN*2) | 0x03<<(MG200_USART_RXD_PIN*2));//PC6和PC7浮空
	if(MG200_USART_TXD_PIN<8)
	{
		MG200_USART_PORT->AFR[0] &=~(0xF<<(MG200_USART_TXD_AFIO_PIN*4));
		MG200_USART_PORT->AFR[0] |=(MG200_USART_TXD_AFIO<<(MG200_USART_TXD_AFIO_PIN*4));
	}
	else
	{
		MG200_USART_PORT->AFR[1] &=~(0xF<<(MG200_USART_TXD_AFIO_PIN*4));
		MG200_USART_PORT->AFR[1] |=(MG200_USART_TXD_AFIO<<(MG200_USART_TXD_AFIO_PIN*4));
	}
	
	if(MG200_USART_RXD_PIN<8)
	{
		MG200_USART_PORT->AFR[0] &=~(0xF<<(MG200_USART_RXD_AFIO_PIN*4));
		MG200_USART_PORT->AFR[0] |=(MG200_USART_RXD_AFIO<<(MG200_USART_RXD_AFIO_PIN*4));
	}
	else
	{
		MG200_USART_PORT->AFR[1] &=~(0xF<<(MG200_USART_RXD_AFIO_PIN*4));
		MG200_USART_PORT->AFR[1] |=(MG200_USART_RXD_AFIO<<(MG200_USART_RXD_AFIO_PIN*4));
	}
	
	
	//配置USART6
	RCC->APB2ENR |=0x01<<5;//模块时钟使能--84Mhz
	MG200_USART->CR1=0;//寄存器清零
	MG200_USART->CR2 &=~(0x03<<12);
	/*
	16 倍过采样
	1 起始位, 8 数据位, 1 停止位
	禁止奇偶校验控制
	*/
	
	//波特率设置
	USARTDIV=84000000.0/(16*bound);
	DIV_Man=USARTDIV;
	DIV_Fra=(USARTDIV-DIV_Man)*16+0.5;
	MG200_USART->BRR=DIV_Man<<4  | DIV_Fra;
	
	MG200_USART->CR1 |=0X01<<4;  //空闲中断使能
	MG200_USART->CR1 |=0X01<<5; //接收缓冲区非空中断使能
	
	//nvic中设置uart1的优先级、使能uart1中断
	NVIC_SetPriority(USART6_IRQn,NVIC_EncodePriority(7-2,3,3));
	NVIC_EnableIRQ(USART6_IRQn);
	
	
	MG200_USART->CR1 |=0x01<<3;//使能发送器
	MG200_USART->CR1 |=0x01<<2;//使能接收器
	MG200_USART->CR1 |=0x01<<13;//使能串口
}

这个函数为串口的两个引脚相关配置,其中开启了串口GPIO口相关的时钟,对GPIO口进行了初始化,TX引脚配置为复用推挽输出,RX引脚配置为浮空输入,因为串口使用到 PC6,PC7,所以我们要把 PC6 和 PC7 都复用器映射到串口 6。然后配置串口相关的初始化,波特率配置为115200,配置相应中断通道优先级以及使能中断通道。打开相应的接收中断以及空闲中断,对串口进行使能。

/*
****************************************************************************************
* Function: USART6_IRQHandler
* Description: 串口6中断服务函数
* Input: None
* Output: None
* Return: None
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
TYPE_MG200_U MG200rev={0};
void USART6_IRQHandler(void)
{
	uint8_t data;
	if(MG200_USART->SR & (0X01<<5))  //接收中断
	{
		MG200rev.RevBuf[MG200rev.RevLen++]=MG200_USART->DR;
	}
	else if(MG200_USART->SR & (0X01<<4))//空闲中断
	{
		data=MG200_USART->SR;
		data=MG200_USART->DR;
		//printf("%s",MG200rev.RevBuf);
		MG200rev.RevLen=0;
		MG200rev.RevOver=1;
	}
	
}

这个函数为串口的中断函数,在这里面将接受到的数据存入结构体的数租中,同时在空闲中断来了之后将相应的结构体中RevOver置为1方便后续进行判断是否接收完成。


/*
****************************************************************************************
* Function: MG200SendByte
* Description: 给MG200发送一个字节数据
* Input: data待发送的一个字节数据
* Output: None
* Return: None
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
void MG200SendByte(uint8_t data)
{
	while((MG200_USART->SR & (0X01<<7))==0);  //等待发送缓冲区为空
	MG200_USART->DR=data;
}

这个函数为一个简单的发送单字节的函数


/*
****************************************************************************************
* Function: MG200SendCommond
* Description: MCU 向指纹模块发送指令
* Input: cmd-指令码   parm-参数
* Output: None
* Return: None
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
void MG200SendCommond(uint8_t cmd,uint8_t param)
{
	uint8_t checksum=0;//校验和
	
	//校验和 为了确认发送数据包的正确性而设,是除去起始码之外的所有字节按照
	//8bit 单位相加的结果(溢出部分将被无视)
	checksum =(SENDADDR+REVADDR+cmd+param+RESERVE)&0xFF;

	MG200SendByte(STARTCODE);//起始码
	MG200SendByte(SENDADDR);//发送地址
	MG200SendByte(REVADDR);//接收地址
	MG200SendByte(cmd);//指令码 表示指令类型
	MG200SendByte(param);//参数 按照指令码的不同,可能存在的参数(数据)
	MG200SendByte(RESERVE);//预留字节, 后续扩展使用;目前未使用,默认为 00h
	MG200SendByte(checksum);//校验和
	
}

这个函数的形参对应发送数据包中的参数以及指令,函数实现了发送一个指定指令的数据包


/*
****************************************************************************************
* Function: MG200Ack
* Description: 指纹模块对指令的回复包
* Input: cmd-所回复的指令码
* Output: None
* Return: None
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
uint8_t MG200Ack(uint8_t cmd,uint8_t* result,uint8_t* param)
{
	uint8_t checksum=0;//校验和
	
	while(!MG200rev.RevOver);//等待U2接收完成
	MG200rev.RevOver=0;
	/*
从指纹模块接收到应答后,主控单元需要检查所接收的数据包是否正确,如果各项都
符合条件就判断为接收到正确回复。即:起始位、收发地址是否正确,指令码是否
与发送的指令码一致、校验和是否正确等
	*/
	if(MG200rev.RevBuf[0]!=STARTCODE)
		return RECEIVE_PARAMETER_ERROR;
	
	if(MG200rev.RevBuf[1]!=0x62)
		return RECEIVE_PARAMETER_ERROR;
	
	if(MG200rev.RevBuf[2]!=0x63)
		return RECEIVE_PARAMETER_ERROR;
	
	if(MG200rev.RevBuf[3]!=cmd)
		return RECEIVE_PARAMETER_ERROR;
	
	checksum =(0x62+0x63+cmd+MG200rev.RevBuf[4]+MG200rev.RevBuf[5]+RESERVE)&0xFF;
	if(MG200rev.RevBuf[7]!=(checksum))
		return RECEIVE_CHECKSUM_ERROR;

	*result =MG200rev.RevBuf[4];
	*param=MG200rev.RevBuf[5];
	
	memset(MG200rev.RevBuf,0,sizeof(MG200rev.RevBuf));
	
	return NO_ERROR;
}

这个函数为接收一个数据包的函数,函数中的形参比发送多一个为返回值,用来后面进行判断是否实现相应的功能,函数最开始等待串口接收一个数据包完成,判断接受的数据是否正确,校验和正确之后,将数据存入传入的形参以及返回值,后用memset清除数组中的内容,然后返回

/*
****************************************************************************************
* Function: MG200Init
* Description: MG200初始化
* Input: None
* Output: None
* Return: None
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
void MG200Init(void)
{
	MG200UsartInit(115200);
	//PC0--Detect:感应上电信号(手指触摸指纹传感器时输出高电平)
	//PC1---MG200_PWR
	RCC->AHB1ENR |=0x01<<2;
	
	MG200_DETECT_PORT->MODER &=~(0x03<<(MG200_DETECT_PIN*2));
	MG200_DETECT_PORT->PUPDR &=~(0x03<<(MG200_DETECT_PIN*2));
	
	MG200_PWR_PORT->MODER &=~(0x03<<(MG200_PWR_PIN*2));
	MG200_PWR_PORT->MODER |= (0x01<<(MG200_PWR_PIN*2));
	MG200_PWR_PORT->OTYPER &=~(1<<MG200_PWR_PIN);
	MG200_PWR_PORT->PUPDR &=~(0x03<<(MG200_PWR_PIN*2));
	
	MG200_PWR_H;
	
}

初始化另外两个GPIO口将PWR引脚拉高


/*
****************************************************************************************
* Function: CaptureAndExtract
* Description: 抓取指纹图像并同时提取特征量
* Input: param-参数 00h, 01h, 02h, 03h, 04h (可在 3~5 次之间, 自定义选择注册指纹的次数)
* Output: None
* Return: None
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
uint8_t CaptureAndExtract(uint8_t param)
{
	uint8_t result;
	uint8_t ackparam;
	
	MG200SendCommond(0x51,param);
	if(NO_ERROR!=MG200Ack(0x51,&result,&ackparam))
		return ACK_ERR;
/*	
返回值result:	
00h: 抓取指纹图像及特征量提取成功
B1h : 指纹过小(small finger)
B2h : 无指纹 (no finger)
B3h : 指纹位置过于靠左,需要将手指靠右边摁按(left finger)
B4h : 指纹位置过于靠右,需要将手指靠左边摁按(right finger)
B5h : 指纹位置过于靠上,需要将手指靠下边摁按(up finger)
B6h : 指纹位置过于靠下,需要将手指靠上边摁按 (down finger)
B7h : 湿手指 (指纹表面出汗或者水渍过多) (wet finger)
B8h : 干燥手指(dry finger)
C0h: 特征提取错误
C2h: 特征提取错误 (图像质量差)
其他: 抓取指纹图像及特征量提取错误
*/
	switch(result)
	{
		case 0x00:printf("抓取指纹图像及特征量提取成功\r\n");break;
		case 0xB1:printf("small finger\r\n");break;
		case 0xB2:printf("no finger\r\n");break;
		case 0xB3:printf("left finger\r\n");break;
		case 0xB4:printf("right finger\r\n");break;
		case 0xB5:printf("up finger\r\n");break;
		case 0xB6:printf("down finger\r\n");break;
		case 0xB7:printf("wet finger\r\n");break;
		case 0xB8:printf("dry finger\r\n");break;
		case 0xC0:printf("特征提取错误\r\n");break;
		case 0xC2:printf("特征提取错误 (图像质量差)\r\n");break;
		default :printf("抓取指纹图像及特征量提取错误\r\n");break;
	}
	return result;
}

抓取指纹图像之后获取相应的特征值,返回相应的读取的返回值


/*
****************************************************************************************
* Function: Enroll
* Description: 注册新指纹用户
* Input: param-参数 00h, 01h, 02h, 03h, 04h (可在 3~5 次之间, 自定义选择注册指纹的次数)
* Output: None
* Return: 00h: 注册成功
					83h: ID 错误(ID < 0 或者 ID > 最大用户数)或者通信错误
					91h: 注册失败(用户区域已满)
					93h: 已经注册的 ID
					94h: 指纹提取次数 < 3
* Author: weihaoMo
* Others: 主控单元 MCU 在使用该注册用户指令前必须先执行 3~5 次(执行次数可根据用户
					需求定制) ReqCaptureAndExtract 指令,提取要注册用户指纹的特征量;
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
uint8_t Enroll(void)
{
	uint8_t result;
	uint8_t ackparam;
	
	//抓取指纹的特征3次
	printf("第一次录入,请放下手指\r\n");
	while(!MG200_DETECT);//等待触摸
	result=CaptureAndExtract(0x00);//第一次抓取指纹的特征-参数0x00
	while( result!=0x00 )
	{
		while(!MG200_DETECT);
		result=CaptureAndExtract(0x00);
	}
	printf("第二次录入,请放下手指\r\n");
	while(!MG200_DETECT);//等待触摸
	result=CaptureAndExtract(0x01);//第二次抓取指纹的特征-参数0x01
	while( result!=0x00 )
	{
		while(!MG200_DETECT);
		result=CaptureAndExtract(0x01);
	}
	printf("第三次录入,请放下手指\r\n");
	while(!MG200_DETECT);//等待触摸
	result=CaptureAndExtract(0x02);//第三次抓取指纹的特征-参数0x02
	while( result!=0x00 )
	{
		while(!MG200_DETECT);
		result=CaptureAndExtract(0x02);
	}
	
	
	MG200SendCommond(0x7F,0x00);//注册的 ID 号(ID 范围 1~100,最大用户数为 100; 当该参数为 00h 时,模块注册成功的 ID 号是模块内部自动分配的)
	if(NO_ERROR!=MG200Ack(0x7F,&result,&ackparam))
		return ACK_ERR;
	
	switch(result)
	{
		case 0x00:printf("注册成功\r\n");break;
		case 0x83:printf("ID 错误(ID < 0 或者 ID > 最大用户数)或者通信错误\r\n");break;
		case 0x91:printf("注册失败(用户区域已满)\r\n");break;
		case 0x93:printf("已经注册的 ID\r\n");break;
		case 0x94:printf("指纹提取次数 < 3\r\n");break;
		
	}

	return result;
	
}

这个函数的作用为注册相应的用户指纹,要先进行三次指纹特征值的提取后发送相应的指令数据包判断注册是否成功


/*
****************************************************************************************
* Function: Match1N
* Description: 采集指纹进行 1: N 比对 (0x71)
* Input: None
* Output: None
* Return: 返回采集指纹进行 1: N 比对的结果
				  0-没有该指纹  1~100比对成功的用户指纹 ID 号  0xFF失败
* Author: weihaoMo
* Others: None
* Date of completion: 2019-11-29
* Date of last modify: 2019-11-29
****************************************************************************************
*/
uint8_t Match1N(void)
{
	uint8_t result;
	uint8_t ackparam;
	printf("请放下手指\r\n");
	while(!MG200_DETECT);//等待触摸
	result=CaptureAndExtract(0x00);//抓取指纹的特征-参数0x00
	while( result!=0x00 )
	{
		while(!MG200_DETECT);
		result=CaptureAndExtract(0x00);
	}
	
	MG200SendCommond(0x71,0x00);
	if(NO_ERROR!=MG200Ack(0x71,&result,&ackparam))
		return ACK_ERR;
	
	
	
	if(0x00==result)
	{
		printf("比对成功\r\n");
		return ackparam;//ID
	}
	else if(0x92==result)
	{
		printf("没有该指纹\r\n");//比对失败
		return ackparam;//ID==0
	}
	else 
	{
		printf("失败\r\n");
		return 0xFF;
	}
	
}

这个函数为比对相应的指纹是否存在,先采集一次指纹后发送比对的数据包,然后接收到的返回值判断是否比对成功

  • 42
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值