【外设移植】FPM383C指纹模块+Ai-M61-32S

[复制链接]
查看2208 | 回复38 | 2023-12-30 13:01:37 | 显示全部楼层 |阅读模式

一、产品介绍

O1CN01mW6gDw1Sru5AjgdNT_!!964772301-0-cib.jpg

HLK-FPM383C系列指纹模块具备完整的指纹处理能力,可以在无需上位机参与的情况 下,完成指纹录入,图像处理,指纹比对,指纹特征储存等功能。和同类指纹产品相比, 具有以下特色:

❖ 模组集成化高、体积更小、功耗更低。

❖ 模组使用自主研发指纹识别算法和芯片,各项性能指标优于同类产品。

❖ 模组使用的指纹识别算法提供模板拼接功能,提升用户体验。

❖ 模组采用指纹特征储存在算法芯片中的方案,可以防止指纹特征被暴力破解,提 高产品安全等级。

❖ 产品具备防雾防尘防破坏能力,有效解决了人体静电的影响、提高了产品采像质 量、增加了产品耐用性。

❖ 模组传感器表面可按用户要求定制颜色。

❖ 模组具有触摸唤醒功能,并可有效识别塑胶手指、硅胶手指、橡胶手指、指模、 指套等假手指。

❖ 产品结构简单,模组化设计,提高了产品的稳定性和一致性、便于大规模批量生 产。

❖ 公开接口代码和命令集,可实现组装式二次开发,降低客户开发难度。

❖ 自主知识产权技术可为客户提供高效、灵活的二次开发支持,充分满足客户需求 且无知识产权纠纷

二、接口定义

O1CN01Q7VMgZ1Sru5Exw8A5_!!964772301-0-cib.jpg

a) UART 缺省波特率为 57.6Kbps,数据格式:8 位数据位,2 位停止位,无校验位;

b) UART 波特率可以通过指令进行设置,范围从 9600 至 115200;

c) 如果主控是 MCU(3.3V),则直接与 UART_TD 和 UART_RD 连接;如果主控是 PC,则需要挂接 RS232 电平转换设备

三、应用范围

HLK-FPM383C系列指纹模块应用广泛,适合各类指纹识别系统,例如:

❖ 指纹门锁、保险柜、枪盒、金融等安全领域;

❖ 门禁系统、工控机、POS 机、驾培、考勤等身份领域;

❖ 私人会所、管理软件、授权许可等管理领域;

四、串行协议

捕获.PNG

模块上电后,约需200ms时间进行初始化工作。在此期间,模块不能响应上位机命令。

通讯协议定义了 HLK-FPM383C 系列模板与上位机之间进行数据交换的规则。硬件上采 用 UART 接口,软件实现上参考如下通讯协议和指令集。 本协议为2层结构:应用层和链路层。应用层主要负责具体功能定义,链路层用来进行 数据传输。在传输协议中定义的2字节或者4字节,采用小字节序(little endian),高位在 前低位在后(例如 0x12345678 实际传输方式为 0x12 0x34 0x56 0x78,不是 0x78 0x56 0x34 0x12)。

链路层描述(UART)

UART 链路层为半双工点对点工作方式,所有命令必须由上位机发起,指纹模块进行响应。UART 数据帧格式:

捕获.PNG

说明:

帧头:UART 起始头界定,无论是上位机发送数据还是指纹模块发送数据,帧头数据固定为 0xF1 1F E2 2E B6 6B A8 8A;

应用层数据长度:描述应用层实际数据的长度,此数据长度不包含帧头、应用层数据长 度、帧头校验和 3 部分;

帧头校验和:为帧头+应用层数据长度的校验和,用来检查数据长度是否有误。

捕获.PNG

五、正文

下面介绍一下FPM383C指纹识别模块用到的指令与指令的详细介绍。

包含: 自动注册、自动验证、图像获取、生成特征、搜索指纹、清空指纹和LED灯光的控制。

