注:这是在STONE技术公司工作的Amy的一篇客座文章,STONE技术公司是一家专门从事工业液晶显示模块的公司。
2019年11月,我计划开发一个指纹门锁项目。当我选择好指纹识别模块时,项目就被暂停了。不过,我想既然已经购买了指纹识别模块,那还是简单地测试一下吧。
这个指纹模块轻易地就能在线购买,它通过UART接口与单片机板通信。另外,它可以支持指纹扫描、指纹输入、指纹比较和指纹删除等功能。
因为该指纹模块制造商为STM32F103系列微控制器提供了一个演示程序,所以我买了一个基于STM32F103C8T6的小型开发板。
指纹模块的演示程序一般使用LED灯提示用户输入指纹并比较其状态(成功或失败)。但我个人比较倾向用显示屏来提示用户和显示结果,因此我选择了480×272分辨率的串口显示屏。该屏通过UART可以与单片机进行通信,具体型号是STONE STVC050WT-01,这部分我会在后面的章节中介绍。
硬件组件
总共使用了三个硬件模块:
- STM32开发板
- 指纹模块
- STONE STVC050WT-01 显示屏
带有UART TTL接口的指纹识别模块

UART指纹读取器模块是由意法半导体公司的STM32F205高速数字处理器驱动的,它集成了指纹算法(TFS-9)和高精度光学传感器(TFS-d400),支持指纹输入、图像处理、特征值提取、模板生成、模板存储、指纹比较和搜索,并公开了一个由主微控制器或处理器驱动的UART接口。
特征
- 敏感指纹传感和快速识别速度:指纹模块采用高精度光学路径和成像元件,因此使用时只需用手即可。
- 稳定性好:该模块采用STM32F205 单片机,功耗低、速度快。速度和稳定性都比中国芯片好一些。
- “科学结构”:该模块采用模块化结构、指纹传感器+处理主板+算法平台。
- 标准16针通用接口:传感器可独立选择,由光学和其他传感器取代;使用商业算法。
- 易于开发:串口UART 操作(可以直接连接到任何带串口的单片机上)极其简单。微雪电子(waveshare)还提供了演示软件、学习软件、MCU程序以及相关工具。
- 开放性:免费输入和输出指纹图片、指纹特征值文件和各种指纹操作。
应用场景
典型的应用程序包括指纹锁、指纹保险箱、指纹访问控制、指纹出勤、对讲机、人员识别、权限管理等。指纹模块可以在全球速卖通上购买,售价是36美元。
STONE 5英寸STVC050WT-01 4:3 TFT-LCD 模块
480×272 TFT 显示屏介绍
在这个项目中,我想使用STONE STVC050WT-01 TFT-LCD 来显示指纹模块的状态(包括输入状态、比较状态和指纹数据删除)。此显示屏配有驱动芯片,且能为用户界面开发提供开发软件。所以,用户只需根据需要通过软件以及任何按钮或文本框添加设计的 UI 图片,然后生成配置文件并以闪存形式接入显示屏。
STONE STVC050WT-01显示屏通过UART TTL信号与MCU通信。
从理论上来说,STONE显示屏和指纹模块硬件是可以直接连接的。但是,由于通信数据协议不同,无法建立通信。所以,仍需要MCU来处理串口通信。

更多的技术信息,包括数据表都可以在产品页面获取,该模块以37.78美元的价格在全球速卖通上售卖 。
使用STONE 显示屏模块只需要4 步
- 使用 PhotoShop 或其他照片编辑软件设计用户显示界面。
- 使用STONE TOOL软件设计显示逻辑和按钮逻辑,并将设计文件下载到显示模块中。
- MCU通过串口与STONE 显示屏模块进行通信。
- 第 3 步获得的数据应使用在MCU的其他操作中。
STONE TOOL软件安装
从官方网站下载最新版本的STONE TOOL软件(当前为是 TOOL 2019版)并安装。
软件安装完成后,将会打开以下界面:

单击左上角的“文件”按钮以创建新项目,具体项目将会在下面部分进行介绍。
STM32 单片机开发板
我们使用基于STM32F103C8T6 MCU的开发板,该开发板可以在全球速卖通上通过快递购买,售价低于2美元。

