基于STM32C8T6、ATK-AS608实现指纹的录入、识别与删除

ATK-AS608介绍

ATK-AS608光学指纹识别模块是广州星翼电子科技有限公司(ALIENTEK)推出的光学指纹识别模块。该模块内置 DSP 运算单元,集成了图像处理和指纹识别算法,能快速采集图像并识别指纹特征。

ATK-AS608的引脚描述如下表所示:

引脚名称

引脚说明

Vi(红线)

模块电源正输入端

Tx(黄线)

串行数据输出,TTL 逻辑电平

Rx(白线)

串行数据输入,TTL 逻辑电平

GND(黑线)

信号地,内部与电源地连接

WAK(蓝线)

感应信号输出,默认高电平有效

Vt(绿线)

触摸感应电源输入端,3.3V供电

通过上位机软件实现指纹功能

上位机软件

https://download.csdn.net/download/qq_44955826/90111719?spm=1001.2014.3001.5501

接线

AS608USB-TTL

Vi(红线)

VCC

Tx(黄线)

RX

Rx(白线)

TX

GND(黑线)

GND

Vt(绿线)

VCC

通过串口驱动实现指纹功能

通过串口通信驱动ATK-AS608光学指纹识别模块可实现录入、识别删除指纹等功能。其中,录入与识别指纹分多步操作实现。删除指纹分为删除指定的指纹和删除所有指纹两个功能,均为单一操作。

指纹录入流程

指纹识别流程

生成特征:指纹特征可以存到第一个缓存区也可以存到第二个缓存区,下文的项目存入的是第二个缓存区。

搜索指纹:调用这个指令就会将已经存在Flash里面的指纹模板和缓存区的指纹特征一一比对,如果有搜索到,会返回这个指纹的ID。要注意的是,调用的时候需要指明比对的特征是缓存区1还是缓存区2,要选择第二步生成特征所存储的缓存区。

单一指纹操作

针对该模块的单一操作,只需按照下表所示的指令包、应答包格式进行串口的收发操作,便可驱动该模块完成相关操作。

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令

参数1

参数n

校验和

内容

0xEF01

0xFFFFFFFF

0x01

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

N bytes

2bytes

名称

包头

模块地址

包标识

包长度

确认码

返回参数

校验和

内容

0xEF01

0xFFFFFFFF

0x07

包长度是包长度(不含)至校验和(含)之间的总字节数;校验和是从包标识(含)至校验和(不含)之间的字节之和,超出2字节的进位忽略。

确认码表示指令执行完毕后的情况。0x00表示指令成功执行,其余数值代表了不同的错误类型。

在所有的操作中,只有在录入图像时,手指才需要按在模块采集处。

下面将阐述种个操作的具体过程:

录入图像

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0003

0x01

0x0005

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

确认码

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0003

确认码含义:

确认码

含义

0x00

录入成功

0x01

收包有错

0x02

传感器上无手指

0x03

录入不成功

串口要发送的数据:EF 01 FF FF FF FF 01 00 03 01 00 05

在指令成功执行后,模块会回复的数据:EF 01 FF FF FF FF 07 00 03 00 00 0A

生成特征,存在缓冲区

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

缓冲区号

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0004

0x02

缓冲区号为0x01或0x02,若输入其他值,则以0x02处理

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

模块地址

包标识

包长度

确认码

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0003

确认码含义:

确认码

含义

0x00

生成特征成功

0x01

收包有错

0x06

指纹图像太乱而生不成特征

0x07

指纹图像正常,但特征点太少而生不成特征

0x15

图像缓冲区内没有有效原始图而生不成图像

生成特征,存入缓存区01

串口要发送的数据:EF 01 FF FF FF FF 01 00 04 02 01 00 08

在指令成功执行后,模块会回复的数据:EF 01 FF FF FF FF 07 00 03 00 00 0A

生成特征,存入缓存区02

