1. 前言
随着信息科学技术的不断进步,信息科学技术已进入到了当今生活的方方面面,尤其是每个行业的经管领域,这类智能化信息技术处理是提高效率、从严管制、公平审查较为有效的方法。考勤登记,作为企业职工的基本管理,是对职工每日出勤管理的根本根据。但是,目前我国绝大多数企业在考勤登记时,依然利用的是古板的考勤方法,比如: 人工注册、打卡、机器打卡等,不光考勤速度较为缓慢,并且在考勤登记时候要专门职员在一边进行记载、统计数据、制成EXCEL表,而报表做完后最终交到主管手里时,有时候时间已过了好几天,根本不行,也不可以施展考勤真实的监视作用。并且还有可能呈现考勤数据不准确,考勤职员纪录犯错,乃至卖弄虚假的这种现象,极度破坏了企业对职工的日常管制。如今使用电脑来管制考勤的事情,很大程度上降低了就业人员的任务量,促使作事效率得以升高,使本来繁杂、索然无味的工作变的简单。提高中小型企业的考勤效率、体现现代化考勤的气氛。
设计总结:
(1)单片机采集指纹数据。将指纹ID传递给上位机进行管理。
(2)考勤记录、打卡全部在上位机完成。 单片机只是完成指纹的采集。
2. 硬件选型
2.1 STM32系统板
主控CPU采用STM32F103RCT6,这颗芯片包括48 KB SRAM、256 KB Flash、2个基本定时器、4个通用定时器、2个高级定时器、51个通用IO口、5个串口、2个DMA控制器、3个SPI、2个I2C、1个USB、1个CAN、3个12位ADC、1个12位DAC、1个SDIO接口,芯片属于大容量类型,配置较高,整体符合硬件选型设计。当前选择的这款开发板自带了一个1.4寸的TFT-LCD彩屏,可以显示当前传感器数据以及一些运行状态信息。
2.2 指纹模块
AS608指纹识别模块是?款?性能的光学指纹识别模块。AS608模块采?了国内著名指纹识别芯?公司杭州晟元芯?技术有限公司(Synochip)的 AS608指纹识别芯?。芯?内置DSP运算单元,集成了指纹识别算法,能?效快速采集图像并识别指纹特征。模块配备了串?、USB通讯接?,?户?需研究复杂的图像处理及指纹识别算法,只需通过简单的串?、USB 按照通讯协议便可控制模块。本模块可应?于各种考勤机、保险箱柜、指纹门禁系统、指纹锁等场合。
供电电压:3.3V(切勿接5V,容易烧毁芯片)
供电电流:< 60mA
指纹图像录入时间:< 1s
搜索时间:< 1.0s(1:500时,均值)
可录入指纹数量:300
通讯接口:USB/USART
3. 上位机程序设计
3.1 开发环境
上位机软件采用Qt框架设计,Qt是一个跨平台的C++图形用户界面应用程序框架。Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。简单来说,QT可以很轻松的帮你做带界面的软件,甚至不需要你投入很大精力。
QT官网: https://www.qt.io/
QT学习入门实战专栏文章: https://blog.csdn.net/xiaolong1126626497/category_11400392.html
QT5.12.6的下载地址: https://download.qt.io/archive/qt/5.12/5.12.6/
打开下载链接后选择下面的版本进行下载:
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
软件安装时断网安装,否则会提示输入账户。
安装的时候,第一个复选框里勾选一个mingw 32编译器即可,其他的不管默认就行,直接点击下一步继续安装。
选择MinGW 32-bit 编译器:
选择MinGW 32-bit 编译器:
3.2 设计效果
4. STM32程序设计
如果需要完整的资料,可以去这里下载: https://download.csdn.net/download/xiaolong1126626497/85896720
这是本项目演示视频:
4.1 程序下载
点击下载编程之后,按下开发板上的复位键,启动下载。
4.2 硬件接线
硬件连接方式:
1. 指纹模块接线
PA2(TX)---指纹模块的RX(白线)
PA3(RX)---指纹模块的TX(黄线)
VCC---3.3v(红线)
GND---GND(黑线)
VCC---3.3V(绿线)--触摸感应电源线
PA6---触摸感应线-高电平有效(蓝线)
2. 板载LED灯接线
LED1---PA8
LED2---PD2
3. 板载按键接线
K0---PA0
K1---PC5
K2---PA15
4.3 keil工程
4.4 通信协议约定
上位机下发指令:
$dev_cmd_lu_ru_zhi_wen:1
$dev_cmd_del_zhi_wen:1
设备上传指令:
$update_lu_ru_ok,
$update_lu_ru_error,
$update_find,1,
4.5 main.c代码
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include <string.h>
#include "timer.h"
#include <string.h>
#include <stdlib.h>
#include "as608.h"
u16 ValidN;
SysPara AS608Para;
void Add_FR(int ID);
void Del_FR(int num);
void press_FR(void);
void ShowErrMessage(u8 ensure);
int ID=0;
char *data_p;
int main()
{
u8 ensure;
u32 i=0;
u8 key=0;
u32 time_cnt=0;
JTAG_Set(JTAG_SWD_DISABLE);
LED_Init();
KEY_Init();
delay_init(72);
USART1_Init(115200);
TIMER1_Init(72,20000);
USART2_Init(57600);
TIMER2_Init(72,20000);
PS_StaGPIO_Init();
printf("系统正常运行!\r\n");
while(PS_HandShake(&AS608Addr))
{
printf("连接指纹模块失败....\r\n");
delay_ms(1000);
}
printf("指纹模块连接成功.....\r\n");
printf("开始读库指纹个数.\r\n");
ensure=PS_ValidTempleteNum(&ValidN);
if(ensure!=0x00)
{
printf("ensure:%s\r\n",ensure);
}
printf("开始读AS608模块参数 .\r\n");
ensure=PS_ReadSysPara(&AS608Para);
if(ensure==0x00)
{
printf("RemainNum:%d Level:%d\r\n",AS608Para.PS_max-ValidN,AS608Para.PS_level);
}
else
{
printf("ensure:%s\r\n",ensure);
}
while(1)
{
if(USART1_RX_FLAG)
{
USART1_RX_BUFFER[USART1_RX_CNT]='\0';
printf("RX:%s\r\n",USART1_RX_BUFFER);
if(strstr((char*)USART1_RX_BUFFER,"$dev_cmd_lu_ru_zhi_wen:"))
{
printf("开始录指纹 .\r\n");
data_p=strstr((char*)USART1_RX_BUFFER,"$dev_cmd_lu_ru_zhi_wen:");
if(data_p)
{
data_p+=strlen("$dev_cmd_lu_ru_zhi_wen:");
ID=atoi(data_p);
printf("ID=%d\r\n",ID);
if(ID>=0)
{
Add_FR(ID);
}
}
else
{
printf("指纹ID解析失败.\r\n");
}
}
if(strstr((char*)USART1_RX_BUFFER,"$dev_cmd_del_zhi_wen:"))
{
printf("开始录指纹 .\r\n");
data_p=strstr((char*)USART1_RX_BUFFER,"$dev_cmd_del_zhi_wen:");
if(data_p)
{
data_p+=strlen("$dev_cmd_del_zhi_wen:");
ID=atoi(data_p);
printf("ID=%d\r\n",ID);
if(ID>=0)
{
Del_FR(ID);
}
}
else
{
printf("指纹ID解析失败.\r\n");
}
}
USART1_RX_FLAG=0;
USART1_RX_CNT=0;
memset(USART1_RX_BUFFER,0,sizeof(USART1_RX_BUFFER));
}
press_FR();
LED1=!LED1;
delay_ms(100);
}
}
void Add_FR(int ID)
{
u8 i=0,ensure,processnum=0;
while(1)
{
switch (processnum)
{
case 0:
i++;
printf("请按下手指.\r\n");
ensure=PS_GetImage();
if(ensure==0x00)
{
ensure=PS_GenChar(CharBuffer1);
if(ensure==0x00)
{
printf("指纹正确.\r\n");
i=0;
processnum=1;
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
break;
case 1:
i++;
printf("再按一次手指.\r\n");
ensure=PS_GetImage();
if(ensure==0x00)
{
ensure=PS_GenChar(CharBuffer2);
if(ensure==0x00)
{
printf("指纹正确.\r\n");
i=0;
processnum=2;
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
break;
case 2:
printf("对比两次指纹.\r\n");
ensure=PS_Match();
if(ensure==0x00)
{
printf("两次指纹是一样的.\r\n");
processnum=3;
}
else
{
printf("对比失败,请重新按手指.\r\n");
ShowErrMessage(ensure);
i=0;
processnum=0;
}
delay_ms(1000);
break;
case 3:
printf("产生一个指纹模板.\r\n");
ensure=PS_RegModel();
if(ensure==0x00)
{
printf("生成指纹模板成功.\r\n");
processnum=4;
}else {processnum=0;ShowErrMessage(ensure);}
delay_ms(1000);
break;
case 4:
ensure=PS_StoreChar(CharBuffer2,ID);
if(ensure==0x00)
{
printf("$update_lu_ru_ok,\r\n");
printf("添加指纹成功.\r\n");
PS_ValidTempleteNum(&ValidN);
printf("显示剩余指纹个数.\r\n");
return ;
}else {processnum=0;ShowErrMessage(ensure);}
break;
}
delay_ms(1000);
LED2=!LED2;
if(i==10)
{
printf("超过10次没有按手指---退出...\r\n");
printf("$update_lu_ru_error,\r\n");
break;
}
}
}
void ShowErrMessage(u8 ensure)
{
printf("%s\r\n",(u8*)EnsureMessage(ensure));
}
void press_FR(void)
{
SearchResult seach;
u8 ensure;
char *str;
ensure=PS_GetImage();
if(ensure==0x00)
{
ensure=PS_GenChar(CharBuffer1);
if(ensure==0x00)
{
ensure=PS_HighSpeedSearch(CharBuffer1,0,300,&seach);
if(ensure==0x00)
{
printf("$update_find,%d,\r\n",seach.pageID);
printf("搜索指纹成功 .\r\n");
printf("Match ID:%d Match score:%d",seach.pageID,seach.mathscore);
}
else
ShowErrMessage(ensure);
}
else
ShowErrMessage(ensure);
delay_ms(1000);
}
}
void Del_FR(int num)
{
u8 ensure;
printf("显示删除指纹: %d.\r\n",num);
printf("0=< ID <=299\r\n");
delay_ms(50);
num=1;
if(num==0xFF00)
ensure=PS_Empty();
else
ensure=PS_DeletChar(num,1);
if(ensure==0)
{
printf("删除指纹成功.\r\n");
}
else
ShowErrMessage(ensure);
delay_ms(1500);
PS_ValidTempleteNum(&ValidN);
printf("显示剩余指纹个数:%d\r\n",AS608Para.PS_max-ValidN);
}
|