1、自动注册模板PS_AutoEnrol

功能说明: 一站式注册指纹,包含采集指纹、生成特征、组合模板、存储模板等功能。如 表 2-1 中加密等级设置为 0 或 1 情况下支持此功能。 

输入参数: ID 号,录入次数,参数 

返回参数: 确认字,参数 

指令代码: 31H 

指令包格式:

捕获.PNG

辅助说明: ID 号:高字节在前,低字节在后。例如录入 1 号指纹,则是 0001H。

录入次数:1byte,录入 2 次,则为 02H,录入 4 次则为 04H。

参数:最低位为 bit0。

  1. bit0:采图背光灯控制位,0-LED 长亮,1-LED 获取图像成功后灭;

  2. bit1:采图预处理控制位,0-关闭预处理,1-打开预处理;

  3. bit2:注册过程中,是否要求模组在关键步骤,返回当前状态,0-要求返回,1-不 要求返回;

  4. bit3:是否允许覆盖 ID 号,0-不允许,1-允许;

  5. bit4:允许指纹重复注册控制位,0-允许,1-不允许;

  6. bit5:注册时,多次指纹采集过程中,是否要求手指离开才能进入下一次指纹图 像采集, 0-要求离开;1-不要求离开;

  7. bit6~bit15:预留

应答包格式:

捕获.PNG

捕获.PNG

指令说明:

  1. 若指定 ID 号无效,则确认码 、参数1 和参数 2 返回(以下直接描述为返回):0b 00 00H。合法性检测:  若指定 ID 号无效,则返回:0b 00 00H。  若录入次数配置错误,则返回 25 00 00H。在不覆盖指纹状态下,若指纹库 已满则返回 1f 00 00H;  若指定 ID 号已存在模板则返回 22 00 00H。  指令合法性检测成功,则返回 00 00 00H,并进入第一次指纹录入。

  2. 等待彩图成功(返回 00 01 0nH)。

  3. 等待生成特征成功(00 02 0nH),如果失败(07 02 0nH),重新等待彩图成功。

  4. 等待手指离开,第一次录入成功(00 03 0nH),手指离开后跳转到步骤 2,进入下一 次循环,直到 n 为设置录入的次数。注:若录入过程中设置为手指不需要离开,那么 直接返回第一次录入成功,并跳转到步骤 2;最后一次采集指纹,没有手指离开录入成 功的应答。

  5. 合成模板,将之前获取的手指特征组合成一个手指模板,成功返回 00 04 F0H,失败返 回 0A 04 F0H。

  6. 指纹重复检查,指将新录入的手指与已经存储的手指进行匹配检查(通过设置参数 bit4 开启或者关闭此功能),若有相同指纹,则返回 27 05 F1H,结束流程;若没有相同 指纹,则返回 00 05 F1H。

  7. 登记该模板数据,存储失败返回 01 06 F2H,结束流程;成功返回 00 06 F2H。

  8. 若收到 PS_Cancel 指令,则终止该指令并返回应答

2、自动验证指纹PS_AutoIdentify

功能说明: 自动采集指纹包含获取图像,生成特征,搜索指纹等功能。如表 2-1 中加密等 级设置为 0 或 1 情况下支持此功能。 

输入参数: 分数等级,ID 号 

返回参数: 确认字,页码(相配指纹模板) 

指令代码: 32H 

指令包格式

捕获.PNG

辅助说明: ID 号:2byte,大端模式。比如录入 1 号指纹,则是 0001H。ID 号为 0xFFFF,则进行 1:N 搜索;否进行 1:1 匹配

参数:最低位为 bit0。

  1. bit0:采图背光灯控制位,0-LED 长亮,1-LED 获取图像成功后灭;

  2. bit1:采图预处理控制位,0-关闭预处理,1-打开预处理;

  3. bit2:注册过程中,是否要求模组在关键步骤,返回当前状态,0-要求返回,1-不要求 返回;

  4. bit3~bit15:预留。 