串口要发送的数据:EF 01 FF FF FF FF 01 00 04 02 02 00 09

在指令成功执行后,模块会回复的数据:EF 01 FF FF FF FF 07 00 03 00 00 0A

精确比对两枚指纹特征

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0003

0x03

0x0007

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

2bytes

名称

包头

芯片地址

包标识

包长度

确认码

比对得分

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0005

确认码含义:

确认码

含义

0x00

指纹匹配成功

0x01

收包有错

0x08

指纹不匹配

串口要发送的数据:EF 01 FF FF FF FF 01 00 03 03 00 07

在指令成功执行后(比对得分为0x00F0),模块会回复的数据:EF 01 FF FF FF FF 07 00 05 00 00 F0 00 FC

合并特征并生成模板

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0003

0x05

0x0009

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

确认码

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0003

确认码含义:

确认码

含义

0x00

特征合并成功

0x01

收包有错

0x0a

合并失败(两枚指纹不属于同一根手指)

串口要发送的数据:EF 01 FF FF FF FF 01 00 03 05 00 09

在指令成功执行后,模块会回复的数据:EF 01 FF FF FF FF 07 00 03 00 00 0A

储存模板到缓冲区

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

1bytes

2bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

缓冲区号

指纹ID

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0006

0x06

缓冲区号为0x01或0x02

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

确认码

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0003

确认码含义:

确认码

含义

0x00

储存成功

0x01

收包有错

0x0b

指纹ID 超出指纹库范围

0x18

写FLASH出错

以储存模板到缓冲区01,并赋予指纹ID = 0x0001为例:

串口要发送的数据:EF 01 FF FF FF FF 01 00 06 06 01 00 01 00 0F

在指令成功执行后,模块会回复的数据:EF 01 FF FF FF FF 07 00 03 00 00 0A

搜索指纹

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

1bytes

2bytes

2bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

缓冲区号

起始ID

查找数量

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0008

0x04

缓冲区号为0x01或0x02

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

2bytes

2bytes

名称

包头

芯片地址

包标识

包长度

确认码

匹配ID

得分

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0007

确认码含义:

确认码

含义

0x00

搜索到指纹

0x01

收包有错

0x09

未搜索到指纹,此时匹配ID与得分为0

以将待识别的指纹录入到缓冲区02并搜索已录入的全部指纹(起始ID = 0,查找数量 = 300)为例:

串口要发送的数据:EF 01 FF FF FF FF 01 00 08 04 02 00 00 01 2C 00 3C

在指令成功执行后(匹配到ID = 0x0005,得分为0x0058的指纹),模块会回复的数据:EF 01 FF FF FF FF 07 00 07 00 00 05 00 58 00 6B

删除指定的指纹

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

2bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

起始ID

删除个数

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0007

0x0c

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

确认码

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0003

确认码含义:

确认码

含义

0x00

删除模板成功

0x01

收包有错

0x10

删除模板失败

以删除ID = 1的指纹(起始ID为1,删除个数为1)为例:

串口要发送的数据:EF 01 FF FF FF FF 01 00 07 0C 00 01 00 01 00 16

在指令成功执行后,模块会回复的数据:EF 01 FF FF FF FF 07 00 03 00 00 0A

删除所有指纹

指令包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

指令码

校验和

内容

0xEF01

0xFFFFFFFF

0x01

0x0003

0x0d

0x11

应答包格式:

字节数

2bytes

4bytes

1bytes

2bytes

1bytes

2bytes

名称

包头

芯片地址

包标识

包长度

确认码

校验和

内容

0xEF01

0xFFFFFFFF

0x07

0x0003

确认码含义:

确认码

含义

0x00

清空成功

0x01

收包有错

0x11

清空失败

串口要发送的数据:EF 01 FF FF FF FF 01 00 03 0D 00 11

在指令成功执行后,模块会回复的数据:EF 01 FF FF FF FF 07 00 03 00 00 0A

