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
接线
AS608 | USB-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