应答包格式:

捕获.PNG

捕获.PNG

捕获.PNG

指令说明:

  1. 若指纹库为空,则确认码和参数返回(以下直接描述为返回):24 00H。若指定 ID 号无 效,则返回 0b 00H。若已登记的 Template 不存在,则返回 23 00H。

  2. 指令合法性检测成功,返回 00 00H,并进入指纹录入。

  3. 在设定的超时时间内,若没有完成一次完整的指纹录入,则返回 26 00H,结束流程。

  4. 检查输入的指纹图像的正确性。若不正确,则等待下次采集图像。

  5. 若输入指纹正确,则返回 00 01H,即录入指纹获取图像成功。

  6. 若生产特征失败,则返回 09 05H,结束流程。

  7. 生成特征成功后,把当前采集到的指纹模板与已登记的指纹模板之间进行比对,并返回 其结果。若比对失败,则返回 09 05H,结束流程;若比对成功,则返回 00 05H,以及 正确的 ID 号码和得分。

  8. 若收到 PS_Cancel 指令,则终止该指令并返回应答。

3、验证用获取图像PS_GetImage

功能说明: 验证指纹时,探测手指,探测到后录入指纹图像存于图像缓冲区。返回确认码 表示:录入成功、无手指等。 输入参数: none 

返回参数: 确认字 

指令代码: 01H 

指令包格式:

捕获.PNG

应答包格式:

捕获.PNG

注:确认码=00H 表示获取图像成功;

确认码=01H 表示收包有错;

确认码=02H 表示传感器上无手指;

sum 指校验和

4、生成特征PS_GenChar

功能说明: 将图像缓冲区中的原始图像生成指纹特征文件存于模板缓冲区。 

输入参数: BufferID(正整数) 

返回参数: 确认字 

指令代码: 02H 

指令包格式:

捕获.PNG

注:在注册过程中,BufferID 表示此次提取的特征存放在缓冲区中的位置;其他情况中, BufferID 有相应的默认值。

应答包格式:

捕获.PNG

注:确认码=00H 表示生成特征成功;

确认码=01H 表示收包有错;

确认码=06H 表示指纹图像太乱而生不成特征;

确认码=07H 表示指纹图像正常,但特征点太少而生不成特征;

确认码=08H 表示当前指纹特征与之前特征之间无关联;(默认关闭此功能)

确认码=0aH 表示合并失败;

确认码=15H 表示图像缓冲区内没有有效原始图而生不成图像;

确认码=28H 表示当前指纹特征与之前特征之间有关联;(默认关闭此功能)

sum 指校验和。

5、搜索指纹PS_Search

功能说明: 以模板缓冲区中的特征文件搜索整个或部分指纹库。若搜索到,则返回页码。 如表 2-1 中加密等级设置为 0 或 1 情况下支持此功能。 

输入参数: BufferID(默认为 1),StartPage(起始页),PageNum(页数) 

返回参数: 确认字,页码(相配指纹模板),得分 

指令代码: 04H 

指令包格式:

捕获.PNG

应答包格式:

捕获.PNG

注:确认码=00H 表示搜索到;

确认码=01H 表示收包有错;

确认码=09H 表示没搜索到;此时页码与得分为 0;

确认码=17H 表示残留指纹或两次采集之间手指没有移动过;

确认码=31H 表示功能与加密等级不匹配;

sum 指校验和

6、清空指纹库PS_Empty

功能说明: 删除 flash 数据库中所有指纹模板。 

输入参数: none 

返回参数: 确认字 

指令代码: 0dH 

指令包格式:

捕获.PNG

应答包格式:

捕获.PNG

注:确认码=00H 表示清空成功;

确认码=01H 表示收包有错;

确认码=11H 表示清空失败;

sum 指校验和

7、LED控制灯指令PS_ControlBLN

功能说明: 控制灯指令主要分为两类:一般指示灯和七彩编程呼吸灯。 