基于STM32C8T6、ATK-AS608实现指纹的录入、识别与删除

元件

接线

STM32

AS608

ST-LINK

USB-TTL

3V3

Vi(红线)

3.3V

PB11

Tx(黄线)

PB10

Rx(白线)

GND

GND(黑线)

GND

GND

PB1

WAK(蓝线)

3V3

Vt(绿线)

SWDIO

SWDIO

SWCLK

SWCLK

PA9

RX

代码

工程文件:https://download.csdn.net/download/qq_44955826/90111719?spm=1001.2014.3001.5503

代码说明

1. main函数中的“delete_fingerprint(1)”、“delete_all_fingerprints()”、“input_fingerprints(1) ”和“identify_fingerprint (status_ID) ”的功能分别是:“删除ID为1的指纹”、“删除所有指纹”、“采集指纹,并将ID赋予为1”和“识别指纹“。删掉它们的注释,就可启动对应的功能。

2. “采集指纹”和“识别指纹”功能相比前文的流程多了“检测到手指按下”以及“判断流程是否执行成功”步骤。     

当模块的Vt引脚接3.3V时,WAK引脚会在手指按在模块采集处时输出高电平,此功能便可用来判断是否有手指按在模块采集处。    

确认码0x00表示指令成功执行,其余数值代表了不同的错误类型。鉴于此,判断录入或识别指纹的多步操作是否全部成功,可通过判断“一初值为0的数累加每一步操作得到的确认码”是否依然为0来实现。

main.c

#include "stm32f10x.h"                  
#include "AS608.h"
#include "Delay.h"

int main(void)
{
	AS608_Init();
	    
	//delete_fingerprint(1);
	//delete_all_fingerprints();

	while(1)
	{
		//input_fingerprints(1);
		//identify_fingerprint (status_ID);
		
		Delay_s(3);
	}	
}

AS608.c

#include "stm32f10x.h"
#include "AS608.h"
#include "USART3.h"
#include "serial.h"

uint8_t usart3_tx_hex[17];	//串口3发送的信息
uint8_t usart3_rx_hex[17];	//串口3接收的信息
uint8_t	check_code_flag = 0x00;		//校验和标志位,0表示校验正确,1表示校验错误
uint8_t status_ID[2];	//状态和ID号,status_ID[0]为0表示识别指纹成功,为1表示识别指纹失败;status_ID[1]为识别到的ID号
	
void AS608_Init(void)
{
	USART3_Init();
	
	Serial_Init();
	
	//用于判断手指是否已放置在采集处
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//
void input_image(void)	//录入图像
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x03;
	usart3_tx_hex[9] = 0x01;
	usart3_tx_hex[10] = 0x00;
	usart3_tx_hex[11] = 0x05;
	
	printf("正在录入图像\r\n");
	
	USART3_SendArray(usart3_tx_hex, 12);
	//在发送与接收之间不能停留太长时间,必须在数据发过来之前就先进入USART3_ReceiveArray(),然后卡死,直到收完所有传过来的数据
	USART3_ReceiveArray(usart3_rx_hex, 12);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		printf("录入图像成功\r\n");
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");
}

void generate_feature_and_store_in_buffer(uint8_t buffer_address)	//生成特征并存在指定缓存区
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x04;
	usart3_tx_hex[9] = 0x02;
	if (buffer_address == 1)
	{	usart3_tx_hex[10] = 0x01;
		usart3_tx_hex[11] = 0x00;
		usart3_tx_hex[12] = 0x08;
		printf("正在生成特征并存在缓存区1\r\n");
	}
	if (buffer_address == 2)
	{	usart3_tx_hex[10] = 0x02;
		usart3_tx_hex[11] = 0x00;
		usart3_tx_hex[12] = 0x09;
		printf("正在生成特征并存在缓存区2\r\n");
	}	
	
	USART3_SendArray(usart3_tx_hex, 13);
	
	USART3_ReceiveArray(usart3_rx_hex, 12);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		if (buffer_address == 1)
		{
			printf("生成特征并存在缓存区1成功\r\n");
		}
		if (buffer_address == 2)
		{
			printf("生成特征并存在缓存区2成功\r\n");
		}
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");
}

