| 本帖最后由 WT_0213 于 2024-4-22 21:54 编辑 
 接下来上干货,之所以放在二楼是因为怕编辑太多发布失败丢失数据。
 FPM383C.h
 
 FPM383C.c复制代码#ifndef __FPM383C_H
#define __FPM383C_H
#include "stdint.h"
void FPM383C_Init(void);
void FPM383C_SendData(int length, uint8_t buffer[]);
void FPM383C_Sleep(void);
uint8_t FPM383C_GetImage(uint32_t timeout);
uint8_t FPM383C_GenChar(uint32_t timeout);
uint8_t FPM383C_Search(uint32_t timeout);
uint8_t FPM383C_Empty(uint32_t timeout);
uint8_t FPM383C_Delete(uint16_t pageID,uint32_t timeout);
uint8_t FPM383C_ControlLED(uint8_t PS_ControlLEDBuf[],uint32_t timeout);
void FPM383C_Identify(void);
void FPM383C_Enroll(uint16_t pageID,uint16_t timeout);
#endif
 main.c复制代码#include "FPM383C.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "bflb_mtimer.h"
#include "bflb_dma.h"
#include "bflb_uart.h"
#include "bflb_gpio.h"
#include "log.h"
//控制模块LED灯颜色
uint8_t PS_BlueLEDBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x03,0x01,0x01,0x00,0x00,0x49};
uint8_t PS_RedLEDBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x02,0x04,0x04,0x02,0x00,0x50};
uint8_t PS_GreenLEDBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x02,0x02,0x02,0x02,0x00,0x4C};
//休眠指令-设置传感器进入休眠模式
uint8_t PS_SleepBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x33,0x00,0x37};
//清空指纹库-删除 flash 数据库中所有指纹模板。
uint8_t PS_EmptyBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x0D,0x00,0x11};
//取消指令-取消自动注册模板和自动验证指纹。如表 2-1 中加密等级设置为 0 或 1 情况下支持此功能
uint8_t PS_CancelBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x30,0x00,0x34};
//自动注册模板-一站式注册指纹,包含采集指纹、生成特征、组合模板、存储模板等功能。加密等级设置为 0 或 1 情况下支持此功能。
uint8_t PS_AutoEnrollBuf[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x31,'\0','\0',0x04,0x00,0x16,'\0','\0'}; 
// 验证用获取图像-验证指纹时,探测手指,探测到后录入指纹图像存于图像缓冲区。返回确认码表示:录入成功、无手指等。
uint8_t PS_GetImageBuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x01,0x00,0x05};
//生成特征值-将图像缓冲区中的原始图像生成指纹特征文件存于模板缓冲区
uint8_t PS_GetCharBuf[13] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x04,0x02,0x01,0x00,0x08};
//搜索指纹-以模板缓冲区中的特征文件搜索整个或部分指纹库。若搜索到,则返回页码。加密等级设置为 0 或 1 情况下支持
uint8_t PS_SearchBuf[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x04,0x01,0x00,0x00,0xFF,0xFF,0x02,0x0C};
//删除模板-删除 flash 数据库中指定 ID 号开始的N 个指纹模板
uint8_t PS_DeleteBuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x0C,'\0','\0',0x00,0x01,'\0','\0'};
//设置名为fpm383c_uart的外设句柄,用来执行串口指令的发送
struct bflb_device_s *fpm383c_uart;
//指纹ID和验证指纹的分数
uint16_t pageID,score;
//USART串口接收缓冲数组
uint8_t USART_ReceiveBuf[20];
//主循环状态标志位
uint8_t ScanStatus = 0;
/**
 * @brief 获取状态
 * 
 * @param Timeout 
 */