输入参数: 功能码,起始颜色,结束颜色,循环次数 

返回参数: 确认字 

指令代码: 3CH 

指令包格式:

捕获.PNG

辅助说明

功能码:LED 灯模式控制位,1-普通呼吸灯,2-闪烁灯,3-常开灯,4-常闭灯,5-渐开灯, 6-渐闭灯,其他功能码不适用于此指令包格式;

起始颜色:设置为普通呼吸灯时,由灭到亮的颜色,只限于普通呼吸灯(功能码 01)功能, 其他功能时,与结束颜色保持一致。其中,bit0 是蓝灯控制位;bit1 是绿灯控制位;bit2 是 红灯控制位。置 1 灯亮,置 0 灯灭。例如 0x01_蓝灯亮,0x02_绿灯亮,0x04_红灯亮,0x06_红绿 灯亮,0x05_红蓝灯亮,0x03_绿蓝灯亮,0x07_红绿蓝灯亮,0x00_全灭;

结束颜色:设置为普通呼吸灯时,由亮到灭的颜色,只限于普通呼吸灯(功能码 0x01),其 他功能时,与起始颜色保持一致。设置方式与起始颜色一样;

循环次数:表示呼吸或者闪烁灯的次数。当设为 0 时,表示无限循环,当设为其他值时, 表示呼吸有限次数。循环次数适用于呼吸、闪烁功能,其他功能中无效,例如在常开、常闭、渐 开和渐闭中是无效的;

本帖被以下淘专辑推荐:

回复

使用道具 举报

WT_0213 | 2023-12-30 13:22:29 | 显示全部楼层

捕获.PNG

运行结果,显示显示注册的指纹ID,随机了一个,不过好像随机的一直都是0a 也就是10。

注册完成后自动会进入识别状态。识别到指纹提示,解锁成功并打印指纹ID;否则提示解锁失败。

【FPM383C指纹识别模块+安信可Ai-m61-32s】 https://www.bilibili.com/video/BV17G411z75w/?share_source=copy_web&vd_source=95f092a8edb82d1fb04a2d285b5f28a7

回复 支持 反对

使用道具 举报

WT_0213 | 2023-12-30 13:47:23 | 显示全部楼层
本帖最后由 WT_0213 于 2024-4-22 21:49 编辑

a440c6254a784ee18a574e9df78d1f53.gif
gitee 地址: https://gitee.com/lazy-ai/ai-m61-32s-fpm383c.git
fpm383c.zip (5.44 KB, 下载次数: 32)
回复 支持 反对

使用道具 举报

WT_0213 | 2024-4-19 13:58:21 | 显示全部楼层
企业微信截图_20240419135058.png

接线方式:
Ai-M61-32s FPM383C
3v3 Pin3
GND PIN6
IO23 PIN5
IO24 PIN4


回复 支持 反对

使用道具 举报

WT_0213 | 2023-12-30 13:05:35 | 显示全部楼层
本帖最后由 WT_0213 于 2024-4-22 21:54 编辑

接下来上干货,之所以放在二楼是因为怕编辑太多发布失败丢失数据。
FPM383C.h
  1. #ifndef __FPM383C_H
  2. #define __FPM383C_H

  3. #include "stdint.h"

  4. void FPM383C_Init(void);
  5. void FPM383C_SendData(int length, uint8_t buffer[]);
  6. void FPM383C_Sleep(void);

  7. uint8_t FPM383C_GetImage(uint32_t timeout);
  8. uint8_t FPM383C_GenChar(uint32_t timeout);
  9. uint8_t FPM383C_Search(uint32_t timeout);
  10. uint8_t FPM383C_Empty(uint32_t timeout);
  11. uint8_t FPM383C_Delete(uint16_t pageID,uint32_t timeout);
  12. uint8_t FPM383C_ControlLED(uint8_t PS_ControlLEDBuf[],uint32_t timeout);
  13. void FPM383C_Identify(void);
  14. void FPM383C_Enroll(uint16_t pageID,uint16_t timeout);

  15. #endif