void accurately_compare_the_characteristics_of_two_fingerprints(void)	//精确比对两枚指纹特征
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x03;
	usart3_tx_hex[9] = 0x03;
	usart3_tx_hex[10] = 0x00;
	usart3_tx_hex[11] = 0x07;
	
	printf("正在精确比对两枚指纹特征\r\n");

	USART3_SendArray(usart3_tx_hex, 12);
	
	USART3_ReceiveArray(usart3_rx_hex, 14);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("%02X ", usart3_rx_hex[12]);
	printf("%02X ", usart3_rx_hex[13]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		printf("精确比对两枚指纹特征成功\r\n");
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");
}

void merge_features_and_generate_templates(void)	//合并特征并生成模板
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x03;
	usart3_tx_hex[9] = 0x05;
	usart3_tx_hex[10] = 0x00;
	usart3_tx_hex[11] = 0x09;
	
	printf("正在合并特征并生成模板\r\n");

	USART3_SendArray(usart3_tx_hex, 12);
	
	USART3_ReceiveArray(usart3_rx_hex, 12);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		printf("合并特征并生成模板成功\r\n");
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");
}

void save_template_to_buffer01_and_give_it_ID(uint8_t ID)	//储存模板到缓冲区01,并赋予ID。ID不要超过241
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x06;
	usart3_tx_hex[9] = 0x06;
	usart3_tx_hex[10] = 0x01;
	usart3_tx_hex[11] = 0x00;
	usart3_tx_hex[12] = ID;
	usart3_tx_hex[13] = 0x00;
	usart3_tx_hex[14] = 0x0E + ID;
	
	printf("正在储存模板到缓冲区01,并赋予ID:%d\r\n", ID);

	USART3_SendArray(usart3_tx_hex, 15);
	
	USART3_ReceiveArray(usart3_rx_hex, 12);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		printf("储存模板到缓冲区01,并赋予ID:%d成功\r\n", ID);
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");

}

uint8_t search_fingerprint (void)		//搜索指纹,返回识别到的ID
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x08;
	usart3_tx_hex[9] = 0x04;
	usart3_tx_hex[10] = 0x02;
	usart3_tx_hex[11] = 0x00;
	usart3_tx_hex[12] = 0x00;
	usart3_tx_hex[13] = 0x01;
	usart3_tx_hex[14] = 0x2C;
	usart3_tx_hex[15] = 0x00;
	usart3_tx_hex[16] = 0x3C;
	
	printf("正在搜索指纹\r\n");

	USART3_SendArray(usart3_tx_hex, 17);
	
	USART3_ReceiveArray(usart3_rx_hex, 16);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("%02X ", usart3_rx_hex[12]);
	printf("%02X ", usart3_rx_hex[13]);
	printf("%02X ", usart3_rx_hex[14]);
	printf("%02X ", usart3_rx_hex[15]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		printf("搜索指纹成功\r\n");
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");
	
	return usart3_rx_hex[11];	//识别到的ID
}

void delete_fingerprint(uint8_t ID)		//删除指定ID的指纹,ID不要超过234
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x07;
	usart3_tx_hex[9] = 0x0C;
	usart3_tx_hex[10] = 0x00;
	usart3_tx_hex[11] = ID;
	usart3_tx_hex[12] = 0x00;
	usart3_tx_hex[13] = 0x01;		//这里是删除(从指定的指纹算起)个数,可根据需要变为函数的输入参数
	usart3_tx_hex[14] = 0x00;
	usart3_tx_hex[15] = 0x15 + ID;
	
	printf("正在删除ID:%d的指纹\r\n", ID);

	USART3_SendArray(usart3_tx_hex, 16);
	
	USART3_ReceiveArray(usart3_rx_hex, 12);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		printf("删除ID:%d的指纹成功\r\n", ID);
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");
}

