STM32CubeIDE实战基于AS608光学指纹模块的智能门锁原型开发在物联网和智能家居快速发展的今天生物识别技术正逐渐成为身份认证的主流方案。指纹识别因其唯一性和便捷性被广泛应用于门禁系统、智能锁具等场景。本文将带你使用STM32CubeIDE开发环境结合AS608光学指纹模块从零开始构建一个具备完整功能的智能门锁原型系统。1. 硬件系统架构设计一个完整的智能门锁原型需要多个硬件模块协同工作。我们的系统将采用模块化设计思路确保各功能单元既能独立测试又能无缝集成。核心组件清单STM32F103C8T6最小系统板Blue PillAS608光学指纹识别模块5V继电器模块模拟电子锁0.96寸OLED显示屏SSD1306驱动有源蜂鸣器反馈提示音LED指示灯红/绿双色薄膜按键开关4向导航键硬件连接示意图如下表示外设模块STM32引脚连接方式AS608 TXPA3USART2_RXAS608 RXPA2USART2_TXOLED SCLPB6I2C1_SCLOLED SDAPB7I2C1_SDA继电器控制线PB8GPIO输出蜂鸣器控制PE5GPIO输出红色LEDPB5GPIO输出绿色LEDPB8GPIO输出按键UPPA0GPIO输入(上拉)按键DOWNPA1GPIO输入(上拉)按键ENTERPA4GPIO输入(上拉)按键BACKPA5GPIO输入(上拉)注意AS608模块需要单独5V电源供电确保指纹采集时电流充足。所有GPIO输入引脚都应配置内部上拉电阻避免悬空状态。2. 开发环境配置与工程搭建STM32CubeIDE作为ST官方推出的集成开发环境提供了从硬件配置到代码生成的一站式解决方案。以下是关键配置步骤新建STM32CubeIDE工程选择STM32F103C8Tx系列芯片配置时钟树HSE 8MHz外部晶振系统时钟设置为72MHzAPB1总线时钟36MHzAPB2总线时钟72MHz外设初始化USART2115200波特率8位数据无校验I2C1标准模式(100kHz)所有使用到的GPIO按上表配置// 关键时钟配置代码自动生成 void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct {0}; RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9; HAL_RCC_OscConfig(RCC_OscInitStruct); RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1; HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2); }3. AS608指纹模块驱动开发AS608通过UART接口通信采用特定的数据包协议。我们需要实现完整的指令集封装以下是指令处理的核心函数// AS608指令发送通用函数 uint8_t AS608_SendCmd(uint8_t cmd, uint8_t *param, uint16_t param_len, uint8_t *response) { uint8_t checksum 0x01 cmd (param_len 8) (param_len 0xFF); uint8_t pkg[12 param_len]; // 构建数据包 pkg[0] 0xEF; pkg[1] 0x01; // 包头 memcpy(pkg[2], AS608_Addr, 4); // 地址 pkg[6] 0x01; // 包标识(命令包) pkg[7] param_len 8; // 长度高字节 pkg[8] param_len 0xFF; // 长度低字节 pkg[9] cmd; // 指令码 memcpy(pkg[10], param, param_len); // 参数 // 计算校验和 for(int i0; iparam_len; i) checksum param[i]; pkg[10param_len] checksum 8; pkg[11param_len] checksum 0xFF; // 发送数据包 HAL_UART_Transmit(huart2, pkg, sizeof(pkg), 100); // 等待响应(超时300ms) return AS608_WaitResponse(response, 300); }指纹处理流程通常包括图像采集、特征生成、模板存储和匹配搜索四个关键步骤。我们将其封装为高阶API// 完整指纹录入流程 uint8_t AS608_EnrollFingerprint(uint16_t pageID) { uint8_t ret; // 第一次采集 if((ret AS608_GetImage()) ! 0x00) return ret; if((ret AS608_GenChar(CharBuffer1)) ! 0x00) return ret; // 第二次采集 if((ret AS608_GetImage()) ! 0x00) return ret; if((ret AS608_GenChar(CharBuffer2)) ! 0x00) return ret; // 特征比对与合并 if((ret AS608_Match()) ! 0x00) return ret; if((ret AS608_RegModel()) ! 0x00) return ret; // 存储模板 return AS608_StoreChar(CharBuffer2, pageID); } // 指纹验证流程 uint8_t AS608_VerifyFingerprint(uint16_t *pageID, uint16_t *score) { uint8_t ret; SearchResult result; if((ret AS608_GetImage()) ! 0x00) return ret; if((ret AS608_GenChar(CharBuffer1)) ! 0x00) return ret; if((ret AS608_HighSpeedSearch(CharBuffer1, 0, 300, result)) ! 0x00) return ret; *pageID result.pageID; *score result.mathscore; return 0x00; }4. 用户界面与系统逻辑实现智能门锁需要友好的用户交互界面。我们使用OLED显示屏和按键实现菜单导航状态机模型管理不同操作模式。系统状态机设计stateDiagram [*] -- 待机模式 待机模式 -- 验证模式: 手指放置 待机模式 -- 管理菜单: 长按BACK键 验证模式 -- 开锁成功: 指纹匹配 验证模式 -- 开锁失败: 指纹不匹配 管理菜单 -- 录入子菜单: 选择添加指纹 管理菜单 -- 删除子菜单: 选择删除指纹 录入子菜单 -- 录入流程: 选择ID 删除子菜单 -- 删除确认: 选择IDOLED显示驱动采用分层设计底层硬件抽象层提供基本绘图函数上层实现菜单渲染// 菜单项结构体 typedef struct { const char* text; uint8_t icon; void (*action)(void); } MenuItem; // 主菜单定义 MenuItem mainMenu[] { {验证指纹, ICON_FINGERPRINT, NULL}, {添加指纹, ICON_PLUS, EnterEnrollMode}, {删除指纹, ICON_TRASH, EnterDeleteMode}, {系统设置, ICON_GEAR, NULL} }; // 菜单渲染函数 void RenderMenu(MenuItem *menu, uint8_t count, uint8_t selected) { OLED_Clear(); for(uint8_t i0; icount; i) { // 绘制选中项背景 if(i selected) OLED_DrawRect(0, i*16, 128, 16, FILL); // 绘制图标和文字 OLED_DrawIcon(2, i*162, menu[i].icon, iselected?BLACK:WHITE); OLED_DrawString(20, i*164, menu[i].text, iselected?BLACK:WHITE); } OLED_Update(); }按键处理采用中断驱动方式通过状态机消除抖动并识别长短按// 按键事件处理 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static uint32_t pressTime[5] {0}; uint8_t keyIdx GetKeyIndex(GPIO_Pin); if(HAL_GPIO_ReadPin(GPIO_Pin) GPIO_PIN_RESET) { // 按下事件 pressTime[keyIdx] HAL_GetTick(); } else { // 释放事件 uint32_t duration HAL_GetTick() - pressTime[keyIdx]; if(duration 20) { // 消抖 if(duration 1000) { PostKeyEvent(keyIdx, KEY_SHORT_PRESS); } else { PostKeyEvent(keyIdx, KEY_LONG_PRESS); } } } }5. 系统集成与功能测试将所有模块集成后我们需要实现完整的门锁控制逻辑。系统上电后进入待机模式通过状态转换实现不同功能。开锁成功处理流程指纹验证通过后启动继电器控制电路绿色LED点亮蜂鸣器发出短促滴声OLED显示欢迎信息保持开锁状态3秒后自动复位void HandleUnlockSuccess(uint16_t userID) { // 驱动继电器开锁 HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_SET); // 绿色LED指示 HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET); // 蜂鸣器提示 Beep(200, 100); // 显示欢迎信息 char welcomeMsg[20]; sprintf(welcomeMsg, 欢迎 #%03d, userID); OLED_ShowMessage(welcomeMsg, 门锁已开启, 3000); // 延时后恢复 HAL_Delay(3000); HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET); }指纹管理功能实现指纹数据库管理需要特别注意数据安全性和操作确认机制。删除操作前必须二次确认防止误操作。void DeleteFingerprint(uint16_t pageID) { char confirmMsg[32]; sprintf(confirmMsg, 确认删除ID:%03d?, pageID); // 显示确认对话框 if(OLED_ShowDialog(警告, confirmMsg, 取消, 确认) DIALOG_RESULT_YES) { uint8_t ret AS608_DeletChar(pageID, 1); if(ret 0x00) { OLED_ShowMessage(操作成功, 指纹已删除, 1500); Beep(100, 50); Beep(100, 50); } else { ShowAS608Error(ret); } } }6. 进阶优化与扩展思路基础功能实现后可以考虑以下增强功能提升系统实用性1. 多用户权限管理实现用户分级管理员/普通用户管理员可添加/删除其他用户指纹记录操作日志到AS608的记事本区域#define USER_ROLE_NORMAL 0 #define USER_ROLE_ADMIN 1 typedef struct { uint16_t fingerprintID; uint8_t role; char name[16]; } UserProfile; UserProfile userDB[MAX_USERS]; uint8_t adminCount 0; uint8_t AddUserWithRole(uint16_t fid, uint8_t role, const char* name) { if(role USER_ROLE_ADMIN adminCount 3) return ERR_TOO_MANY_ADMINS; // 添加到内存数据库 userDB[userCount].fingerprintID fid; userDB[userCount].role role; strncpy(userDB[userCount].name, name, 15); if(role USER_ROLE_ADMIN) adminCount; userCount; return SUCCESS; }2. 防拆报警功能利用STM32的GPIO检测机壳开关触发后启动蜂鸣器报警并记录事件需要管理员指纹才能解除报警状态3. 低功耗优化空闲时进入STOP模式降低功耗通过RTC定时唤醒检查按键指纹模块配置为自动休眠模式void EnterLowPowerMode(void) { // 关闭外设时钟 __HAL_RCC_GPIOA_CLK_DISABLE(); __HAL_RCC_GPIOB_CLK_DISABLE(); // 保留唤醒引脚时钟 __HAL_RCC_GPIOC_CLK_ENABLE(); // 配置唤醒源 HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); // 进入STOP模式 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后系统时钟重新配置 SystemClock_Config(); }4. 无线扩展接口预留蓝牙/Wi-Fi模块接口通过AT指令实现远程状态查询添加加密通信保障安全性实际开发中发现AS608模块在强光直射环境下识别率会下降。解决方法是在指纹采集窗口周围增加遮光橡胶圈或者在软件上增加图像质量检测拒绝低质量指纹图像。
STM32CubeIDE项目实战:用AS608光学指纹模块做个智能门锁原型(附完整工程)
发布时间:2026/6/11 2:38:33
STM32CubeIDE实战基于AS608光学指纹模块的智能门锁原型开发在物联网和智能家居快速发展的今天生物识别技术正逐渐成为身份认证的主流方案。指纹识别因其唯一性和便捷性被广泛应用于门禁系统、智能锁具等场景。本文将带你使用STM32CubeIDE开发环境结合AS608光学指纹模块从零开始构建一个具备完整功能的智能门锁原型系统。1. 硬件系统架构设计一个完整的智能门锁原型需要多个硬件模块协同工作。我们的系统将采用模块化设计思路确保各功能单元既能独立测试又能无缝集成。核心组件清单STM32F103C8T6最小系统板Blue PillAS608光学指纹识别模块5V继电器模块模拟电子锁0.96寸OLED显示屏SSD1306驱动有源蜂鸣器反馈提示音LED指示灯红/绿双色薄膜按键开关4向导航键硬件连接示意图如下表示外设模块STM32引脚连接方式AS608 TXPA3USART2_RXAS608 RXPA2USART2_TXOLED SCLPB6I2C1_SCLOLED SDAPB7I2C1_SDA继电器控制线PB8GPIO输出蜂鸣器控制PE5GPIO输出红色LEDPB5GPIO输出绿色LEDPB8GPIO输出按键UPPA0GPIO输入(上拉)按键DOWNPA1GPIO输入(上拉)按键ENTERPA4GPIO输入(上拉)按键BACKPA5GPIO输入(上拉)注意AS608模块需要单独5V电源供电确保指纹采集时电流充足。所有GPIO输入引脚都应配置内部上拉电阻避免悬空状态。2. 开发环境配置与工程搭建STM32CubeIDE作为ST官方推出的集成开发环境提供了从硬件配置到代码生成的一站式解决方案。以下是关键配置步骤新建STM32CubeIDE工程选择STM32F103C8Tx系列芯片配置时钟树HSE 8MHz外部晶振系统时钟设置为72MHzAPB1总线时钟36MHzAPB2总线时钟72MHz外设初始化USART2115200波特率8位数据无校验I2C1标准模式(100kHz)所有使用到的GPIO按上表配置// 关键时钟配置代码自动生成 void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct {0}; RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9; HAL_RCC_OscConfig(RCC_OscInitStruct); RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1; HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2); }3. AS608指纹模块驱动开发AS608通过UART接口通信采用特定的数据包协议。我们需要实现完整的指令集封装以下是指令处理的核心函数// AS608指令发送通用函数 uint8_t AS608_SendCmd(uint8_t cmd, uint8_t *param, uint16_t param_len, uint8_t *response) { uint8_t checksum 0x01 cmd (param_len 8) (param_len 0xFF); uint8_t pkg[12 param_len]; // 构建数据包 pkg[0] 0xEF; pkg[1] 0x01; // 包头 memcpy(pkg[2], AS608_Addr, 4); // 地址 pkg[6] 0x01; // 包标识(命令包) pkg[7] param_len 8; // 长度高字节 pkg[8] param_len 0xFF; // 长度低字节 pkg[9] cmd; // 指令码 memcpy(pkg[10], param, param_len); // 参数 // 计算校验和 for(int i0; iparam_len; i) checksum param[i]; pkg[10param_len] checksum 8; pkg[11param_len] checksum 0xFF; // 发送数据包 HAL_UART_Transmit(huart2, pkg, sizeof(pkg), 100); // 等待响应(超时300ms) return AS608_WaitResponse(response, 300); }指纹处理流程通常包括图像采集、特征生成、模板存储和匹配搜索四个关键步骤。我们将其封装为高阶API// 完整指纹录入流程 uint8_t AS608_EnrollFingerprint(uint16_t pageID) { uint8_t ret; // 第一次采集 if((ret AS608_GetImage()) ! 0x00) return ret; if((ret AS608_GenChar(CharBuffer1)) ! 0x00) return ret; // 第二次采集 if((ret AS608_GetImage()) ! 0x00) return ret; if((ret AS608_GenChar(CharBuffer2)) ! 0x00) return ret; // 特征比对与合并 if((ret AS608_Match()) ! 0x00) return ret; if((ret AS608_RegModel()) ! 0x00) return ret; // 存储模板 return AS608_StoreChar(CharBuffer2, pageID); } // 指纹验证流程 uint8_t AS608_VerifyFingerprint(uint16_t *pageID, uint16_t *score) { uint8_t ret; SearchResult result; if((ret AS608_GetImage()) ! 0x00) return ret; if((ret AS608_GenChar(CharBuffer1)) ! 0x00) return ret; if((ret AS608_HighSpeedSearch(CharBuffer1, 0, 300, result)) ! 0x00) return ret; *pageID result.pageID; *score result.mathscore; return 0x00; }4. 用户界面与系统逻辑实现智能门锁需要友好的用户交互界面。我们使用OLED显示屏和按键实现菜单导航状态机模型管理不同操作模式。系统状态机设计stateDiagram [*] -- 待机模式 待机模式 -- 验证模式: 手指放置 待机模式 -- 管理菜单: 长按BACK键 验证模式 -- 开锁成功: 指纹匹配 验证模式 -- 开锁失败: 指纹不匹配 管理菜单 -- 录入子菜单: 选择添加指纹 管理菜单 -- 删除子菜单: 选择删除指纹 录入子菜单 -- 录入流程: 选择ID 删除子菜单 -- 删除确认: 选择IDOLED显示驱动采用分层设计底层硬件抽象层提供基本绘图函数上层实现菜单渲染// 菜单项结构体 typedef struct { const char* text; uint8_t icon; void (*action)(void); } MenuItem; // 主菜单定义 MenuItem mainMenu[] { {验证指纹, ICON_FINGERPRINT, NULL}, {添加指纹, ICON_PLUS, EnterEnrollMode}, {删除指纹, ICON_TRASH, EnterDeleteMode}, {系统设置, ICON_GEAR, NULL} }; // 菜单渲染函数 void RenderMenu(MenuItem *menu, uint8_t count, uint8_t selected) { OLED_Clear(); for(uint8_t i0; icount; i) { // 绘制选中项背景 if(i selected) OLED_DrawRect(0, i*16, 128, 16, FILL); // 绘制图标和文字 OLED_DrawIcon(2, i*162, menu[i].icon, iselected?BLACK:WHITE); OLED_DrawString(20, i*164, menu[i].text, iselected?BLACK:WHITE); } OLED_Update(); }按键处理采用中断驱动方式通过状态机消除抖动并识别长短按// 按键事件处理 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static uint32_t pressTime[5] {0}; uint8_t keyIdx GetKeyIndex(GPIO_Pin); if(HAL_GPIO_ReadPin(GPIO_Pin) GPIO_PIN_RESET) { // 按下事件 pressTime[keyIdx] HAL_GetTick(); } else { // 释放事件 uint32_t duration HAL_GetTick() - pressTime[keyIdx]; if(duration 20) { // 消抖 if(duration 1000) { PostKeyEvent(keyIdx, KEY_SHORT_PRESS); } else { PostKeyEvent(keyIdx, KEY_LONG_PRESS); } } } }5. 系统集成与功能测试将所有模块集成后我们需要实现完整的门锁控制逻辑。系统上电后进入待机模式通过状态转换实现不同功能。开锁成功处理流程指纹验证通过后启动继电器控制电路绿色LED点亮蜂鸣器发出短促滴声OLED显示欢迎信息保持开锁状态3秒后自动复位void HandleUnlockSuccess(uint16_t userID) { // 驱动继电器开锁 HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_SET); // 绿色LED指示 HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET); // 蜂鸣器提示 Beep(200, 100); // 显示欢迎信息 char welcomeMsg[20]; sprintf(welcomeMsg, 欢迎 #%03d, userID); OLED_ShowMessage(welcomeMsg, 门锁已开启, 3000); // 延时后恢复 HAL_Delay(3000); HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET); }指纹管理功能实现指纹数据库管理需要特别注意数据安全性和操作确认机制。删除操作前必须二次确认防止误操作。void DeleteFingerprint(uint16_t pageID) { char confirmMsg[32]; sprintf(confirmMsg, 确认删除ID:%03d?, pageID); // 显示确认对话框 if(OLED_ShowDialog(警告, confirmMsg, 取消, 确认) DIALOG_RESULT_YES) { uint8_t ret AS608_DeletChar(pageID, 1); if(ret 0x00) { OLED_ShowMessage(操作成功, 指纹已删除, 1500); Beep(100, 50); Beep(100, 50); } else { ShowAS608Error(ret); } } }6. 进阶优化与扩展思路基础功能实现后可以考虑以下增强功能提升系统实用性1. 多用户权限管理实现用户分级管理员/普通用户管理员可添加/删除其他用户指纹记录操作日志到AS608的记事本区域#define USER_ROLE_NORMAL 0 #define USER_ROLE_ADMIN 1 typedef struct { uint16_t fingerprintID; uint8_t role; char name[16]; } UserProfile; UserProfile userDB[MAX_USERS]; uint8_t adminCount 0; uint8_t AddUserWithRole(uint16_t fid, uint8_t role, const char* name) { if(role USER_ROLE_ADMIN adminCount 3) return ERR_TOO_MANY_ADMINS; // 添加到内存数据库 userDB[userCount].fingerprintID fid; userDB[userCount].role role; strncpy(userDB[userCount].name, name, 15); if(role USER_ROLE_ADMIN) adminCount; userCount; return SUCCESS; }2. 防拆报警功能利用STM32的GPIO检测机壳开关触发后启动蜂鸣器报警并记录事件需要管理员指纹才能解除报警状态3. 低功耗优化空闲时进入STOP模式降低功耗通过RTC定时唤醒检查按键指纹模块配置为自动休眠模式void EnterLowPowerMode(void) { // 关闭外设时钟 __HAL_RCC_GPIOA_CLK_DISABLE(); __HAL_RCC_GPIOB_CLK_DISABLE(); // 保留唤醒引脚时钟 __HAL_RCC_GPIOC_CLK_ENABLE(); // 配置唤醒源 HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); // 进入STOP模式 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后系统时钟重新配置 SystemClock_Config(); }4. 无线扩展接口预留蓝牙/Wi-Fi模块接口通过AT指令实现远程状态查询添加加密通信保障安全性实际开发中发现AS608模块在强光直射环境下识别率会下降。解决方法是在指纹采集窗口周围增加遮光橡胶圈或者在软件上增加图像质量检测拒绝低质量指纹图像。