STM32开发环境
Keil vision是由Keil开发的集成开发环境。目前,主要有Vision2、Vision3、Vision4和Vision5几个版本。其实这当中是有一些故事的。2005年,Keil被Arm收购。2011年3月,Arm发布了最新集成开发环境的Realview MDK开发工具,该工具其实是集成了Keil uvision4的最新版本,其编译器和调试工具主要针对Arm设备进行了优化。
STM32使用KEIL MDK开发环境的具体情况,可以在该公司网站上找到。
STONE 显示屏和指纹模块测试项目的实现
开发板与STONE 显示屏的硬件连接
为了确保以后可以编写代码,我们首先必须确定硬件连接是可靠的。
STM32F103C8T6开发板和STVC050WT-01 TFT 显示屏通过UART连接,STM32F103C8T6开发板和指纹模块也可以通过UART连接。
确保硬件连接正确之后,继续下一步。
UI图形设计只需一步
首先,我们需要设计一个UI显示图像,它可以用PhotoShop软件或其他图像设计工具进行设计。UI 显示图像设计完成后,要将图像保存为 JPG 格式。(下图是我在Photoshop设计的UI 图像)

TFT -LCD显示模块设计
打开STONE TOOL2019 软件,并创建一个新项目:


删除新项目加载的默认图像,并添加我们自己设计的 UI 图像。
如何通过STONE TOOL工具添加字体文件

UI 设计时,会出现一个实时显示指纹验证的状态栏,因此你需要添加字体以及文本显示组件和按钮。
效果如下:

如何生成STONE LCD的配置文件
完成上述 UI 设计后,你可以生成配置文件并将其下载到 STVC050WT-01 显示屏上,在 STONE 开发材料中对该显示屏进行过描述。

执行步骤 1 :生成配置文件,然后将 U盘插入计算机,U盘就会显示出来。
步骤2:然后单击“下载到您磁盘”,将配置文件下载到 U盘中,之再将 U盘插入 STVC050WT-01 中以完成升级。
如何通过 UART TTL接口连接指纹模块
指纹模块实际上由两部分组成:
- 光学收集器
- 驱动电路
核心部分是驱动电路,且由STM32F2系列芯片集成。该芯片将指纹算法和扫描算法嵌入到芯片中,并采用UART通信来获取结果,这为应用程序的开发人员提供了非常方便的条件。
硬件连接:
VCC— 3.3 v或5v
GND — GND
TXD(指纹模块串口发送)— RXD(PC或单片机串口Rx)
RXD(指纹模块串口接收)— TXD(PC或单片机串口Tx)
BL(指纹头背光,未连接)— IO端口
RST(指纹模块重置,未连接)— IO端口
第一时,你可以使用 Windows PC 通过串口与指纹模块进行通信,从而进行测试。你们也可以在微雪百科中上找到更多的细节信息。
STM32 应用开发
你们可以访问指纹模块供应商的官方网站,下载指纹模块演示程序,然后使用KEIL软件打开程序。
在进一步开发软件之前,我们先来连接一下硬件。

然后通过串口控制台发送指令的方式检查连接是否能正常工作。