void delete_all_fingerprints(void)		//删除所有指纹
{
	usart3_tx_hex[0] = 0xEF;
	usart3_tx_hex[1] = 0x01;
	usart3_tx_hex[2] = 0xFF;
	usart3_tx_hex[3] = 0xFF;
	usart3_tx_hex[4] = 0xFF;
	usart3_tx_hex[5] = 0xFF;
	usart3_tx_hex[6] = 0x01;
	usart3_tx_hex[7] = 0x00;
	usart3_tx_hex[8] = 0x03;
	usart3_tx_hex[9] = 0x0D;
	usart3_tx_hex[10] = 0x00;
	usart3_tx_hex[11] = 0x11;
	
	printf("正在删除所有指纹\r\n");

	USART3_SendArray(usart3_tx_hex, 12);
	
	USART3_ReceiveArray(usart3_rx_hex, 12);		
	
	printf("收到的数据为:");
	printf("%02X ", usart3_rx_hex[0]);
	printf("%02X ", usart3_rx_hex[1]);
	printf("%02X ", usart3_rx_hex[2]);
	printf("%02X ", usart3_rx_hex[3]);
	printf("%02X ", usart3_rx_hex[4]);
	printf("%02X ", usart3_rx_hex[5]);
	printf("%02X ", usart3_rx_hex[6]);
	printf("%02X ", usart3_rx_hex[7]);
	printf("%02X ", usart3_rx_hex[8]);
	printf("%02X ", usart3_rx_hex[9]);
	printf("%02X ", usart3_rx_hex[10]);
	printf("%02X ", usart3_rx_hex[11]);
	printf("\r\n");
	
	if (usart3_rx_hex[9] == 0x00)
	{
		printf("删除所有指纹成功\r\n");
	}
	else 
	{
		check_code_flag = 0x01;
		printf("错误信息为:");
		printf("%02X \r\n", usart3_rx_hex[9]);
	}
	
	printf("\r\n");
}
/
void input_fingerprints(uint8_t ID)		//录入指纹
{
	printf("请放手指\r\n\r\n");
	
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1)	//如果手指已放置在采集处
	{
		input_image();//录入图像
		generate_feature_and_store_in_buffer(1);//生成特征,存在缓存区1
		input_image();//再次录入图像
		generate_feature_and_store_in_buffer(2);//生成特征,存在缓存区2
		accurately_compare_the_characteristics_of_two_fingerprints();//精确比对两枚指纹特征
		merge_features_and_generate_templates();//合并特征并生成模板
		save_template_to_buffer01_and_give_it_ID(ID);	//储存模板到缓冲区01,并赋予ID 
		
		if (check_code_flag == 0x00)
		{
			printf("录入指纹成功\r\n");
		}
		else 
		{
			printf("录入指纹失败\r\n");
			check_code_flag = 0x00;
		}
		
		printf("\r\n");
	}
}

void identify_fingerprint (uint8_t* status_ID)	//识别指纹,以数组形式返回是否识别成功以及识别到的ID
{	
	printf("请放手指\r\n\r\n");
	
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1)	//如果手指已放置在采集处
	{
		input_image();//录入图像
		generate_feature_and_store_in_buffer(2);//生成特征,存在缓存区2
		status_ID[1] = search_fingerprint();	//搜索指纹
		
		status_ID[0] = check_code_flag;
		if (check_code_flag == 0x00)
		{
			printf("识别指纹成功\r\n");
		}
		else 
		{
			printf("识别指纹失败\r\n");
			check_code_flag = 0x00;
		}
		
		printf("\r\n");
	}
}

AS608.h

#ifndef __AS608_H
#define __AS608_H

#include "stm32f10x.h"
	
extern uint8_t status_ID[2];

void AS608_Init(void);

