ZW101指纹模块

[复制链接]
7788 | 2024-4-26 21:40:42 | 显示全部楼层
感谢楼主
回复

使用道具 举报

知行合一 | 2024-4-26 21:48:05 | 显示全部楼层
感谢楼主
回复

使用道具 举报

楚华 | 2024-4-26 22:11:26 | 显示全部楼层
这个价位更低
回复 支持 反对

使用道具 举报

mmt | 2024-4-29 18:23:25 | 显示全部楼层
填坑啦~填坑啦~。这两天忙别的事,一直没把代码传上来,先传上效果图。

Snipaste_2024-04-25_20-46-52.png

回复 支持 反对

使用道具 举报

mmt | 2024-4-29 18:24:51 | 显示全部楼层
引脚图

Snipaste_2024-04-25_21-02-35.png
Snipaste_2024-04-25_21-02-44.png

回复 支持 反对

使用道具 举报

mmt | 2024-4-29 18:25:52 | 显示全部楼层
本帖最后由 mmt 于 2024-4-29 18:27 编辑

ZW101.c文件。实现了基本的功能,还有待优化。
  1. #include "ZW101.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. #include "matrix_key.h"

  11. extern uint16_t key_out();

  12. //缓冲区号
  13. #define Buffer1 0x01
  14. #define Buffer2 0x02

  15. //模块包头
  16. uint8_t PS_Head[2] = {0xEF,0x01};

  17. //模块地址
  18. uint8_t PS_Addr[4] = {0xFF,0xFF,0xFF,0xFF};

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

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

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

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

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

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

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

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

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

  39. //精确对比两枚指纹特征
  40. uint8_t PS_MatchBuf[12] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x03, 0x00, 0x07};

  41. //合并特征-将特征文件融合后生成一个模板,结果存于模板缓冲区中
  42. uint8_t PS_RegModelBuf[12] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x05, 0x00, 0x09};

  43. //储存模板-将模板缓冲区中的模板文件存储到OageID号flash数据库位置
  44. uint8_t PS_StoreBuf[15] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x06, 0x06, 0x01, 0x00, '\0', '\0', '\0'};

  45. //读出模板-将flash数据库中指定ID号的指纹模板读入到模板缓冲区中
  46. uint8_t PS_LoadCharBuf[15] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x06, 0x07, 0x01, '\0', '\0', '\0', '\0'};

  47. //上传模板-将保存在模板缓冲区中的模板文件上传给主控
  48. uint8_t PS_UpCharBuf[13] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x08, '\0', '\0', '\0'};

  49. //下载模板-主控下载模板到模组的一个模板缓冲区
  50. uint8_t PS_DownCharBuf[13] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x09, '\0', '\0', '\0'};

  51. //写系统寄存器-写模组寄存器
  52. uint8_t PS_WriteRegBuf[14] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x05, 0x0E, '\0', '\0', '\0', '\0'};

  53. //读模组基本参数-读取模组的基本参数(波特率、包大小等),参数表前16个字节存放了模组的基本通讯和配置信息,称为模组的基本参数
  54. uint8_t PS_ReadSysParaBuf[12] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x0F, 0x00, 0x13};

  55. //读参数页-读取flash information page 所在的参数页(512bytes)
  56. uint8_t PS_ReadINFpageBuf[12] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x16, 0x00, 0x1A};

  57. //读有效模板个数
  58. uint8_t PS_ValidTempleteNumBuf[12] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x1D, 0x00, 0x21};

  59. //读索引表-读取录入模板的索引表
  60. uint8_t PS_ReadIndexTableBuf[13] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x1F, '\0', '\0', '\0'};

  61. //注册用获取图像-注册指纹时,探测手指,探测到后录入指纹图像缓冲区
  62. uint8_t PS_GetEnrollImageBuf[12] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x29, 0x00, 0x2D};

  63. //获取模组附加参数
  64. uint8_t PS_ReadAddParaBuf[13] = {0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x62, 0x00, 0x66};

  65. //自动验证指纹-自动采集指纹包括获取图像、生成特征、搜索指纹等功能
  66. uint8_t PS_AutoIdentifyBuf[17] = {  0xEF, 0x01,
  67.                                     0xFF, 0xFF, 0xFF, 0xFF,
  68.                                     0x01,
  69.                                     0x00, 0x08,
  70.                                     0x32,
  71.                                     0x00,
  72.                                     0x00, 0x01,
  73.                                     0x00, 0x00,
  74.                                     0x00, 0x3C };

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

  77. //USART串口接收长度以及标志位
  78. uint8_t USART2_STA  = 0;

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

  81. //USART串口接收缓冲数组
  82. uint8_t USART_ReceiveBuf[30];

  83. //主循环状态标志位
  84. uint8_t ScanStatus = 0;

  85. /// @brief uart中断触发方法
  86. /// @param irq
  87. /// @param arg
  88. void uart_isr(int irq, void *arg)
  89. {
  90.           uint32_t intstatus = bflb_uart_get_intstatus(zw101_uart);
  91.            //接收超时中断,当一段时间内数据没有接收后便会停止,在触发中断后
  92.         uint8_t i = 0;
  93.     if (intstatus & UART_INTSTS_RTO) {
  94.                 // 检测缓冲区是否有数据
  95.         while (bflb_uart_rxavailable(zw101_uart)) {
  96.                         // 轮询fpm383c_uart接收到的字符
  97.                         uint8_t data = bflb_uart_getchar(zw101_uart);
  98.                         // 获取数据并放入缓冲数组
  99.                         USART_ReceiveBuf[i++] = data;
  100.         }
  101.                 //停止接收后清空中断标志等待下一次发送
  102.         bflb_uart_int_clear(zw101_uart, UART_INTCLR_RTO);
  103.                 USART2_STA = 1;
  104.     }
  105.         
  106. }

  107. /// @brief 初始化ZW101指纹模块
  108. void ZW101_Init(){
  109.         // 声明 gpio句柄
  110.     struct bflb_device_s* gpio;
  111.         // ZW101 模块默认波特率为 57600
  112.     struct bflb_uart_config_s cfg = {
  113.         .baudrate = 57600,
  114.         .data_bits = UART_DATA_BITS_8,
  115.         .stop_bits = UART_STOP_BITS_1,
  116.         .parity = UART_PARITY_NONE,
  117.         .flow_ctrl = 0,
  118.         .tx_fifo_threshold = 4,
  119.         .rx_fifo_threshold = 4,
  120.     };

  121.         // 初始化ZW101指纹模块UART
  122.     gpio = bflb_device_get_by_name("gpio");
  123.     zw101_uart = bflb_device_get_by_name("uart1");

  124.     //将GPIO_23和GPIO_24设置为TX和RX
  125.     bflb_gpio_uart_init(gpio, GPIO_PIN_23, GPIO_UART_FUNC_UART1_TX);
  126.     bflb_gpio_uart_init(gpio, GPIO_PIN_24, GPIO_UART_FUNC_UART1_RX);

  127.     bflb_uart_init(zw101_uart, &cfg);

  128.         // uart tx fifo 阈值中断屏蔽开关,开启后超过设定阈值则触发中断。
  129.     bflb_uart_txint_mask(zw101_uart, true);
  130.         // uart rx fifo 阈值中断和超时屏蔽开关这里用不上关闭即可。
  131.     bflb_uart_rxint_mask(zw101_uart, false);
  132.         // 注册中断入口函数
  133.     bflb_irq_attach(zw101_uart->irq_num, uart_isr, NULL);
  134.         //  使能 GPIO 中断
  135.     bflb_irq_enable(zw101_uart->irq_num);
  136. }

  137. /// @brief USART串口发送数据
  138. /// @param length 发送数组长度
  139. /// @param ZW101_DataBuf 需要发送的功能数组
  140. void ZW101_SendData(int length,uint8_t ZW101_DataBuf[])
  141. {

  142.         for(int i = 0;i<length;i++)
  143.         {
  144.         bflb_uart_put(zw101_uart,(uint8_t *)&ZW101_DataBuf[i], 1);
  145.         }
  146.         USART2_STA = 0;
  147. }

  148. /// @brief 写系统寄存器
  149. /// @param  
  150. uint8_t ZW101_WriteReg(uint16_t Reg_Num, uint16_t Content,uint16_t timeout)
  151. {
  152.     PS_WriteRegBuf[10] = Reg_Num;
  153.     PS_WriteRegBuf[11] = Content;
  154.     PS_WriteRegBuf[12] = (0x14 + PS_WriteRegBuf[10] + PS_WriteRegBuf[11]) >> 8;
  155.     PS_WriteRegBuf[13] = (0x14 + PS_WriteRegBuf[10] + PS_WriteRegBuf[11]);
  156.     for (size_t i = 0; i < 14; i++)
  157.     {
  158.         printf("PS_WriteRegBuf[%d]:,%x\r\n",i,PS_WriteRegBuf[i] );
  159.     }
  160.     ZW101_SendData(14, PS_WriteRegBuf);
  161.         while(!USART2_STA && (--timeout))
  162.         {
  163.                 bflb_mtimer_delay_ms(1);
  164.         }
  165.         uint8_t temp = USART_ReceiveBuf[9];
  166.         if (temp == 0)
  167.         {
  168.                 printf("\r\n设置完成");
  169.         }
  170.         else
  171.         {
  172.                 printf("\r\n设置错误");
  173.         }
  174.     memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  175.     return temp;
  176. }

  177. /// @brief 储存模板
  178. /// @param  
  179. uint8_t ZW101_StoreChar(uint8_t BufferID,uint16_t PageID,uint16_t timeout)
  180. {
  181.         PS_StoreBuf[10] = (BufferID);
  182.         PS_StoreBuf[11] = (PageID>>8);
  183.     PS_StoreBuf[12] = (PageID);
  184.         PS_StoreBuf[13] = (0x0D + PS_StoreBuf[10] + PS_StoreBuf[11] + PS_StoreBuf[12]) >> 8;
  185.         PS_StoreBuf[14] = (0x0D + PS_StoreBuf[10] + PS_StoreBuf[11] + PS_StoreBuf[12]);
  186.     ZW101_SendData(15, PS_StoreBuf);
  187.         while(!USART2_STA && (--timeout))
  188.         {
  189.                 bflb_mtimer_delay_ms(1);
  190.         }
  191.     uint8_t temp = USART_ReceiveBuf[9];
  192.         if (temp == 0)
  193.         {
  194.                 ZW101_ShowErrMessage(temp);
  195.                 printf("\r\n保存完毕,ID号为:%d",PageID);
  196.         }
  197.         else
  198.         {
  199.                 ZW101_ShowErrMessage(temp);
  200.                 printf("\r\n保存失败");
  201.         }
  202.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  203.     return temp;
  204. }

  205. /// @brief 读取模组的基本参数
  206. /// @param  
  207. uint16_t ZW101_ReadSysPara(SysPara *p, uint16_t timeout)
  208. {
  209.         uint8_t ensure;
  210.     ZW101_SendData(12, PS_ReadSysParaBuf);
  211.         while(!USART2_STA && (--timeout))
  212.         {
  213.                 printf("\r\n接收到信息");
  214.                 ensure = USART_ReceiveBuf[9];
  215.                 p->PS_max = (USART_ReceiveBuf[14]<<8)+USART_ReceiveBuf[15];
  216.                 p->PS_level = (USART_ReceiveBuf[16]<<8)+USART_ReceiveBuf[17];
  217.                 p->PS_addr = (USART_ReceiveBuf[18]<<24)+(USART_ReceiveBuf[19]<<16)+(USART_ReceiveBuf[20]<<8)+USART_ReceiveBuf[21];
  218.                 p->PS_size = (USART_ReceiveBuf[22]<<8)+USART_ReceiveBuf[23];
  219.                 p->PS_N = (USART_ReceiveBuf[24]<<8)+USART_ReceiveBuf[25];
  220.         }
  221.         ensure = (USART_ReceiveBuf[9] == 0x00 ? USART_ReceiveBuf[9] : 0xFF);
  222.         if(ensure==0x00)
  223.         {
  224.                 printf("\r\n模块最大指纹容量=%d",p->PS_max);
  225.                 printf("\r\n对比等级=%d",p->PS_level);
  226.                 printf("\r\n地址=%x",p->PS_addr);
  227.                 printf("\r\n波特率=%d",p->PS_N*9600);
  228.         }
  229.         else
  230.                 printf("\r\n错误");
  231.     return USART_ReceiveBuf[9];
  232. }

  233. /// @brief 读有效模板个数
  234. /// @param  
  235. uint16_t ZW101_ValidTempNum(uint16_t timeout)
  236. {
  237.         uint16_t ValidTempNum;
  238.     ZW101_SendData(12, PS_ValidTempleteNumBuf);
  239.         while(!USART2_STA && (--timeout))
  240.         {
  241.                 bflb_mtimer_delay_ms(1);
  242.         }
  243.         ValidTempNum = (int)((USART_ReceiveBuf[10] << 8) + USART_ReceiveBuf[11]);
  244.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  245.         return ValidTempNum;
  246. }

  247. /// @brief 发送休眠指令 确认码=00H 表示休眠设置成功。确认码=01H 表示休眠设置失败。
  248. /// @param  
  249. void ZW101_Sleep(void)
  250. {
  251.         ZW101_SendData(12,PS_SleepBuf);
  252. }

  253. /// @brief 验证用获取图像
  254. /// @param timeout 接收数据的超时时间
  255. /// @return 确认码
  256. uint8_t ZW101_GetImage(uint32_t timeout)
  257. {
  258.         uint8_t tmp;
  259.         ZW101_SendData(12,PS_GetImageBuf);
  260.         while(!USART2_STA && (--timeout))
  261.         {
  262.                 bflb_mtimer_delay_ms(1);
  263.         }
  264.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  265.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  266.         return tmp;
  267. }

  268. /// @brief 精确对比模版缓冲区中的特征文件。
  269. /// @param timeout 接收数据的超时时间
  270. /// @return 确认码
  271. uint8_t ZW101_Match(uint32_t timeout)
  272. {
  273.         uint8_t ensure;
  274.         ZW101_SendData(12,PS_MatchBuf);
  275.         while(!USART2_STA && (--timeout))
  276.         {
  277.                 bflb_mtimer_delay_ms(1);
  278.         }
  279.         ensure = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  280.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  281.         return ensure;
  282. }

  283. /// @brief 将图像缓冲区中的原始图像生成指纹特征文件存于模板缓冲区。
  284. /// @param timeout 接收数据的超时时间
  285. /// @return 确认码
  286. uint8_t ZW101_GenChar(uint8_t BufferID, uint32_t timeout)
  287. {
  288.         uint8_t tmp;
  289.         PS_GetCharBuf[10] = BufferID;
  290.         PS_GetCharBuf[11] = (0x07+PS_GetCharBuf[10])>>8;
  291.         PS_GetCharBuf[12] = (0x07+PS_GetCharBuf[10]);
  292.         ZW101_SendData(13,PS_GetCharBuf);
  293.         while(!USART2_STA && (--timeout))
  294.         {
  295.                 bflb_mtimer_delay_ms(1);
  296.         }
  297.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  298.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  299.         return tmp;
  300. }

  301. /// @brief 合并特征(生成模板)
  302. /// @param timeout 接收数据的超时时间
  303. /// @return 确认码
  304. uint8_t ZW101_RegModel(uint32_t timeout)
  305. {
  306.         uint8_t ensure;
  307.         ZW101_SendData(12, PS_RegModelBuf);
  308.         while(!USART2_STA && (--timeout))
  309.         {
  310.                 bflb_mtimer_delay_ms(1);
  311.         }
  312.         ensure = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  313.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  314.         return ensure;
  315. }

  316. /// @brief 发送搜索指纹指令
  317. /// @param timeout 接收数据的超时时间
  318. /// @return 确认码
  319. uint8_t ZW101_Search(uint32_t timeout)
  320. {
  321.         ZW101_SendData(17,PS_SearchBuf);
  322.         while(!USART2_STA && (--timeout))
  323.         {
  324.                 bflb_mtimer_delay_ms(1);
  325.         }
  326.         return (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  327. }

  328. ///@brief 上传模板
  329. ///@param BufferID 模板缓冲区
  330. ///@return 确认码
  331. uint8_t ZW101_UpChar(uint8_t BufferID,uint16_t timeout)
  332. {
  333.         PS_UpCharBuf[10] = (BufferID);
  334.         PS_UpCharBuf[11] = ((0x0D + PS_UpCharBuf[10])>>8);
  335.         PS_UpCharBuf[12] = ((0x0D + PS_UpCharBuf[10]));
  336.         ZW101_SendData(13, PS_UpCharBuf);
  337.         while(!USART2_STA && (--timeout))
  338.         {
  339.                 bflb_mtimer_delay_ms(1);
  340.         }
  341.         return (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  342. }

  343. ///@brief 下载模板
  344. ///@param BufferID 模板缓冲区
  345. ///@return 确认码
  346. uint8_t ZW101_DownChar(uint8_t BufferID,uint16_t timeout)
  347. {
  348.         PS_DownCharBuf[10] = (BufferID);
  349.         PS_DownCharBuf[11] = ((0x0E + PS_DownCharBuf[10])>>8);
  350.         PS_DownCharBuf[12] = ((0x0E + PS_DownCharBuf[10]));
  351.         ZW101_SendData(13, PS_DownCharBuf);
  352.         while(!USART2_STA && (--timeout))
  353.         {
  354.                 bflb_mtimer_delay_ms(1);
  355.         }
  356.         return (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  357. }

  358. /// @brief 删除指定指纹指令
  359. /// @param pageID 需要删除的指纹ID号
  360. /// @param timeout 接收数据的超时时间
  361. /// @return 确认码
  362. uint8_t ZW101_Delete(uint16_t pageID,uint32_t timeout)
  363. {
  364.         uint8_t tmp;
  365.         PS_DeleteBuf[10] = (pageID>>8);
  366.         PS_DeleteBuf[11] = (pageID);
  367.         PS_DeleteBuf[14] = (0x15+PS_DeleteBuf[10]+PS_DeleteBuf[11])>>8;
  368.         PS_DeleteBuf[15] = (0x15+PS_DeleteBuf[10]+PS_DeleteBuf[11]);
  369.         ZW101_SendData(16,PS_DeleteBuf);
  370.         while(!USART2_STA && (--timeout))
  371.         {
  372.                 bflb_mtimer_delay_ms(1);
  373.         }
  374.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  375.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  376.         return tmp;
  377. }

  378. /// @brief 清空指纹库
  379. /// @param timeout 接收数据的超时时间
  380. /// @return 确认码
  381. uint8_t ZW101_Empty(uint32_t timeout)
  382. {
  383.         uint8_t tmp;
  384.         ZW101_SendData(12,PS_EmptyBuf);
  385.         while(!USART2_STA && (--timeout))
  386.         {
  387.                 bflb_mtimer_delay_ms(1);
  388.         }
  389.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  390.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  391.         return tmp;
  392. }

  393. /// @brief 发送控制灯光指令
  394. /// @param PS_ControlLEDBuf 不同颜色的协议数据
  395. /// @param timeout 接收数据的超时时间
  396. /// @return 确认码
  397. uint8_t ZW101_ControlLED(uint8_t PS_ControlLEDBuf[],uint32_t timeout)
  398. {
  399.         uint8_t tmp;
  400.         ZW101_SendData(16,PS_ControlLEDBuf);
  401.         while(!USART2_STA && (--timeout))
  402.         {
  403.                 bflb_mtimer_delay_ms(1);
  404.         }
  405.         tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
  406.         memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  407.         return tmp;
  408. }

  409. /// @brief 自动注册
  410. /// @param pageID 输入需要注册的指纹ID号,取值范围0—59
  411. /// @param timeout 设置注册指纹超时时间,因为需要按压四次手指,建议大于10000(即10s)
  412. void ZW101_Enroll(uint16_t pageID, uint16_t timeout)
  413. {
  414.         LOG_E("注册指纹ID: %d\r\n", pageID);
  415.         PS_AutoEnrollBuf[10] = (pageID>>8);
  416.         PS_AutoEnrollBuf[11] = (pageID);
  417.         PS_AutoEnrollBuf[15] = (0x52+PS_AutoEnrollBuf[10]+PS_AutoEnrollBuf[11])>>8;
  418.         PS_AutoEnrollBuf[16] = (0x52+PS_AutoEnrollBuf[10]+PS_AutoEnrollBuf[11]);
  419.         ZW101_SendData(17,PS_AutoEnrollBuf);
  420.         while(!USART2_STA && (--timeout))
  421.         {
  422.                 bflb_mtimer_delay_ms(1);
  423.         }
  424.         if(USART_ReceiveBuf[9] == 0x00)
  425.         {
  426.                 LOG_E("指纹注册完成\r\n");
  427.                 // 亮绿灯2秒
  428.                 ZW101_ControlLED(PS_GreenLEDBuf,2000);
  429.                 // 重置接收数据缓存
  430.                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  431.                 return;
  432.         }
  433.         else if(timeout == 0)
  434.         {
  435.                 // 超时取消注册
  436.                 ZW101_SendData(12,PS_CancelBuf);
  437.                 bflb_mtimer_delay_ms(50);
  438.                 // 重置接收数据缓存
  439.                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  440.         }
  441.         // 亮红灯2秒
  442.         ZW101_ControlLED(PS_RedLEDBuf,2000);
  443. }

  444. /// @brief 验证指纹是否注册
  445. /// @param  
  446. void ZW101_Identify(void)
  447. {
  448.         uint8_t ensure;
  449.         ensure = ZW101_GetImage(2000);
  450.         if(ensure == 0x00)
  451.         {
  452.                 ensure = ZW101_GenChar(Buffer1, 2000);
  453.                 if(ensure == 0x00)
  454.                 {
  455.                         struct bflb_device_s *led = bflb_device_get_by_name("gpio");
  456.                         if(ZW101_Search(2000) == 0x00)
  457.                         {
  458.                                 score = (int)((USART_ReceiveBuf[10] << 8) + USART_ReceiveBuf[11]);
  459.                                 LOG_E("解锁成功 指纹ID:%d\r\n",(int)score);
  460.                                 ZW101_ControlLED(PS_GreenLEDBuf,1000);               
  461.                                 bflb_gpio_init(led, GPIO_PIN_14, GPIO_OUTPUT);
  462.                                 bflb_gpio_set(led, GPIO_PIN_14);
  463.                                 bflb_mtimer_delay_ms(1000);
  464.                                 bflb_gpio_reset(led, GPIO_PIN_14);
  465.                                 // 重置接收数据缓存
  466.                                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  467.                                 return;
  468.                         }else{
  469.                                 LOG_E("解锁失败\r\n");
  470.                                 bflb_gpio_init(led, GPIO_PIN_12, GPIO_OUTPUT);
  471.                                 bflb_gpio_set(led, GPIO_PIN_12);
  472.                                 bflb_mtimer_delay_ms(1000);
  473.                                 bflb_gpio_reset(led, GPIO_PIN_12);
  474.                                 // 重置接收数据缓存
  475.                                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  476.                                 return;
  477.                         }
  478.                 }
  479.         }
  480. }

  481. /// @brief 自动验证指纹是否注册
  482. /// @param  
  483. void ZW101_AutoIdentify(void){
  484.     if(ZW101_GetImage(2000) == 0x00)
  485.     {
  486.         if(ZW101_GenChar(Buffer1, 2000) == 0x00)
  487.         {
  488.             struct bflb_device_s *led = bflb_device_get_by_name("gpio");
  489.             if(ZW101_Search(2000) == 0x00)
  490.             {
  491.                 ZW101_SendData(17, PS_AutoIdentifyBuf);               
  492.                 score = (int)((USART_ReceiveBuf[11] << 8) + USART_ReceiveBuf[12]);
  493.                                 LOG_E("解锁成功 指纹ID:%d\r\n",(int)score);
  494.                                 ZW101_ControlLED(PS_GreenLEDBuf,1000);               
  495.                                 bflb_gpio_init(led, GPIO_PIN_14, GPIO_OUTPUT);
  496.                                 bflb_gpio_set(led, GPIO_PIN_14);
  497.                                 bflb_mtimer_delay_ms(1000);
  498.                                 bflb_gpio_reset(led, GPIO_PIN_14);
  499.                                 // 重置接收数据缓存
  500.                                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  501.                                 return;
  502.             }else{
  503.                                 LOG_E("解锁失败\r\n");
  504.                                 bflb_gpio_init(led, GPIO_PIN_12, GPIO_OUTPUT);
  505.                                 bflb_gpio_set(led, GPIO_PIN_12);
  506.                                 bflb_mtimer_delay_ms(1000);
  507.                                 bflb_gpio_reset(led, GPIO_PIN_12);
  508.                                 // 重置接收数据缓存
  509.                                 memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
  510.                                 return;
  511.                         }
  512.         }
  513.     }
  514. }

  515. /// @brief 录入指纹
  516. /// @param  
  517. void ZW101_Add(void)
  518. {
  519.         uint8_t ensure, processnum = 0;
  520.         uint16_t PageID = 0;
  521.         struct bflb_device_s *led = bflb_device_get_by_name("gpio");
  522.         printf("\r\n开始录入指纹");
  523.         while (1)
  524.         {
  525.                 switch (processnum)
  526.                 {
  527.                         case 0:
  528.                                 ensure = ZW101_GetImage(2000);
  529.                                 if (ensure == 0x00)
  530.                                 {
  531.                                         ensure = ZW101_GenChar(Buffer1, 2000);
  532.                                         if (ensure == 0x00)
  533.                                         {
  534.                                                 printf("\r\n指纹一正常");
  535.                                                 ZW101_ControlLED(PS_GreenLEDBuf,1000);               
  536.                                                 bflb_gpio_init(led, GPIO_PIN_14, GPIO_OUTPUT);
  537.                                                 bflb_gpio_set(led, GPIO_PIN_14);
  538.                                                 bflb_mtimer_delay_ms(1000);
  539.                                                 bflb_gpio_reset(led, GPIO_PIN_14);
  540.                                                 processnum = 1;
  541.                                         }
  542.                                 }
  543.                                 break;
  544.                         case 1:
  545.                                 ensure = ZW101_GetImage(2000);
  546.                                 if (ensure == 0x00)
  547.                                 {
  548.                                         ensure = ZW101_GenChar(Buffer2, 2000);
  549.                                         if (ensure == 0x00)
  550.                                         {
  551.                                                 printf("\r\n指纹二正常");
  552.                                                 ZW101_ControlLED(PS_GreenLEDBuf,1000);               
  553.                                                 bflb_gpio_init(led, GPIO_PIN_14, GPIO_OUTPUT);
  554.                                                 bflb_gpio_set(led, GPIO_PIN_14);
  555.                                                 bflb_mtimer_delay_ms(1000);
  556.                                                 bflb_gpio_reset(led, GPIO_PIN_14);
  557.                                                 processnum = 3;
  558.                                         }                        
  559.                                 }
  560.                                 break;
  561.                         case 2:
  562.                                 ensure = ZW101_Match(2000);
  563.                                 if (ensure == 0x00)
  564.                                 {
  565.                                         printf("\r\n对比成功,两次指纹一样");
  566.                                         processnum = 3;
  567.                                 }
  568.                                 else
  569.                                 {
  570.                                         ZW101_ShowErrMessage(ensure);
  571.                                         processnum = 0;
  572.                                 }
  573.                                 bflb_mtimer_delay_ms(1200);
  574.                                 break;
  575.                         case 3:
  576.                                 ensure = ZW101_RegModel(2000);
  577.                                 if (ensure == 0x00)
  578.                                 {
  579.                                         printf("\r\n生成指纹模板成功");
  580.                                         processnum = 4;
  581.                                 }
  582.                                 else
  583.                                 {
  584.                                         ZW101_ShowErrMessage(ensure);
  585.                                         processnum = 0;
  586.                                 }
  587.                                 bflb_mtimer_delay_ms(1200);
  588.                                 break;
  589.                         case 4:
  590.                                 do
  591.                                 {
  592.                                         PageID = key_out();
  593.                                 } while (PageID == 0);
  594.                                 ensure = ZW101_StoreChar(Buffer2,PageID,2000);
  595.                                 if (ensure == 0x00)
  596.                                 {
  597.                                         printf("\r\n录入指纹成功");
  598.                                         ZW101_ValidTempNum(2000);
  599.                                         return ;
  600.                                 }
  601.                                 else
  602.                                 {
  603.                                         ZW101_ShowErrMessage(ensure);
  604.                                         processnum = 0;
  605.                                 }
  606.                                 break;
  607.                         }
  608.         }
  609. }

  610. ///模板应答包确认码解析
  611. /// @brief 解析确认码错误信息
  612. /// @param ensure 确认码
  613. /// @return 返回确认码信息
  614. const char *EnsureMessage(uint8_t ensure)
  615. {
  616.         const char *p;
  617.         switch(ensure)
  618.         {
  619.                 case  0x00:
  620.                         p="OK";break;               
  621.                 case  0x01:
  622.                         p="数据包接受错误";break;
  623.                 case  0x02:
  624.                         p="传感器上没有手指";break;
  625.                 case  0x03:
  626.                         p="录入指纹图像失败";break;
  627.                 case  0x04:
  628.                         p="指纹图像太干、太淡而生不成特征";break;
  629.                 case  0x05:
  630.                         p="指纹图像太湿、太糊而生不成特征";break;
  631.                 case  0x06:
  632.                         p="指纹图像太乱而生不成特征";break;
  633.                 case  0x07:
  634.                         p="指纹图像正常,但特征点太少(面积太小)而生不成特征";break;
  635.                 case  0x08:
  636.                         p="指纹不匹配";break;
  637.                 case  0x09:
  638.                         p="没搜索到指纹";break;
  639.                 case  0x0a:
  640.                         p="特征合并失败";break;
  641.                 case  0x0b:
  642.                         p="访问指纹库时地址序号超出指纹库范围";break;
  643.                 case  0x0c:
  644.                         p="从指纹库读模板出错或无效";break;
  645.                 case  0x0d:
  646.                         p="上传特征失败";break;
  647.                 case  0x0e:
  648.                         p="模组不能接收后续数据包";break;
  649.                 case  0x0f:
  650.                         p="上传图像失败";break;
  651.                 case  0x10:
  652.                         p="删除模板失败";break;
  653.                 case  0x11:
  654.                         p="清空指纹库失败";break;
  655.                 case  0x12:
  656.                         p="不能进入低功耗状态";break;        
  657.                 case  0x13:
  658.                         p="口令不正确";break;        
  659.                 case  0x14:
  660.                         p="系统复位失败";break;               
  661.                 case  0x15:
  662.                         p="缓冲区内没有有效原始图像而生不成图像";break;
  663.                 case  0x17:
  664.                         p="残留指纹或两次采集之间手指没有移动过";break;
  665.                 case  0x18:
  666.                         p="读写FLASH出错";break;
  667.                 case  0x1a:
  668.                         p="无效寄存器号";break;
  669.                 case  0x1b:
  670.                         p="寄存器设定内容错误号";break;
  671.                 case  0x1c:
  672.                         p="记事本页码指定错误";break;
  673.                 case  0x1d:
  674.                         p="端口操作失败";break;
  675.                 case  0x1e:
  676.                         p="自动注册失败";break;
  677.                 case  0x1f:
  678.                         p="指纹库满";break;
  679.                 case  0x20:
  680.                         p="设备地址错误";break;
  681.                 case  0x21:
  682.                         p="密码有误";break;
  683.                 case  0x22:
  684.                         p="指纹模板非空";break;
  685.                 case  0x23:
  686.                         p="指纹模板为空";break;
  687.                 case  0x24:
  688.                         p="指纹库为空";break;
  689.                 case  0x25:
  690.                         p="录入次数设置错误";break;
  691.                 case  0x26:
  692.                         p="超时";break;
  693.                 case  0x27:
  694.                         p="指纹已存在";break;
  695.                 case  0x28:
  696.                         p="指纹模板有关联";break;
  697.                 case  0x29:
  698.                         p="传感器初始化失败";break;
  699.                 case  0x2A:
  700.                         p="模组信息非空";break;
  701.                 case  0x2B:
  702.                         p="模组信息为空";break;
  703.                 case  0x33:
  704.                         p="图像面积小";break;
  705.                 case  0x34:
  706.                         p="图像不可用";break;
  707.                 case  0x35:
  708.                         p="非法数据";break;
  709.                 default :
  710.                         p="注册次数少于规定次数";break;
  711.         }
  712. return p;        
  713. }

  714. ///显示确认码错误信息
  715. /// @param ensure 确认码
  716. void ZW101_ShowErrMessage(uint8_t ensure)
  717. {
  718.         char *p = EnsureMessage(ensure);
  719.         printf("\r\n%s",p);
  720. }
复制代码


回复 支持 反对

使用道具 举报

mmt | 2024-4-29 18:28:57 | 显示全部楼层
ZW101.h

  1. #ifndef __ZW101_H
  2. #define __ZW101_H
  3. #include "stdint.h"

  4. typedef struct
  5. {
  6.         uint16_t PS_max;//指纹最大容量
  7.         uint8_t  PS_level;//安全等级
  8.         uint32_t PS_addr;
  9.         uint8_t  PS_size;//通讯数据包大小
  10.         uint8_t  PS_N;//波特率
  11. }SysPara;
  12. void ZW101_Init(void);
  13. void ZW101_SendData(int length, uint8_t buffer[]);
  14. void ZW101_Sleep(void);
  15. uint16_t ZW101_ReadSysPara(SysPara *p, uint16_t timeout);
  16. uint8_t ZW101_StoreChar(uint8_t BufferID,uint16_t PageID,uint16_t timeout);
  17. uint8_t ZW101_WriteReg(uint16_t Reg_Num, uint16_t Content,uint16_t timeout);
  18. uint8_t ZW101_GetImage(uint32_t timeout);
  19. uint8_t ZW101_GenChar(uint8_t BufferID, uint32_t timeout);
  20. uint8_t ZW101_RegModel(uint32_t timeout);
  21. uint8_t ZW101_Match(uint32_t timeout);
  22. uint8_t ZW101_Search(uint32_t timeout);
  23. uint8_t ZW101_UpChar(uint8_t BufferID,uint16_t timeout);
  24. uint8_t ZW101_DownChar(uint8_t BufferID,uint16_t timeout);
  25. uint8_t ZW101_Empty(uint32_t timeout);
  26. uint8_t ZW101_Delete(uint16_t pageID,uint32_t timeout);
  27. uint8_t ZW101_ControlLED(uint8_t PS_ControlLEDBuf[],uint32_t timeout);
  28. void ZW101_Enroll(uint16_t pageID,uint16_t timeout);
  29. void ZW101_Identify(void);
  30. void ZW101_AutoIdentify(void);
  31. uint16_t ZW101_ValidTempNum(uint16_t timeout);
  32. void ZW101_Add(void);
  33. const char *EnsureMessage(uint8_t ensure);
  34. void ZW101_ShowErrMessage(uint8_t ensure);


  35. #endif
复制代码


回复 支持 反对

使用道具 举报

mmt | 2024-4-29 18:34:08 | 显示全部楼层
main.c配合HID可以实现Win下的指纹解锁。将不同的指纹对应不同软件的密码,可以实现一键输入。

  1. #include "usbh_core.h"
  2. #include "bflb_mtimer.h"
  3. #include "bflb_dma.h"
  4. #include "bflb_uart.h"
  5. #include "bflb_l1c.h"
  6. #include "board.h"
  7. #include "time.h"
  8. #include "ZW101.h"
  9. #include "matrix_key.h"


  10. #define DBG_TAG "MAIN"
  11. #include "log.h"

  12. //主要用来控制注册和识别
  13. int ISRegister = 0;

  14. //指纹模块的参数
  15. SysPara ZW101_Para;

  16. extern void hid_keyboard_init(void);
  17. extern void hid_send_key(uint16_t val);
  18. extern uint16_t key_out();
  19. extern void matrix_keys_init();

  20. int main(void)
  21. {
  22.     board_init();
  23.     matrix_keys_init();
  24.     hid_keyboard_init();
  25.     ZW101_Init();
  26.     ZW101_Empty(2000);
  27.     srand((unsigned int)time(NULL));
  28.     uint16_t key_val = 0;
  29.     uint8_t ISRegister = 0;

  30.     while (1) {
  31.         key_val = key_out();
  32.         if (key_val == 10)
  33.         {
  34.             ISRegister = 1;
  35.         }
  36.         else if (key_val == 11)
  37.         {
  38.             ISRegister = 2;
  39.             
  40.         }
  41.         else if (key_val == 12)
  42.         {
  43.             ISRegister = 3;
  44.             
  45.         }
  46.         else if (key_val == 13)
  47.         {
  48.             ZW101_ReadSysPara(&ZW101_Para,2000);
  49.         }
  50.         if (ISRegister == 1)
  51.         {
  52.             ZW101_Add();
  53.             ISRegister = 0;
  54.         }
  55.         else if (ISRegister == 2)
  56.         {
  57.             ZW101_Identify();
  58.         }
  59.         else if (ISRegister == 3)
  60.         {
  61.             ZW101_WriteReg(0x05,0x03,2000);
  62.         }
  63.         bflb_mtimer_delay_ms(10);      
  64.     }
  65. }
复制代码


回复 支持 反对

使用道具 举报

mmt | 2024-4-29 18:46:22 | 显示全部楼层
配合HID后的效果图,HID传输中未加FreeRTOS,指纹一和指纹二对应字符串“123”,指纹三对应字符串“12345”。

Snipaste_2024-04-29_18-43-04.png

回复 支持 反对

使用道具 举报

King6688 | 2024-5-2 14:25:27 | 显示全部楼层
mmt 发表于 2024-4-29 18:25
ZW101.c文件。实现了基本的功能,还有待优化。

有点长,建议发压缩包
回复 支持 反对

使用道具 举报

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

本版积分规则