FPM383F指纹模块超详解 附驱动

FPM383F指纹模块超详解 附驱动

0. 本人使用环境介绍

0.1 硬件环境

ESP32-C3FPM383C指纹模块一根破旧的usb数据线

0.2 软件环境

Clion2024.2.2ESP-IDF5.3.1Clion插件ESP-IDF

1. 硬件接口说明

1.1 UART

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

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

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

1.2 USB

标准 USB 接口,内嵌 USB 通讯协议;

兼容 USB2.0,工作在 Full Speed;

默认 VID=0x2109;默认 PID=0x7638;

1.3 UART 与 USB 协同工作

主控即可通过 UART 或 USB 与指纹模组通讯;

两个接口只能单独工作,不支持同时工作;

两个接口执行相同的协议和命令;

两个接口共享同一个数据缓冲区;

2. 业务类指令集

2.1 通用指令集

2.1.1 验证用获取图像PS_GetImage

2.1.1 代码实现

/**

* 从指纹传感器获取图像

*

* 该函数通过UART向指纹传感器发送指令,请求获取当前图像,并接收传感器的响应

* 根据响应中的状态码判断图像获取是否成功,以及图像质量是否符合要求

*

* @return uint8_t 返回状态码:

* - 0: 获取图像成功

* - 1: 图像不清晰,请重新采集

* - 2: 获取图像失败或其他错误

*/

uint8_t Finger_GetImage() {

// 准备发送给指纹传感器的数据包

uint8_t sent_data[13] = {

0xEF, 0x01, // 包头

0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址

0x01, // 包标识

0x00, 0x03, // 包长度

0x01, // 指令码

0x00, // 参数

0x00, 0x5 // 校验和

};

// 通过UART发送数据包

uart_write_bytes(UART_NUM_0, sent_data, 13);

// 准备接收指纹传感器的响应数据

uint8_t get_data[64];

// 读取UART接收到的数据,等待最多100ms

int st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);

// 检查读取状态

if (st >= 0) {

// 根据响应数据中的状态码判断图像获取结果

if (get_data[6] == 0x07 && get_data[10] == 0x00) {

printf("获取图像成功\r\n");

return 0;

} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {

printf("图像不清晰,请重新采集\r\n");

return 1;

}

}

// 如果读取失败或响应数据不符合预期,则返回错误码

return 2;

}

2.1.2 生成特征PS_GenChar

2.1.2 代码实现

/**

* 生成指纹特征

*

* 本函数通过UART向指纹模块发送指令,生成指纹特征

*

* @param buffer 指纹数据缓冲区

* @return uint8_t

* - 0: 特征生成成功

* - 1: 特征生成失败

* - 2: UART读写错误

*/

uint8_t Finger_GenChar(uint8_t buffer) {

// 构造发送数据包

uint8_t sent_data[13] = {

0xEF, 0x01, // 包头

0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址

0x01, // 包标识

0x00, 0x04, // 包长度

0x02, // 指令码

'\0', // 参数

'\0', '\0' // 校验和

};

// 将缓冲区数据放入发送数据包中

sent_data[10] = buffer;

// 计算校验和

uint16_t sum = sent_data[6] + sent_data[7] + sent_data[8] + sent_data[9] + sent_data[10];

// 将校验和放入发送数据包中

sent_data[11] = sum >> 8;

sent_data[12] = sum;

// 通过UART发送数据包

uart_write_bytes(UART_NUM_0, sent_data, 13);

// 接收指纹模块返回的数据

uint8_t get_data[64];

int st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);

// 根据返回数据判断特征生成结果

if (st >= 0) {

if (get_data[6] == 0x07 && get_data[10] == 0x00) {

printf("生成特征成功\r\n");

return 0;

} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {

printf("生成特征失败\r\n");

return 1;

}

}

// 如果读写错误,返回2

return 2;

}

2.1.3 搜索指纹PS_Search

2.1.3 代码实现