void input_image(void);
void generate_feature_and_store_in_buffer(uint8_t buffer_address);
void accurately_compare_the_characteristics_of_two_fingerprints(void);
void merge_features_and_generate_templates(void);
void save_template_to_buffer01_and_give_it_ID(uint8_t ID);
uint8_t search_fingerprint (void);

void delete_fingerprint(uint8_t ID);
void delete_all_fingerprints(void);

void input_fingerprints(uint8_t ID);
void identify_fingerprint (uint8_t* status_ID);

#endif

USART3.c

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

void USART3_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
		
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 57600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART3, &USART_InitStructure);

	USART_Cmd(USART3, ENABLE);
}

void USART3_SendByte(uint8_t Byte)
{
	USART_SendData(USART3, Byte);
	while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
}

void USART3_SendArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		USART3_SendByte(Array[i]);
	}
}
/*
void USART3_SendString(char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i ++)
	{
		USART3_SendByte(String[i]);
	}
}

uint32_t USART3_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y --)
	{
		Result *= X;
	}
	return Result;
}

void USART3_SendNumber(uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i ++)
	{
		USART3_SendByte(Number / USART3_Pow(10, Length - i - 1) % 10 + '0');
	}
}


void USART3_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	USART3_SendString(String);
}



uint8_t USART3_GetRxFlag(void)
{
	if (USART3_RxFlag == 1)
	{
		USART3_RxFlag = 0;
		return 1;
	}
	return 0;
}

void USART3_IRQHandler(void)
{
	static uint8_t RxState = 0;
	static uint8_t pRxPacket = 0;
	if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART3);
		
		if (RxState == 0)
		{
			if (RxData == 0xFF)
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1)
		{
			USART3_RxPacket[pRxPacket] = RxData;
			pRxPacket ++;
			if (pRxPacket >= 4)
			{
				RxState = 2;
			}
		}
		else if (RxState == 2)
		{
			if (RxData == 0xFE)
			{
				RxState = 0;
				USART3_RxFlag = 1;
			}
		}
		
		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
	}
}
*/

uint8_t USART3_ReceiveByte(void)
{
	uint8_t Byte;
	while (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET);	//串口3收到数据会将其置1(SET)
	Byte = USART_ReceiveData(USART3);
	return Byte;
}

uint8_t* USART3_ReceiveArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		Array[i] = USART3_ReceiveByte();
	}
	return Array;
}

USART3.h

#ifndef __USART3_H
#define __USART3_H

#include <stdio.h>

void USART3_Init(void);
void USART3_SendByte(uint8_t Byte);
void USART3_SendArray(uint8_t *Array, uint16_t Length);
void USART3_SendString(char *String);
void USART3_SendNumber(uint32_t Number, uint8_t Length);
void USART3_Printf(char *format, ...);

uint8_t USART3_ReceiveByte(void);
uint8_t* USART3_ReceiveArray(uint8_t *Array, uint16_t Length);


uint8_t USART3_GetRxFlag(void);

#endif

serial.c

//串口1打印和输入

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

void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStructure);
		
	USART_Cmd(USART1, ENABLE);
}


void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	//当其置1(SET) 标志着串口1接收完成
}

//重定向c库函数printf到串口
int fputc(int ch, FILE *f)
{
	Serial_SendByte(ch);
	return ch;
}

uint8_t Serial_ReceiveByte(void)
{
	uint8_t Byte;
	Byte = USART_ReceiveData(USART1);
	while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);	//当其置1(SET) 标志着串口1发送完成
	return Byte;
}

//重定向c库函数scanf到串口,重写后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
    uint8_t ch;
    ch = Serial_ReceiveByte();
    return ch;
}

serial.h

//串口1打印提示信息

#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
uint8_t Serial_ReceiveByte(void);

#endif

现象

指纹录入成功现象

指纹识别成功现象

指纹删除成功现象

删除指定指纹

删除全部指纹

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值