🎀 文章作者:二土电子
🌸 关注公众号获取完整程序工程!
🐸 期待大家一起学习交流!
文章目录
一、项目简介
本项目基于STM32F103C8T6和指纹识别模块设计了一个门禁系统,主要功能有:指纹识别、指纹添加和指纹删除。
🔧软件工具:Keil5、串口助手
二、硬件简介
- 主控:STM32F103C8T6核心板
- 指纹模块:ZW101
- 三个独立按键,一端接地
- USB-TTL,用于输出信息
2.1 指纹模块简介
ZW101是一款一体化半导体指纹处理模组,由主动式半导体指纹采集SENSOR和指纹识别处理芯片构成。
指纹识别算法芯片采用高性能、低功耗riscv内核,运行360度自适应自学习算法。半导体Sensor采用主动式射频采集方式,支持低功耗手指检测,省去外挂手指触摸检测芯片,集成度高,产品结构简单,提高了产品的稳定性和一致性。同时提供七彩灯效果,可根据用户需求定制不同颜色以及显示方式。
2.2 引脚分配
首先我们看一下指纹模块的各个引脚
引脚序号 | 引脚名称 | 引脚功能 |
---|---|---|
1 | V_Touch | 触摸功能供电引脚 |
2 | TouchOut | 触摸检测引脚,有触摸输出1,没触摸输出0 |
3 | VCC | 电源引脚 |
4 | TX | 发送引脚 |
5 | RX | 接收引脚 |
6 | GND | 地 |
下面是整个项目的引脚分配
引脚 | 对应IO |
---|---|
V_Touch | 3.3V |
TouchOut | PA0 |
TX | PA3 |
RX | PA2 |
添加按键 | PA5 |
删除按键 | PA6 |
清空指纹库按键 | PA7 |
三、软件设计思路
3.1 添加指纹
ZW101添加指纹流程如下
发送验证获取图像指令 —返回成功—> 上传4bit图像 —返回成功—> 生成特征 —返回成功—> 储存模板
在生成指纹模板时我们需要设定指纹ID号、录入次数,就是每次生成一个指纹信息需要录入几次,就类似于我们身份证添加指纹信息的时候需要抬起来放下好多次一样,是为了更加精准。
上面的步骤每一步都需要发送对应的指令,为了简化生成指纹模板的步骤,通信协议中还提供了一个自动注册模板的指令,可以直接使用该指令生成模板,非常方便。
3.2 删除指纹
删除指纹比较简单,只需要一条指令,指令中包含有要删除指纹的ID即可,详细信息在通信协议中都可以找到。
3.3 指纹识别
ZW101指纹识别流程如下
读出模板 ——> 获取验证图像 ——> 上传4bit图像 ——> 生成特征 ——> 精确比对两枚指纹特征
与添加指纹相同,为了简化指纹识别过程,通信协议手册中提供了一个指令可以直接实现指纹识别。
四、程序设计
4.1 添加指纹
添加指纹函数支持用户输出要添加指纹的ID以及录入次数,在等待指纹模块和回复时使用while循环,为了防止指纹模块长时间没有返回信息导致系统陷入死循环,添加了超时检测,在规定时间内没有得到指纹模块的回复信息会自动跳出循环。
/*
*==============================================================================
*函数名称:Med_Zw101_AddFinger
*函数功能:ZW101添加指纹
*输入参数:id:指纹ID号;cunt:录入次数
*返回值:0:失败;1:成功
*备 注:无
*==============================================================================
*/
u8 Med_Zw101_AddFinger (u8 id,u8 cunt)
{
u8 flag = 0;
u8 timeOut = 0; // 超时计数变量
u8 data[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x31,0x00,0x00,0x05,0x00,0x04,0x00,0x43};
data[11] = id;
data[12] = cunt;
data[16] = 0x3E + id + cunt;
// 发送指令
USART2_Send(data,17);
// 等待接收完应答数据
while (!gUsart2EndFlag)
{
timeOut ++;
if (timeOut >= 5000)
break;
delay_ms(1);
}
if (gUsart2EndFlag == 1)
{
if (USART2_RECEFIFO[9] == 0x00 && USART2_RECEFIFO[10] == 0x06 && USART2_RECEFIFO[11] == 0xF2)
flag = 1;
gUsart2EndFlag = 0;
}
return flag;
}
4.2 指纹识别
指纹识别函数会自动将当前指纹与指纹库内全部指纹进行比较并返回比较结果信息。
/*
*==============================================================================
*函数名称:Med_Zw101_IdentifyFinger
*函数功能:ZW101识别指纹
*输入参数:无
*返回值:0:失败;1:成功
*备 注:无
*==============================================================================
*/
u8 Med_Zw101_IdentifyFinger (void)
{
u8 flag = 0;
u8 timeOut = 0; // 超时计数变量
u8 data[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x32,0x02,0xFF,0xFF,0x00,0x05,0x02,0x40};
// 发送指令
USART2_Send(data,17);
// 等待接收完应答数据
while (!gUsart2EndFlag)
{
timeOut ++;
if (timeOut >= 2000)
break;
delay_ms(1);
}
if (gUsart2EndFlag == 1)
{
if (USART2_RECEFIFO[9] == 0x00)
flag = 1;
gUsart2EndFlag = 0;
}
return flag;
}
4.3 删除指纹
删除指纹函数支持用户输出要删除指纹的ID
/*
*==============================================================================
*函数名称:Med_Zw101_DeleteFinger
*函数功能:ZW101删除指纹
*输入参数:id:要删除的指纹ID
*返回值:0:失败;1:成功
*备 注:无
*==============================================================================
*/
u8 Med_Zw101_DeleteFinger (u8 id)
{
u8 flag = 0;
u8 timeOut = 0; // 超时计数变量
u8 data[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x0C,0x00,0x00,0x00,0x01,0x00,0x15};
data[11] = id;
data[15] = 0x15 + id;
// 发送指令
USART2_Send(data,16);
// 等待接收完应答数据
while (!gUsart2EndFlag)
{
timeOut ++;
if (timeOut >= 50)
break;
delay_ms(1);
}
if (gUsart2EndFlag == 1)
{
if (USART2_RECEFIFO[9] == 0x00)
flag = 1;
gUsart2EndFlag = 0;
}
return flag;
}
4.4 业务函数
下面是整个ZW101的业务函数,能够根据按下按键实现添加指纹
删除指纹和清空指纹库功能,并且能够通过串口输出全部调试信息
/*
*==============================================================================
*函数名称:App_Zw101_Task
*函数功能:ZW101业务函数
*输入参数:无
*返回值:无
*备 注:无
*==============================================================================
*/
void App_Zw101_Task (void)
{
u8 keyValue = 0;
u8 timeOut = 0; // 超时计数变量
keyValue = Med_KeyScan();
switch (keyValue)
{
case 0xAD:
printf ("Add a fingerprint!\r\n");
printf ("Please enter the fingerprint ID you want to add\r\n");
// 等待接收到输入的指纹编号
while (!gUsart1EndFlag)
{
timeOut ++;
if (timeOut >= 1000)
break;
delay_ms(1);
}
if (gUsart1EndFlag)
{
if ((USART1_RECEFIFO[0] - 48) <= 0xFF)
{
if (Med_Zw101_AddFinger(USART1_RECEFIFO[0] - 48,5))
{
printf ("The addition is successful, and the ID number is %d\r\n",USART1_RECEFIFO[0] - 48);
}
else
printf ("Failed to add!\r\n");
}
else
printf ("The fingerprint ID was entered incorrectly!\r\n");
gUsart1EndFlag = 0;
}
else
printf ("The fingerprint ID is not entered!\r\n");
break;
case 0xDE:
printf ("Delete a fingerprint!\r\n");
printf ("Please enter the fingerprint ID you want to remove\r\n");
// 等待接收到输入的指纹编号
while (!gUsart1EndFlag)
{
timeOut ++;
if (timeOut >= 1000)
break;
delay_ms(1);
}
if (gUsart1EndFlag)
{
if ((USART1_RECEFIFO[0] - 48) <= 0xFF)
{
if (Med_Zw101_DeleteFinger(USART1_RECEFIFO[0] - 48))
{
printf ("The delete is successful, and the ID number is %d\r\n",USART1_RECEFIFO[0] - 48);
}
else
printf ("Failed to delete!\r\n");
}
else
printf ("The fingerprint ID was entered incorrectly!\r\n");
gUsart1EndFlag = 0;
}
else
printf ("The fingerprint ID is not entered!\r\n");
break;
case 0x55:
if (Med_Zw101_EmptyFinger())
printf ("The fingerprint database was emptied!\r\n");
break;
case 0xFF:
if (TOUCH == 1)
{
if (Med_Zw101_IdentifyFinger())
printf ("Fingerprints are in the library!\r\n");
else
printf ("Fingerprints are not in the library!\r\n");
}
break;
default:
break;
}
}
五、使用方法
首先要确保接线正确,指纹模块正常状态下是蓝色呼吸灯常量,在没有任何按键按下时默认处于指纹识别模式
-
指纹识别
将手指放到指纹识别区域会自动进行指纹识别,如果指纹与库内指纹匹配会返回正确信息并且模块亮绿灯,如果没有匹配的指纹,模块会闪红灯并输出提示信息 -
添加指纹
按下添加指纹按键时会提示进入添加指纹模式并提示输入要添加的指纹ID,直接输入即可,需要注意的是最多支持添加50枚指纹,而且不支持覆盖功能,就是说已经用过的ID在没有清除的情况下是无法重复添加指纹的,添加成功后会返回提示信息。 -
删除指纹
按下删除指纹按键会提示进入删除指纹模式并提示输入要删除的指纹ID,发送后会返回提示信息。 -
清空指纹库
与删除指纹类似。