/**

* 搜索指纹指令

*

* 本函数通过UART向指纹模块发送搜索指令,并接收搜索结果

* 搜索指令是一个固定格式的字节序列,通过UART发送给指纹模块

* 接收到的数据显示搜索结果,包括成功、收包错误或搜索失败

*

* @return uint8_t 返回0表示搜索成功,返回1表示搜索失败或通信错误

*/

uint8_t FINGER_Search(void)

{

// 搜索指纹的指令序列,包含必要的指令码和参数

uint8_t command[17]={

0xEF,0x01,

0xFF,0xFF,0xFF,0xFF,

0x01,

0x00,0x08,

0x04,

0x01,

0x00,0x00,

0xFF,0xFF,

0x02,0x0C

};

// 通过UART发送搜索指令

uart_write_bytes(UART_NUM_1,command,17);

// 接收指纹模块返回的数据

uint8_t recv_data[64]={0};

int len=uart_read_bytes(UART_NUM_1,recv_data,64,500/portTICK_PERIOD_MS);

// 检查接收到的数据长度

if(len>0)

{

// 根据接收数据的内容判断搜索结果

if(recv_data[6]==0x07 && recv_data[9]==0x00)

{

printf("搜索成功\r\n");

return 0;

}

else if(recv_data[6]==0x07 && recv_data[9]==0x01)

{

printf("收包错误\r\n");

}

else if(recv_data[6]==0x07 && recv_data[9]==0x09)

{

printf("搜索失败\r\n");

}

}

// 如果没有接收到数据或接收到的数据不匹配任何条件,则返回1

return 1;

}

2.1.4 合并特征 PS_RegModel

2.1.4 代码实现

/**

* 注册指纹模型

*

* 本函数通过串口发送指令以注册指纹模型,并根据返回结果判断注册是否成功

*

* @return uint8_t 返回注册状态码:

* 0 - 合并成功

* 1 - 收包错误

* 2 - 合并失败

* 3 - 通信失败或其他错误

*/

uint8_t Finger_RegModel() {

// 准备发送的数据包,包含包头、设备地址、包标识、包长度、指令码、参数和校验和

uint8_t sent_data[13] = {

0xEF, 0x01, // 包头

0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址

0x01, // 包标识

0x00, 0x03, // 包长度

0x05, // 指令码

0x00, // 参数

0x00, 0x09 // 校验和

};

// 通过UART发送数据包

uart_write_bytes(UART_NUM_0, sent_data, 13);

// 准备接收数据缓冲区

uint8_t get_data[64];

// 通过UART读取返回数据,设置超时时间为100ms

int st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);

// 检查读取状态

if (st >= 0) {

// 根据返回数据判断注册结果

if (get_data[6] == 0x07 && get_data[10] == 0x00) {

printf("合并成功\r\n");

return 0;

} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {

printf("收包错误\r\n");

return 1;

} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {

printf("合并失败\r\n");

return 2;

}

}

// 如果通信失败或其他错误,返回3

return 3;

}

2.1.5 储存模板PS_StoreChar

2.1.5 代码实现

/**

* 函数: Finger_StoreChar

*

* 描述: 将一个字符的数据存储到指定的页面ID中。

*

* 参数:

* - buffer: 要存储的字符数据。

* - pageID: 目标页面的ID。

*

* 返回值:

* - 0: 存储成功。

* - 1: 收包错误。

* - 2: 超出指纹库范围。

* - 3: 通信失败或其他错误。

*/

uint8_t Finger_StoreChar(uint8_t buffer, uint16_t pageID) {

// 构造要发送的数据包

uint8_t sent_data[15] = {

0xEF, 0x01, // 包头

0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址

0x01, // 包标识

0x00, 0x03, // 包长度

0x06, // 指令码

'\0', // 缓冲区

'\0', '\0', //位置号

'\0', '\0' // 校验和

};

// 将要存储的字符数据放入数据包中

sent_data[10] = buffer;

// 计算数据包的校验和

uint16_t sum =

sent_data[6] + sent_data[7] + sent_data[8] + sent_data[9] + sent_data[10] + sent_data[11] + sent_data[12];

sent_data[11] = pageID >> 8;

sent_data[12] = pageID;

sent_data[13] = sum >> 8;

sent_data[14] = sum;

// 通过UART发送数据包

uart_write_bytes(UART_NUM_0, sent_data, 15);

// 接收响应数据

uint8_t get_data[64];

int st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);