复制代码
FPM383C.c
  1. #include "FPM383C.h"
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include "string.h"
  5. #include "bflb_mtimer.h"
  6. #include "bflb_dma.h"
  7. #include "bflb_uart.h"
  8. #include "bflb_gpio.h"
  9. #include "log.h"

  10. //控制模块LED灯颜色
  11. uint8_t PS_BlueLEDBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x03,0x01,0x01,0x00,0x00,0x49};
  12. uint8_t PS_RedLEDBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x02,0x04,0x04,0x02,0x00,0x50};
  13. uint8_t PS_GreenLEDBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x02,0x02,0x02,0x02,0x00,0x4C};

  14. //休眠指令-设置传感器进入休眠模式
  15. uint8_t PS_SleepBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x33,0x00,0x37};

  16. //清空指纹库-删除 flash 数据库中所有指纹模板。
  17. uint8_t PS_EmptyBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x0D,0x00,0x11};

  18. //取消指令-取消自动注册模板和自动验证指纹。如表 2-1 中加密等级设置为 0 或 1 情况下支持此功能
  19. uint8_t PS_CancelBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x30,0x00,0x34};

  20. //自动注册模板-一站式注册指纹,包含采集指纹、生成特征、组合模板、存储模板等功能。加密等级设置为 0 或 1 情况下支持此功能。
  21. uint8_t PS_AutoEnrollBuf[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x31,'\0','\0',0x04,0x00,0x16,'\0','\0'};

  22. // 验证用获取图像-验证指纹时,探测手指,探测到后录入指纹图像存于图像缓冲区。返回确认码表示:录入成功、无手指等。
  23. uint8_t PS_GetImageBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x01,0x00,0x05};

  24. //生成特征值-将图像缓冲区中的原始图像生成指纹特征文件存于模板缓冲区
  25. uint8_t PS_GetCharBuf[13] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x04,0x02,0x01,0x00,0x08};

  26. //搜索指纹-以模板缓冲区中的特征文件搜索整个或部分指纹库。若搜索到,则返回页码。加密等级设置为 0 或 1 情况下支持
  27. uint8_t PS_SearchBuf[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x04,0x01,0x00,0x00,0xFF,0xFF,0x02,0x0C};

  28. //删除模板-删除 flash 数据库中指定 ID 号开始的N 个指纹模板
  29. uint8_t PS_DeleteBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x0C,'\0','\0',0x00,0x01,'\0','\0'};

  30. //设置名为fpm383c_uart的外设句柄,用来执行串口指令的发送
  31. struct bflb_device_s *fpm383c_uart;

  32. //指纹ID和验证指纹的分数
  33. uint16_t pageID,score;

  34. //USART串口接收缓冲数组
  35. uint8_t USART_ReceiveBuf[20];

  36. //主循环状态标志位
  37. uint8_t ScanStatus = 0;

  38. /**
  39. * @brief 获取状态
  40. *
  41. * @param Timeout
  42. */
  43. void FPM383C_ReceiveData(uint16_t Timeout)
  44. {
  45.   uint8_t i = 0;
  46.   // 检测缓冲区是否有数据
  47.   while(bflb_uart_rxavailable(fpm383c_uart) == 0 && (--Timeout))
  48.   {
  49.     bflb_mtimer_delay_ms(1);
  50.   }
  51.   // 轮询fpm383c_uart接收到的字符
  52.   while(bflb_uart_rxavailable(fpm383c_uart) > 0)
  53.   {
  54.     bflb_mtimer_delay_ms(2);
  55.         // 获取数据并放入缓冲数组
  56.     USART_ReceiveBuf[i++] = bflb_uart_getchar(fpm383c_uart);
  57.     if(i > 15) break;
  58.   }
  59. }

  60. /// @brief 初始化FPM383C指纹模块
  61. void FPM383C_Init(){
  62.         // 声明 gpio句柄
  63.     struct bflb_device_s* gpio;
  64.         // FPM383C 模块默认波特率为 57600
  65.     struct bflb_uart_config_s cfg = {
  66.         .baudrate = 57600,
  67.         .data_bits = UART_DATA_BITS_8,
  68.         .stop_bits = UART_STOP_BITS_1,
  69.         .parity = UART_PARITY_NONE,
  70.                .flow_ctrl = UART_FLOWCTRL_NONE,
  71.         .rx_fifo_threshold = 7,
  72.         .tx_fifo_threshold = 7
  73.     };

  74.         // 初始化FPM383C指纹模块UART
  75.     gpio = bflb_device_get_by_name("gpio");
  76.     fpm383c_uart = bflb_device_get_by_name("uart1");

  77.     //将GPIO_23和GPIO_24设置为TX和RX
  78.     bflb_gpio_uart_init(gpio, GPIO_PIN_23, GPIO_UART_FUNC_UART1_TX);
  79.     bflb_gpio_uart_init(gpio, GPIO_PIN_24, GPIO_UART_FUNC_UART1_RX);

  80.     bflb_uart_init(fpm383c_uart, &cfg);
  81. }

  82. /// @brief USART串口发送数据
  83. /// @param length 发送数组长度
  84. /// @param FPM383C_DataBuf 需要发送的功能数组
  85. void FPM383C_SendData(int length,uint8_t FPM383C_DataBuf[])
  86. {

  87.         for(int i = 0;i<length;i++)
  88.         {
  89.         bflb_uart_put(fpm383c_uart,(uint8_t *)&FPM383C_DataBuf[i], 1);
  90.         }
  91. }

  92. /// @brief 发送休眠指令 确认码=00H 表示休眠设置成功。确认码=01H 表示休眠设置失败。
  93. /// @param  
  94. void FPM383C_Sleep(void)
  95. {
  96.         FPM383C_SendData(12,PS_SleepBuf);
  97. }

  98. /// @brief 验证用获取图像
  99. /// @param timeout 接收数据的超时时间
  100. /// @return 确认码
  101. uint8_t FPM383C_GetImage(uint32_t timeout)
  102. {
  103.         uint8_t tmp;
  104.         FPM383C_SendData(12,PS_GetImageBuf);
  105.         FPM383C_ReceiveData(timeout);
  106.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  107.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  108.         return tmp;
  109. }

  110. /// @brief 将图像缓冲区中的原始图像生成指纹特征文件存于模板缓冲区。
  111. /// @param timeout 接收数据的超时时间
  112. /// @return 确认码
  113. uint8_t FPM383C_GenChar(uint32_t timeout)
  114. {
  115.         uint8_t tmp;
  116.         FPM383C_SendData(13,PS_GetCharBuf);
  117.         FPM383C_ReceiveData(timeout);
  118.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  119.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  120.         return tmp;
  121. }

  122. /// @brief 发送搜索指纹指令
  123. /// @param timeout 接收数据的超时时间
  124. /// @return 确认码
  125. uint8_t FPM383C_Search(uint32_t timeout)
  126. {
  127.         FPM383C_SendData(17,PS_SearchBuf);
  128.         FPM383C_ReceiveData(timeout);
  129.         return (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  130. }

  131. /// @brief 删除指定指纹指令
  132. /// @param pageID 需要删除的指纹ID号
  133. /// @param timeout 接收数据的超时时间
  134. /// @return 确认码
  135. uint8_t FPM383C_Delete(uint16_t pageID,uint32_t timeout)
  136. {
  137.         uint8_t tmp;
  138.         PS_DeleteBuf[10] = (pageID>>8);
  139.         PS_DeleteBuf[11] = (pageID);
  140.         PS_DeleteBuf[14] = (0x15+PS_DeleteBuf[10]+PS_DeleteBuf[11])>>8;
  141.         PS_DeleteBuf[15] = (0x15+PS_DeleteBuf[10]+PS_DeleteBuf[11]);
  142.         FPM383C_SendData(16,PS_DeleteBuf);
  143.         FPM383C_ReceiveData(timeout);
  144.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  145.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  146.         return tmp;
  147. }

  148. /// @brief 清空指纹库
  149. /// @param timeout 接收数据的超时时间
  150. /// @return 确认码
  151. uint8_t FPM383C_Empty(uint32_t timeout)
  152. {
  153.         uint8_t tmp;
  154.         FPM383C_SendData(12,PS_EmptyBuf);
  155.         FPM383C_ReceiveData(timeout);
  156.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  157.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  158.         return tmp;
  159. }

  160. /// @brief 发送控制灯光指令
  161. /// @param PS_ControlLEDBuf 不同颜色的协议数据
  162. /// @param timeout 接收数据的超时时间
  163. /// @return 确认码
  164. uint8_t FPM383C_ControlLED(uint8_t PS_ControlLEDBuf[],uint32_t timeout)
  165. {
  166.         uint8_t tmp;
  167.         FPM383C_SendData(16,PS_ControlLEDBuf);
  168.         FPM383C_ReceiveData(timeout);
  169.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  170.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  171.         return tmp;
  172. }

  173. /// @brief 验证指纹是否注册
  174. /// @param  
  175. void FPM383C_Identify(void)
  176. {
  177.         if(FPM383C_GetImage(2000) == 0x00)
  178.         {
  179.                 if(FPM383C_GenChar(2000) == 0x00)
  180.                 {
  181.                         struct bflb_device_s *led = bflb_device_get_by_name("gpio");
  182.                         if(FPM383C_Search(2000) == 0x00)
  183.                         {
  184.                                 score = (int)((USART_ReceiveBuf[10] << 8) + USART_ReceiveBuf[11]);
  185.                                 LOG_E("解锁成功 指纹ID:%d\r\n",(int)score);
  186.                                 FPM383C_ControlLED(PS_GreenLEDBuf,1000);
  187.                
  188.                                 bflb_gpio_init(led, GPIO_PIN_14, GPIO_OUTPUT);
  189.                                 bflb_gpio_set(led, GPIO_PIN_14);
  190.                                 bflb_mtimer_delay_ms(1000);
  191.                                 bflb_gpio_reset(led, GPIO_PIN_14);
  192.                                 // 重置接收数据缓存
  193.                                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  194.                                 return;
  195.                         }else{
  196.                                 LOG_E("解锁失败\r\n");
  197.                                 bflb_gpio_init(led, GPIO_PIN_12, GPIO_OUTPUT);
  198.                                 bflb_gpio_set(led, GPIO_PIN_12);
  199.                                 bflb_mtimer_delay_ms(1000);
  200.                                 bflb_gpio_reset(led, GPIO_PIN_12);
  201.                                 // 重置接收数据缓存
  202.                                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  203.                                 return;
  204.                         }
  205.                 }
  206.         }
  207. }

  208. /// @brief 自动注册
  209. /// @param pageID 输入需要注册的指纹ID号,取值范围0—59
  210. /// @param timeout 设置注册指纹超时时间,因为需要按压四次手指,建议大于10000(即10s)
  211. void FPM383C_Enroll(uint16_t pageID,uint16_t timeout)
  212. {
  213.         LOG_E("注册指纹ID: %d\r\n", pageID);
  214.         PS_AutoEnrollBuf[10] = (pageID>>8);
  215.         PS_AutoEnrollBuf[11] = (pageID);
  216.         PS_AutoEnrollBuf[15] = (0x54+PS_AutoEnrollBuf[10]+PS_AutoEnrollBuf[11])>>8;
  217.         PS_AutoEnrollBuf[16] = (0x54+PS_AutoEnrollBuf[10]+PS_AutoEnrollBuf[11]);
  218.         FPM383C_SendData(17,PS_AutoEnrollBuf);
  219.         FPM383C_ReceiveData(timeout);
  220.         if(USART_ReceiveBuf[9] == 0x00)
  221.         {
  222.                 LOG_E("指纹注册完成\r\n");
  223.                 // 亮绿灯2秒
  224.                 FPM383C_ControlLED(PS_GreenLEDBuf,2000);
  225.                 // 重置接收数据缓存
  226.                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  227.                 return;
  228.         }
  229.         else if(timeout == 0)
  230.         {
  231.                 // 超时取消注册
  232.                 FPM383C_SendData(12,PS_CancelBuf);
  233.                 bflb_mtimer_delay_ms(50);
  234.                 // 重置接收数据缓存
  235.                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  236.         }
  237.         // 亮红灯2秒
  238.         FPM383C_ControlLED(PS_RedLEDBuf,2000);
  239. }
复制代码
main.c
  1. #include "bflb_mtimer.h"
  2. #include "bflb_dma.h"
  3. #include "bflb_uart.h"
  4. #include "bflb_l1c.h"
  5. #include "board.h"
  6. #include "time.h"
  7. #include "FPM383C.h"

  8. //主要用来控制注册和识别
  9. int ISRegister = 1;

  10. int main(void)
  11. {
  12.     board_init();
  13.    
  14.     // 初始化FPM383C指纹模块
  15.     FPM383C_Init();

  16.     // 清空指纹库
  17.     FPM383C_Empty(2000);

  18.     // 随机id
  19.     srand((unsigned int)time(NULL));
  20.     int fpm383cPageId = rand() % 59 + 1;

  21.     while (1) {
  22.         if(ISRegister){
  23.             // 开启注册指纹,指纹ID:0—59, 超时时间尽量在 10秒左右,需要录入四次
  24.             FPM383C_Enroll(fpm383cPageId, 10000);
  25.             // 休息600毫秒进行下次注册
  26.             bflb_mtimer_delay_ms(600);
  27.             // 模块休眠一下
  28.             FPM383C_Sleep();
  29.             ISRegister = 0;
  30.         }else{
  31.             // 开启自动识别
  32.             FPM383C_Identify();
  33.         }

  34.         bflb_mtimer_delay_ms(10);
  35.     }
  36. }
复制代码

CMakeLists.txt
  1. cmake_minimum_required(VERSION 3.15)

  2. include(proj.conf)

  3. find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
  4. # User
  5. sdk_add_compile_definitions(-DCONFIG_CLI_CMD_ENABLE)
  6. #sdk_add_compile_definitions(-DBL616_DHCP_DEBUG)
  7. target_sources(app PRIVATE
  8.                 FPM383C.c)

  9. sdk_add_include_directories(.)

  10. sdk_set_main_file(main.c)

  11. project(fpm383c)
复制代码

其他文件都是通用的,就不放了。



回复 支持 反对

使用道具 举报

WT_0213 | 2023-12-30 13:08:45 | 显示全部楼层
指纹模块测试工具:

https://r0.hlktech.com/download/HLK-FPM383C/3/指纹测试工具.zip
串口测试工具:
串口测试工具.zip (411.02 KB, 下载次数: 6)
回复 支持 反对

使用道具 举报

lazy | 2023-12-30 13:24:23 | 显示全部楼层
本帖最后由 lazy 于 2023-12-30 13:48 编辑

很详细,厉害
回复 支持 反对

使用道具 举报

1084504793 | 2023-12-30 14:45:24 | 显示全部楼层
学到了
回复

使用道具 举报

hdydy | 2023-12-30 18:55:33 | 显示全部楼层
学习学习
回复

使用道具 举报

san | 2023-12-30 23:46:04 | 显示全部楼层
学到了
回复

使用道具 举报

End | 2023-12-31 10:44:01 | 显示全部楼层
要是都能够统一放到一个仓库就好了,测试完成都pr一下
羡慕
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则