void FPM383C_ReceiveData(uint16_t Timeout)
{
  uint8_t i = 0;
  // 检测缓冲区是否有数据
  while(bflb_uart_rxavailable(fpm383c_uart) == 0 && (--Timeout))
  {
    bflb_mtimer_delay_ms(1);
  }
  // 轮询fpm383c_uart接收到的字符
  while(bflb_uart_rxavailable(fpm383c_uart) > 0)
  {
    bflb_mtimer_delay_ms(2);
        // 获取数据并放入缓冲数组
    USART_ReceiveBuf[i++] = bflb_uart_getchar(fpm383c_uart);
    if(i > 15) break; 
  }
}
/// @brief 初始化FPM383C指纹模块
void FPM383C_Init(){
        // 声明 gpio句柄
    struct bflb_device_s* gpio;
        // FPM383C 模块默认波特率为 57600 
    struct bflb_uart_config_s cfg = {
        .baudrate = 57600,
        .data_bits = UART_DATA_BITS_8,
        .stop_bits = UART_STOP_BITS_1,
        .parity = UART_PARITY_NONE,
               .flow_ctrl = UART_FLOWCTRL_NONE,
        .rx_fifo_threshold = 7,
        .tx_fifo_threshold = 7
    };
        // 初始化FPM383C指纹模块UART
    gpio = bflb_device_get_by_name("gpio");
    fpm383c_uart = bflb_device_get_by_name("uart1");
    //将GPIO_23和GPIO_24设置为TX和RX
    bflb_gpio_uart_init(gpio, GPIO_PIN_23, GPIO_UART_FUNC_UART1_TX);
    bflb_gpio_uart_init(gpio, GPIO_PIN_24, GPIO_UART_FUNC_UART1_RX);
    bflb_uart_init(fpm383c_uart, &cfg);
}
/// @brief USART串口发送数据
/// @param length 发送数组长度
/// @param FPM383C_DataBuf 需要发送的功能数组
void FPM383C_SendData(int length,uint8_t FPM383C_DataBuf[])
{
        for(int i = 0;i<length;i++)
        {
        bflb_uart_put(fpm383c_uart,(uint8_t *)&FPM383C_DataBuf[i], 1);
        }
}
/// @brief 发送休眠指令 确认码=00H 表示休眠设置成功。确认码=01H 表示休眠设置失败。
/// @param  
void FPM383C_Sleep(void)
{
        FPM383C_SendData(12,PS_SleepBuf);
}
/// @brief 验证用获取图像
/// @param timeout 接收数据的超时时间
/// @return 确认码
uint8_t FPM383C_GetImage(uint32_t timeout)
{
        uint8_t tmp;
        FPM383C_SendData(12,PS_GetImageBuf);
        FPM383C_ReceiveData(timeout);
        tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
        memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
        return tmp;
}
/// @brief 将图像缓冲区中的原始图像生成指纹特征文件存于模板缓冲区。
/// @param timeout 接收数据的超时时间
/// @return 确认码
uint8_t FPM383C_GenChar(uint32_t timeout)
{
        uint8_t tmp;
        FPM383C_SendData(13,PS_GetCharBuf);
        FPM383C_ReceiveData(timeout);
        tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
        memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
        return tmp;
}
/// @brief 发送搜索指纹指令
/// @param timeout 接收数据的超时时间
/// @return 确认码
uint8_t FPM383C_Search(uint32_t timeout)
{
        FPM383C_SendData(17,PS_SearchBuf);
        FPM383C_ReceiveData(timeout);
        return (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
}
/// @brief 删除指定指纹指令
/// @param pageID 需要删除的指纹ID号
/// @param timeout 接收数据的超时时间
/// @return 确认码
uint8_t FPM383C_Delete(uint16_t pageID,uint32_t timeout)
{
        uint8_t tmp;
        PS_DeleteBuf[10] = (pageID>>8);
        PS_DeleteBuf[11] = (pageID);
        PS_DeleteBuf[14] = (0x15+PS_DeleteBuf[10]+PS_DeleteBuf[11])>>8;
        PS_DeleteBuf[15] = (0x15+PS_DeleteBuf[10]+PS_DeleteBuf[11]);
        FPM383C_SendData(16,PS_DeleteBuf);
        FPM383C_ReceiveData(timeout);
        tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
        memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
        return tmp;
}
/// @brief 清空指纹库
/// @param timeout 接收数据的超时时间
/// @return 确认码
uint8_t FPM383C_Empty(uint32_t timeout)
{
        uint8_t tmp;
        FPM383C_SendData(12,PS_EmptyBuf);
        FPM383C_ReceiveData(timeout);
        tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
        memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
        return tmp;
}
/// @brief 发送控制灯光指令
/// @param PS_ControlLEDBuf 不同颜色的协议数据
/// @param timeout 接收数据的超时时间
/// @return 确认码
uint8_t FPM383C_ControlLED(uint8_t PS_ControlLEDBuf[],uint32_t timeout)
{
        uint8_t tmp;
        FPM383C_SendData(16,PS_ControlLEDBuf);
        FPM383C_ReceiveData(timeout);
        tmp = (USART_ReceiveBuf[6] == 0x07 ? USART_ReceiveBuf[9] : 0xFF);
        memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
        return tmp;
}
/// @brief 验证指纹是否注册
/// @param  
void FPM383C_Identify(void)
{
        if(FPM383C_GetImage(2000) == 0x00)
        {
                if(FPM383C_GenChar(2000) == 0x00)
                {
                        struct bflb_device_s *led = bflb_device_get_by_name("gpio");
                        if(FPM383C_Search(2000) == 0x00)
                        {
                                score = (int)((USART_ReceiveBuf[10] << 8) + USART_ReceiveBuf[11]);
                                LOG_E("解锁成功 指纹ID:%d\r\n",(int)score);
                                FPM383C_ControlLED(PS_GreenLEDBuf,1000);
                
                                bflb_gpio_init(led, GPIO_PIN_14, GPIO_OUTPUT);
                                bflb_gpio_set(led, GPIO_PIN_14);
                                bflb_mtimer_delay_ms(1000);
                                bflb_gpio_reset(led, GPIO_PIN_14);
                                // 重置接收数据缓存
                                memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
                                return;
                        }else{
                                LOG_E("解锁失败\r\n");
                                bflb_gpio_init(led, GPIO_PIN_12, GPIO_OUTPUT);
                                bflb_gpio_set(led, GPIO_PIN_12);
                                bflb_mtimer_delay_ms(1000);
                                bflb_gpio_reset(led, GPIO_PIN_12);
                                // 重置接收数据缓存
                                memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
                                return;
                        }
                }
        }
}
/// @brief 自动注册
/// @param pageID 输入需要注册的指纹ID号,取值范围0—59
/// @param timeout 设置注册指纹超时时间,因为需要按压四次手指,建议大于10000(即10s)
void FPM383C_Enroll(uint16_t pageID,uint16_t timeout)
{
        LOG_E("注册指纹ID: %d\r\n", pageID);
        PS_AutoEnrollBuf[10] = (pageID>>8);
        PS_AutoEnrollBuf[11] = (pageID);
        PS_AutoEnrollBuf[15] = (0x54+PS_AutoEnrollBuf[10]+PS_AutoEnrollBuf[11])>>8;
        PS_AutoEnrollBuf[16] = (0x54+PS_AutoEnrollBuf[10]+PS_AutoEnrollBuf[11]);
        FPM383C_SendData(17,PS_AutoEnrollBuf);
        FPM383C_ReceiveData(timeout);
        if(USART_ReceiveBuf[9] == 0x00)
        {
                LOG_E("指纹注册完成\r\n");
                // 亮绿灯2秒
                FPM383C_ControlLED(PS_GreenLEDBuf,2000);
                // 重置接收数据缓存
                memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
                return;
        }
        else if(timeout == 0)
        {
                // 超时取消注册
                FPM383C_SendData(12,PS_CancelBuf);
                bflb_mtimer_delay_ms(50);
                // 重置接收数据缓存
                memset(USART_ReceiveBuf,0xFF,sizeof(USART_ReceiveBuf));
        }
        // 亮红灯2秒
        FPM383C_ControlLED(PS_RedLEDBuf,2000);
}
 复制代码#include "bflb_mtimer.h"
#include "bflb_dma.h"
#include "bflb_uart.h"
#include "bflb_l1c.h"
#include "board.h"
#include "time.h"
#include "FPM383C.h"
//主要用来控制注册和识别
int ISRegister = 1;
int main(void)
{
    board_init();
    
    // 初始化FPM383C指纹模块
    FPM383C_Init();
    // 清空指纹库
    FPM383C_Empty(2000);
    // 随机id
    srand((unsigned int)time(NULL));
    int fpm383cPageId = rand() % 59 + 1;
    while (1) {
        if(ISRegister){
            // 开启注册指纹,指纹ID:0—59, 超时时间尽量在 10秒左右,需要录入四次
            FPM383C_Enroll(fpm383cPageId, 10000);
            // 休息600毫秒进行下次注册
            bflb_mtimer_delay_ms(600);
            // 模块休眠一下
            FPM383C_Sleep();
            ISRegister = 0;
        }else{
            // 开启自动识别
            FPM383C_Identify();
        }
        bflb_mtimer_delay_ms(10);
    }
}
CMakeLists.txt
 
 复制代码cmake_minimum_required(VERSION 3.15)
include(proj.conf)
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
# User
sdk_add_compile_definitions(-DCONFIG_CLI_CMD_ENABLE)
#sdk_add_compile_definitions(-DBL616_DHCP_DEBUG)
target_sources(app PRIVATE
                FPM383C.c)
sdk_add_include_directories(.)
sdk_set_main_file(main.c)
project(fpm383c)
其他文件都是通用的,就不放了。
 
 
 
 
 |