// 根据响应数据判断存储结果

if (st >= 0) {

if (get_data[6] == 0x07 && get_data[10] == 0x00) {

printf("储存成功\r\n");

return 0;

} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {

printf("收包错误\r\n");

return 1;

} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {

printf("超出指纹库范围\r\n");

return 2;

}

}

return 3;

}

2.1.6 搜索指纹PS_Search

2.1.6 代码实现

/**

* 搜索指纹指令

*

* 本函数通过UART向指纹模块发送搜索指令,并接收搜索结果

* 搜索指令是一个固定格式的字节序列,通过UART发送给指纹模块

* 接收到的数据显示搜索结果,包括成功、收包错误或搜索失败

*

* @return uint8_t 返回0表示搜索成功,返回1表示搜索失败或通信错误

*/

uint8_t FINGER_Search(void)

{

// 搜索指纹的指令序列,包含必要的指令码和参数

uint8_t command[17]={

0xEF,0x01,

0xFF,0xFF,0xFF,0xFF,

0x01,

0x00,0x08,

0x04,

0x01,

0x00,0x00,

0xFF,0xFF,

0x02,0x0C

};

// 通过UART发送搜索指令

uart_write_bytes(UART_NUM_1,command,17);

// 接收指纹模块返回的数据

uint8_t recv_data[64]={0};

int len=uart_read_bytes(UART_NUM_1,recv_data,64,500/portTICK_PERIOD_MS);

// 检查接收到的数据长度

if(len>0)

{

// 根据接收数据的内容判断搜索结果

if(recv_data[6]==0x07 && recv_data[9]==0x00)

{

printf("搜索成功\r\n");

return 0;

}

else if(recv_data[6]==0x07 && recv_data[9]==0x01)

{

printf("收包错误\r\n");

}

else if(recv_data[6]==0x07 && recv_data[9]==0x09)

{

printf("搜索失败\r\n");

}

}

// 如果没有接收到数据或接收到的数据不匹配任何条件,则返回1

return 1;

}

2.1.7 休眠指令PS_Sleep

2.1.7 代码实现

/**

* @brief 控制指纹模块进入休眠模式

*

* 该函数通过UART向指纹模块发送休眠指令,使模块进入低功耗状态。

* 主要包括以下几个步骤:

* 1. 组装休眠指令的数据包。

* 2. 通过UART发送指令包。

* 3. 等待并接收指纹模块的响应。

* 4. 解析响应,判断休眠指令是否执行成功。

*

* @return uint8_t

* - 0: 指纹模块休眠成功

* - 1: 指纹模块休眠失败

*/

uint8_t Driver_Finger_Sleep()

{

// 组装发送给指纹模块的休眠指令包

uint8_t command[12] = {

0xEF, 0x01, // 包头

0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址

0x01, // 包标识

0x00, 0x03, // 包长度

0x33, // 指令码

0x00, 0x37 // 校验和

};

// 通过UART发送休眠指令包

uart_write_bytes(UART_NUM_1, command, 12);

// 初始化接收缓冲区

uint8_t recv_data[64] = {0};

// 等待并接收指纹模块的响应

int len =

uart_read_bytes(UART_NUM_1, recv_data, 64, 100 / portTICK_PERIOD_MS);

// 判断接收到的响应长度是否大于0

if (len > 0)

{

// 检查响应中的特定字段,判断休眠指令是否执行成功

if (recv_data[6] == 0x07 && recv_data[9] == 0x00)

{

// 休眠成功

printf("指纹模块休眠成功\r\n");

return 0;

}

}

// 休眠失败

printf("指纹模块休眠失败\r\n");

return 1;

}

通用指令更到这 待更新后续!!!