基于天空星HC32F4A0的AS608光学指纹模块驱动移植与功能实现

发布时间:2026/7/23 2:12:51

基于天空星HC32F4A0的AS608光学指纹模块驱动移植与功能实现 基于天空星HC32F4A0的AS608光学指纹模块驱动移植与功能实现最近在做一个门禁项目需要用到指纹识别功能选用了市面上很常见的AS608光学指纹模块。这个模块性价比高资料也多但要把它的驱动在国产的天空星HC32F4A0开发板上跑起来还是需要花点功夫的。今天我就把整个移植和调试的过程整理出来手把手带你从硬件连接到代码实现完成指纹的录入、搜索和删除功能。这篇文章适合正在使用HC32F4A0系列芯片或者想为其他MCU平台移植AS608驱动的朋友。我会尽量把原理讲清楚代码也给全你跟着做一遍基本上就能在自己的项目里用起来了。1. 认识AS608指纹模块在动手写代码之前咱们先得搞清楚要驱动的对象是什么。AS608光学指纹模块核心是杭州晟元芯片技术有限公司的一颗指纹识别专用芯片。它的最大好处是芯片内部已经集成了指纹图像采集、处理和特征值比对算法我们开发者不用去研究复杂的图像处理和指纹识别算法只需要通过简单的串口发送指令就能控制它完成所有工作。1.1 模块基本参数与硬件连接先看看模块的关键参数这对后续的电路设计和代码配置很重要参数项规格说明工作电压3.0V - 3.6V (注意绝对不能超过3.6V)工作电流30mA - 60mA指纹容量最多可存储300枚指纹 (ID编号从0到299)认假率 0.001% (安全性很高)搜索时间 0.3秒 (速度很快)控制接口串口 (UART) 或 USB引脚8 Pin (2.54mm间距排针)模块有8个引脚用不同颜色的线区分接线时千万别搞错了红线 (VCC)接3.3V电源。这里有个大坑模块最高只能承受3.6V如果你手头的开发板是5V输出必须用LDO降压到3.3V再接入否则模块会瞬间烧毁。黄线 (TX)模块的串口发送端接MCU的RX(接收端)。白线 (RX)模块的串口接收端接MCU的TX(发送端)。黑线 (GND)电源地接3.3V电源的负极。蓝线 (TOUCH)触摸感应信号输出。当手指触摸识别区时这个引脚会输出高电平。使用时需要接一个上拉电阻到3.3V。绿线 (VTOUCH)触摸感应电路的电源直接和1脚(VCC)并接即可。7、8脚 (D, D-)USB信号线。如果我们只用串口控制这两个引脚悬空不接就行。注意接线时模块的TX接MCU的RX模块的RX接MCU的TX这是交叉连接别接反了。电源一定要是3.3V1.2 模块的工作原理AS608模块内部有3个重要的缓冲区理解它们对编程很有帮助ImageBuffer (图像缓冲区)72KB大小。当手指按下时光学传感器采集的原始指纹图像就存放在这里。CharBuffer1 和 CharBuffer2 (特征文件缓冲区)各512字节。这两个缓冲区用来存放从指纹图像中提取出来的“特征码”。你可以把特征码理解成指纹的“数学摘要”它比原始图像小得多用于快速比对。录入指纹时需要采集两次图像分别放入CharBuffer1和CharBuffer2然后合成一个最终的“指纹模板”存入指纹库。搜索时则是将当前采集的特征码与指纹库中所有的模板进行比对。2. 硬件引脚配置与驱动移植我们的目标是在天空星HC32F4A0开发板上通过串口控制AS608模块。首先得确定用哪个串口以及对应的引脚。2.1 选择串口引脚查看HC32F4A0的数据手册第44页的引脚功能定义图我选择了USART2并使用它的复用功能。对应的引脚是USART2_TX: PA2 (作为MCU的发送端接模块的RX/白线)USART2_RX: PA3 (作为MCU的接收端接模块的TX/黄线)在代码中我们通过宏定义来配置这些引脚这样以后想换引脚也方便。// bsp_as608.h 中的引脚定义 #define BSP_AS608_FCG FCG3_PERIPH_USART2 // 串口2的时钟 #define BSP_AS608_TX_PORT GPIO_PORT_A // 串口TX的端口 #define BSP_AS608_RX_PORT GPIO_PORT_A // 串口RX的端口 #define BSP_AS608_TOUCH_PORT GPIO_PORT_C // 触摸检测引脚端口 #define BSP_AS608_FUNC GPIO_FUNC_20 // 串口2的复用功能编号 #define BSP_AS608_TX_PIN GPIO_PIN_02 // 串口TX的引脚 (PA2) #define BSP_AS608_RX_PIN GPIO_PIN_03 // 串口RX的引脚 (PA3) #define BSP_AS608_TOUCH_PIN GPIO_PIN_02 // 触摸检测引脚 (PC2) #define BSP_AS608 CM_USART2 // 串口2外设2.2 移植驱动文件到工程移植步骤和添加其他外设驱动类似在你的工程目录下比如Drivers/BSP文件夹新建bsp_as608.c和bsp_as608.h两个文件。将后面提供的完整代码复制到这两个文件中。在工程管理界面如Keil的Project里把这两个文件添加到你的项目里。在需要调用指纹功能的主文件或其它文件中包含头文件#include bsp_as608.h。接下来咱们看看核心的初始化函数as608_gpio_config是怎么写的。2.3 串口与GPIO初始化这个函数负责配置USART2的引脚、波特率并开启中断。AS608模块的默认通信波特率是57600。// bsp_as608.c 中的初始化函数 (节选关键部分) void as608_gpio_config(uint32_t band_rate) { stc_usart_uart_init_t stcUartInit; // 1. 配置TX(PA2)和RX(PA3)引脚为USART2的复用功能 GPIO_SetFunc(BSP_AS608_TX_PORT, BSP_AS608_TX_PIN, BSP_AS608_FUNC); GPIO_SetFunc(BSP_AS608_RX_PORT, BSP_AS608_RX_PIN, BSP_AS608_FUNC); // 2. 使能USART2的时钟 FCG_Fcg3PeriphClockCmd(BSP_AS608_FCG, ENABLE); // 3. 配置串口参数 (void)USART_UART_StructInit(stcUartInit); stcUartInit.u32ClockSrc USART_CLK_SRC_INTERNCLK; // 使用内部时钟 stcUartInit.u32Baudrate band_rate; // 波特率设为57600 stcUartInit.u32DataWidth USART_DATA_WIDTH_8BIT; // 8位数据位 stcUartInit.u32StopBit USART_STOPBIT_1BIT; // 1位停止位 stcUartInit.u32HWFlowControl USART_HW_FLOWCTRL_NONE; // 无硬件流控 // 初始化USART2 USART_UART_Init(BSP_AS608, stcUartInit, NULL); // 4. 配置并开启接收中断 stc_irq_signin_config_t stcIrqSigninCfg; stcIrqSigninCfg.enIRQn BSP_AS608_RECV_IRQ; // 接收中断号 stcIrqSigninCfg.enIntSrc BSP_AS608_RECV_TYPE; // 中断源 stcIrqSigninCfg.pfnCallback USART2_RECV_IRQHandler; // 中断服务函数 (void)INTC_IrqSignIn(stcIrqSigninCfg); NVIC_EnableIRQ(stcIrqSigninCfg.enIRQn); // 5. 开启USART2的发送和接收功能 USART_FuncCmd(BSP_AS608, USART_TX, ENABLE); USART_FuncCmd(BSP_AS608, USART_RX, ENABLE); USART_FuncCmd(BSP_AS608, USART_INT_RX, ENABLE); // 开启接收中断 // 6. 初始化触摸检测引脚(PC2)为上拉输入 stc_gpio_init_t stcGpioInit; (void)GPIO_StructInit(stcGpioInit); stcGpioInit.u16PinDir PIN_DIR_IN; // 输入模式 stcGpioInit.u16PullUp PIN_PU_ON; // 开启上拉电阻 (void)GPIO_Init(BSP_AS608_TOUCH_PORT, BSP_AS608_TOUCH_PIN, stcGpioInit); }这里我用了中断方式来接收数据因为串口通信是异步的用中断比轮询效率高得多。当USART2收到数据时会自动跳转到USART2_RECV_IRQHandler函数。3. 理解AS608的通信协议与指令AS608模块的所有操作都是通过MCU发送特定的指令包然后模块返回应答包来完成的。指令包有固定的格式。3.1 指令包格式每个发送给AS608的指令包都由以下几部分组成包头 (2字节)固定为0xEF 0x01芯片地址 (4字节)默认是0xFF 0xFF 0xFF 0xFF包标识 (1字节)指令包是0x01包长度 (2字节)指包标识之后到校验和之前的数据长度。指令码 (1字节)比如获取图像是0x01参数 (长度不定)有些指令需要参数如保存指纹的位置ID。校验和 (2字节)从“包标识”到“参数”最后一个字节的所有数据之和。在代码里我把常用的指令都定义成了数组用的时候直接发送就行比如获取指纹图像的指令// 获取指纹图像的命令包已包含包头、地址、包长等 const unsigned char FPM10A_Get_Img[] {0x01,0x00,0x03,0x01,0x00,0x05}; // 分解一下 // 包标识: 0x01 // 包长度: 0x00 0x03 (表示后面有3个字节) // 指令码: 0x01 (Get Image) // 参数: 无 // 校验和: 0x00 0x05 (0x010x000x030x010x05)3.2 基础通信函数驱动里封装了几个最基础的通信函数所有高级功能都建立在它们之上uart2_send_byte(): 发送一个字节数据。FPM10A_Cmd_Send_Pack_Head(): 发送指令包的包头和芯片地址部分。FPM10A_Receive_Data():接收模块返回的数据。这里有个关键点发送指令后必须等待并接收模块的应答应答包里包含一个“确认码”为0表示指令执行成功非0则表示出错具体错误码查手册。void FPM10A_Receive_Data(unsigned char ucLength) { unsigned char i 0; unsigned int timeout 1000; // 超时时间1000ms // 等待接收完成标志位被置位在中断服务函数中设置 while(u2_recv_flag0 timeout 0 ) { delay_ms(1); timeout--; } delay_ms(100); // 原文特别强调这里一定要加延时 if( u2_recv_flag 1 ) { u2_recv_flag 0; // 将接收缓冲区的数据复制到指令处理缓冲区 for (i0;iucLength;i) { FPM10A_RECEICE_BUFFER[i] u2_recv_buff[i]; } uart2_receive_clear(); // 清空接收缓冲区准备下次接收 } else { // 超时没有收到数据 } }提示delay_ms(100);这一行延时非常重要在实际调试中我发现如果去掉这个延时紧接着发送下一条指令很容易失败。这是因为模块处理完一条指令并返回数据后需要一小段“休息”时间才能响应下一条指令。4. 核心功能实现录入、搜索与删除驱动层准备好后实现具体功能就清晰多了。每个功能都是按“发送指令-等待应答-判断结果”的流程来走。4.1 功能一录入指纹录入一个指纹需要采集两次图像确保特征提取准确。流程如下第一次采集发送Get_Img指令让用户按下手指。成功后发送Img_To_Buffer1指令将图像特征存入Buffer1。提示抬起手指让用户抬起手指准备第二次按压。第二次采集再次发送Get_Img指令。成功后发送Img_To_Buffer2指令将图像特征存入Buffer2。生成并存储模板发送Reg_Model指令将Buffer1和Buffer2的特征合成为一个完整的指纹模板。最后发送Save_Finger指令并指定一个ID号0-299将模板存入指纹库的该位置。// 添加指纹的核心流程代码片段 if(FPM10A_RECEICE_BUFFER[9]0) // 判断第一次采集是否成功 { delay_ms(100); FINGERPRINT_Cmd_Img_To_Buffer1(); // 特征存入Buffer1 FPM10A_Receive_Data(12); delay_ms(1000); // 等待用户抬起手指 // ... 第二次采集代码类似 if(FPM10A_RECEICE_BUFFER[9]0) // 判断第二次采集是否成功 { FINGERPRINT_Cmd_Img_To_Buffer2(); // 特征存入Buffer2 FPM10A_Receive_Data(12); FPM10A_Cmd_Reg_Model(); // 合成模板 FPM10A_Receive_Data(12); // 保存指纹到指定ID FPM10A_Cmd_Save_Finger(finger_id); FPM10A_Receive_Data(12); printf(成功添加ID %d\r\n,finger_id); finger_id; // ID号自增为下次录入准备 } }4.2 功能二搜索指纹搜索功能用于身份验证。流程更简单检测到有手指按下通过触摸感应引脚。发送Get_Img指令采集图像。发送Img_To_Buffer1指令生成特征码。发送Search指令在指纹库中搜索匹配的模板。模块会返回搜索结果。如果找到返回包中会包含匹配的指纹ID和匹配得分如果没找到确认码会是非0值。unsigned int FPM10A_Find_Fingerprint(void) { unsigned int find_fingerid 255; // 255表示未找到 if( get_as608_touch() 1 ) // 检测到有手指触摸 { FPM10A_Cmd_Get_Img(); // 采集图像 FPM10A_Receive_Data(12); if(FPM10A_RECEICE_BUFFER[9]0) // 采集成功 { FINGERPRINT_Cmd_Img_To_Buffer1(); // 生成特征码 FPM10A_Receive_Data(12); FPM10A_Cmd_Search_Finger(); // 在指纹库中搜索 FPM10A_Receive_Data(16); if(FPM10A_RECEICE_BUFFER[9] 0) // 搜索成功 { // 从返回包中提取指纹ID (第10和11字节) find_fingerid FPM10A_RECEICE_BUFFER[10]*256 FPM10A_RECEICE_BUFFER[11]; printf(找到指纹ID %d\r\n,find_fingerid); } else { printf(未找到匹配指纹\r\n); } } } return find_fingerid; // 返回找到的ID或255 }4.3 功能三删除指纹删除功能比较简单可以删除单个指纹也可以清空整个指纹库。示例代码提供了清空所有指纹的函数FINGERPRINT_Cmd_Delete_All_Model()它会发送删除全部模板的指令。注意删除操作不可逆在实际产品中要做好权限管理或二次确认示例代码里就通过串口询问“Whether to delete fingerprint?”并等待确认键。5. 在主函数中调用与测试最后我们在main函数里把上面的功能串联起来进行一个完整的流程测试。#include board.h #include bsp_uart.h #include stdio.h #include bsp_as608.h int32_t main(void) { board_init(); // 开发板基础初始化时钟、系统滴答等 uart1_init(57600U); // 初始化调试串口用于打印信息 printf(系统启动\r\n); // 1. 初始化AS608模块波特率57600 as608_gpio_config(57600U); printf(AS608模块初始化完成\r\n); // 2. 检测模块是否连接正常 if(Device_Check()) { printf(AS608模块检测成功通信正常\r\n); } else { printf(错误未检测到AS608模块请检查接线和电源\r\n); while(1); // 通信失败停机 } // 3. 可选清空指纹库用于首次测试 // FPM10A_Delete_All_Fingerprint(); // 4. 进入指纹录入流程根据串口指令 FPM10A_Add_Fingerprint(); // 5. 主循环持续进行指纹搜索验证 while(1) { unsigned int id FPM10A_Find_Fingerprint(); if(id ! 255) { // 找到指纹可以执行开锁、登录等操作 // 例如控制继电器开锁、点亮LED等 } delay_ms(300); // 适当延时避免搜索过于频繁 } }调试心得与常见问题模块无反应通信失败首先检查电源万用表量一下VCC和GND之间是不是稳定的3.3V这是最常见的问题。检查接线确认TX-RX是否交叉连接触摸感应引脚(VT)是否上拉到3.3V。检查波特率AS608默认是57600确认代码和模块设置一致模块波特率一般可通过指令修改但新手建议先用默认值。能通信但采集图像总是失败手指按压确保手指完全覆盖识别窗口力度适中不要太轻也不要太重。环境光强光直射或环境光过暗都可能影响光学传感器尝试调整角度或遮光。镜头清洁指纹识别窗口如果有污渍用软布轻轻擦干净。搜索时误识别或拒识率高录入质量确保录入时两次按压的指纹区域基本一致且图像质量良好模块返回成功确认码。指纹特性极少数干燥、脱皮或纹理很浅的指纹可能识别困难。代码移植到其他MCU本驱动代码的核心是串口发送/接收和指令时序。如果你用的是STM32、GD32等其他芯片只需要把底层GPIO和UART的初始化函数替换成对应芯片的HAL库或标准库函数即可上层的指令发送、功能逻辑完全不用动。整个代码我已经在实际的天空星HC32F4A0开发板上跑通了录入、搜索、删除功能都稳定工作。你可以直接使用提供的代码根据自己的项目需求修改按键检测逻辑示例中用串口模拟按键和找到指纹后的执行动作。希望这篇教程能帮你顺利把指纹功能加到自己的项目里。

相关新闻