我用最终代码(main.c)对程序做了一些小修改,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
#include <stm32f10x.h> #include "usart.h" #include "timer.h" #include "fingerprint.h" #define ADDUSER_BTN_ADDR 0x01 #define VERIFY_BTN_ADDR 0x05 #define CLEAR_BTN_ADDR 0x09 #define TEXT_STATUS_ADDR 0x0c #define USER_SUCESS 0x01 #define USER_FAIL 0X00 u8 data_send[8]= {0xA5, 0x5A, 0x05, 0x82, 0x00, 0x00, 0x00,0x00}; void delay() { u16 i, j; for (i = 0; i < 1000; i++) for(j = 0; j < 10000; j++); } //void USERGPIO_Init(void) //{ // GPIO_InitTypeDef GPIO_InitStructure; // // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE); // // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO_Init(GPIOF, &GPIO_InitStructure); // GPIO_ResetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9); // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_8; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // GPIO_Init(GPIOG, &GPIO_InitStructure); // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // GPIO_Init(GPIOC, &GPIO_InitStructure); //} //u8 key_scan(void) //{ // if(!USER_KEY||!PRESS_KEY||!DEL_KEY) // { // delay(); // if(!USER_KEY) return 1; // if(!PRESS_KEY) return 2; // if(!DEL_KEY) return 3; // } // return 0; //} void UART1_Send_Array(u8 send_array[],unsigned char num) { u8 i=0; while(i<num) { USART_SendData(USART1,send_array[i]); while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET); i++; } } extern u8 USART_RX_BUF[10]; extern u8 USART_RX_END; extern u16 USART_RX_STA; int main(void) { int i = 5; SystemInit(); // USERGPIO_Init(); usart_Configuration(115200,19200); //Ö¸ÎÆÄ£¿éĬÈÏÊÇ19200 // printf("Test Uart Fingerprint Reader\r\n"); SetcompareLevel(5); // printf("compare level£º%d\r\n", GetcompareLevel()); // printf("time out£º%d\r\n",GetTimeOut()); // printf("total user:%d\r\n",GetUserCount()); while(1) { if(USART_RX_END) { //UART1_Send_Array(USART_RX_BUF,8); switch (USART_RX_BUF[5]) { case ADDUSER_BTN_ADDR: //printf("User:%d\r\n",GetUserCount()); switch(AddUser(i)) { case ACK_SUCCESS: i++; //printf("finger add success\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_SUCESS; UART1_Send_Array(data_send,8); LED2_ON; delay(); LED2_OFF; break; case ACK_FAIL: //printf("fail\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_FAIL; UART1_Send_Array(data_send,8); LED3_ON; delay(); LED3_OFF; break; case ACK_FULL: //printf("full\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_FAIL; UART1_Send_Array(data_send,8); LED4_ON; delay(); LED4_OFF; break; } break; case VERIFY_BTN_ADDR: switch(VerifyUser()) { case ACK_SUCCESS: //printf("Verify sucess\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_SUCESS; UART1_Send_Array(data_send,8); LED2_ON; delay(); LED2_OFF; break; case ACK_NO_USER: //printf("NO_USER\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_FAIL; UART1_Send_Array(data_send,8); LED3_ON; delay(); LED3_OFF; break; case ACK_TIMEOUT: //printf("time out\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_FAIL; UART1_Send_Array(data_send,8); LED3_ON; delay(); LED3_OFF; break; case ACK_GO_OUT: //printf("GO OUT\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_FAIL; UART1_Send_Array(data_send,8); break; }; break; case CLEAR_BTN_ADDR: ClearAllUser(); //printf("all user remove\r\n"); data_send[5]=TEXT_STATUS_ADDR; data_send[7]=USER_SUCESS; UART1_Send_Array(data_send,8); break; default: USART_RX_END=0; USART_RX_STA=0; } USART_RX_END=0; USART_RX_STA=0; } } } |
我们还必须要修改stm32f10x_it.c文件,以此来添加 USART 中断处理函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
u16 USART_RX_STA=0; u8 USART_RX_END=0; u8 USART_RX_BUF[10]; void USART1_IRQHandler(void) { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { Res =USART_ReceiveData(USART1); //printf("%x",USART_ReceiveData(USART1)); // USART_SendData(USART1,Res); if(USART_RX_END==0) { USART_RX_BUF[USART_RX_STA]=Res ; USART_RX_STA++; if(USART_RX_STA>8) { USART_RX_END=1; } } } } |
最终结果
最后,我们只需要连接STM32板、指纹模块、显示屏幕和电源。而后按下 STONE 显示屏上方对应的按钮,你应该就能够添加、删除和验证指纹了。


文章翻译者:Taylor Lee,瑞科慧联(RAK)高级嵌入式开发工程师,有丰富的物联网和开源软硬件经验,熟悉行业主流软硬件框架,对行业发展动向有着敏锐的感知力和捕捉能力。