光學(xué)指紋識別傳感器采用了國內(nèi)著名指紋識別芯片公司杭州晟元芯片技術(shù)有限公司(Synochip) 的 AS608 指紋識別芯片。芯片內(nèi)置 DSP 運算單元,集成了指紋識別算法,能高效快速采集 圖像并識別指紋特征。模塊配備了串口、USB 通訊接口,用戶無需研究復(fù)雜的圖像處理及及指紋識別算法,只需通過簡單的串口、USB 按照通訊協(xié)議便可控制模塊。本模塊可應(yīng)用于各種考勤機、保險箱柜、指紋門禁系統(tǒng)、指紋鎖等場合。
01模塊來源
模塊實物展示:

資料下載鏈接:https://pan.baidu.com/s/1mCDdiU5nwtooxmHiPfYTFA
資料提取碼:kj8o
02 規(guī)格參數(shù)
工作電壓:3.0-3.6V
工作電流:30~60mA
指紋存容量:300 枚(ID:0~299)
認假率:<0.001%
搜索時間:<0.3(S)
控制方式:串口或USB
以上信息見廠家資料文件
03移植過程
我們的目標(biāo)是將例程移植至CW32F030C8T6開發(fā)板上【實現(xiàn)添加指紋、刪除指紋和搜索指紋的功能】。首先要獲取資料,查看數(shù)據(jù)手冊應(yīng)如何實現(xiàn)讀取數(shù)據(jù),再移植至我們的工程。
3.1查看資料
系統(tǒng)內(nèi)設(shè)有一個72K字節(jié)的圖像緩沖區(qū)與二個512bytes大小的特征文件緩沖區(qū),名字分別稱為:lmageBuffer,CharBuffer1和CharBuffer2。用戶可以通過指令讀寫任意一個緩沖區(qū)。CharBufferl或 CharBuffer2既可以用于存放普通特征文件也可以用于存放模板特征文件。通過UART 口上傳或下載圖像時為了加快速度,只用到像素字節(jié)的高4位,即將兩個像素合成一個字節(jié)傳送。通過USB口則是整8位像素。
指紋庫容量根據(jù)掛接的FLASH容量不同而改變,系統(tǒng)會自動判別。指紋模板按照序號存放,序號定義為:0—(N-1)(N為指紋庫容量)。用戶只能根據(jù)序號訪問指紋庫內(nèi)容。
這里我們使用的是串口控制方式,USB的接口我們可以懸空不接。

1腳(紅線):模塊主電源,接3.3V供電(請勿接3.3V以上電源,否則燒毀模塊?。?;
2腳(黃線):模塊串口TX(發(fā)送端),接MCU或TTL串口的RX(接收端);
3腳(白線):模塊串口RX(接收端),接MCU或TTL串口的TX(發(fā)送端);
4腳(黑線):模塊電源地,接3.3V電源地(負極);
5腳(藍線):模塊觸摸感應(yīng)信號輸出(高電平為檢測到觸摸),需接VTI到3.3V。
6腳(綠線):模塊觸摸感應(yīng)電路電源(3.3V),可以與1腳(紅線)并接。
7腳,8腳為USB信號線,使用串口控制模塊時可以懸空不用。
3.2引腳選擇
想要使用uart串口,需要確定使用的引腳是否有串口外設(shè)功能,可以通過用戶手冊進行查看。在用戶手冊的第146頁。
這里選擇使用PA2和PA3的附加串口2功能。

有串口功能的引腳

接線表
3.3移植至工程
移植步驟中的導(dǎo)入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_as608.c與bsp_as608.h。這里不再過多講述,移植完成后面修改相關(guān)代碼。
將bsp_uart.c修改為下面的代碼:
/* * Change Logs: * Date Author Notes * 2024-06-12 LCKFB-LP first version */ #include "bsp_uart.h" #include "stdio.h" uint8_t u1_recv_buff[512]; // 接收緩沖區(qū) uint16_t u1_recv_length; // 接收數(shù)據(jù)長度 uint8_t u1_recv_flag; // 接收完成標(biāo)志位 /****************************************************************** * 函 數(shù) 名 稱:uart1_init * 函 數(shù) 說 明:初始化USART1的串口收發(fā)功能 * 函 數(shù) 形 參:__rate:波特率 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void uart1_init(uint32_t __rate) { //配置RCC RCC_AHBPeriphClk_Enable(DEBUG_USART_GPIO_CLK, ENABLE); // 使能GPIO時鐘 DEBUG_USART_APBClkENx(DEBUG_USART_CLK, ENABLE); // 使能串口時鐘 // 配置GPIO GPIO_InitTypeDef GPIO_InitStructure; //UART TX RX 復(fù)用 DEBUG_USART_AFTX; DEBUG_USART_AFRX; GPIO_InitStructure.Pins = DEBUG_USART_TX_GPIO_PIN; // 引腳 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽輸出 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; // 輸出速度高 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // 初始化GPIO GPIO_InitStructure.Pins = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉輸入 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); // 配置UART USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = __rate; // 波特率 USART_InitStructure.USART_Over = USART_Over_16; // 配置USART的過采樣率。 USART_InitStructure.USART_Source = USART_Source_PCLK; // 設(shè)置時鐘源 USART_InitStructure.USART_UclkFreq = DEBUG_USART_UclkFreq; //設(shè)置USART時鐘頻率(和主頻一致即可) USART_InitStructure.USART_StartBit = USART_StartBit_FE; //RXD下降沿開始 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位1 USART_InitStructure.USART_Parity = USART_Parity_No ; // 不使用校驗 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用流控 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收發(fā)模式 USART_Init(DEBUG_USARTx, &USART_InitStructure); //優(yōu)先級,無優(yōu)先級分組 NVIC_SetPriority(DEBUG_USART_IRQ, 0); //UARTx中斷使能 NVIC_EnableIRQ(DEBUG_USART_IRQ); //使能UARTx RC中斷 USART_ITConfig(DEBUG_USARTx, USART_IT_RC, ENABLE); } #if !defined(__MICROLIB) //不使用微庫的話就需要添加下面的函數(shù) #if (__ARMCLIB_VERSION <= 6000000) //如果編譯器是AC5 就定義下面這個結(jié)構(gòu)體 struct __FILE { int handle; }; #endif FILE __stdout; //定義_sys_exit()以避免使用半主機模式 void _sys_exit(int x) { x = x; } #endif /* retarget the C library printf function to the USART */ int fputc(int ch, FILE *f) { // 發(fā)送一個字節(jié) USART_SendData(DEBUG_USARTx, (uint8_t)ch); // 等待發(fā)送完成 while( RESET == USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) ){} return ch; } void uart1_receive_clear(void) { for(int i = 0; i < 512; i++) { u1_recv_buff[i] = 0; } u1_recv_length = 0; u1_recv_flag = 0; } /****************************************************************** * 函 數(shù) 名 稱:UART1_IRQHandler * 函 數(shù) 說 明:串口1中斷服務(wù)函數(shù) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void UART1_IRQHandler(void) { uint8_t TxRxBuffer; if (USART_GetITStatus(CW_UART1, USART_IT_RC) != RESET) { // 接收一個字節(jié) TxRxBuffer = USART_ReceiveData_8bit(CW_UART1); u1_recv_buff[u1_recv_length++] = TxRxBuffer; u1_recv_flag = 1; // USART_SendData_8bit(CW_UART1, TxRxBuffer); // 將數(shù)據(jù)發(fā)回用于驗證 // 清除標(biāo)志位 USART_ClearITPendingBit(CW_UART1, USART_IT_RC); } }
將bsp_uart.h修改為下面的代碼:
/* * Change Logs: * Date Author Notes * 2024-06-12 LCKFB-LP first version */ #include "board.h" //UARTx #define DEBUG_USARTx CW_UART1 #define DEBUG_USART_CLK RCC_APB2_PERIPH_UART1 #define DEBUG_USART_APBClkENx RCC_APBPeriphClk_Enable2 #define DEBUG_USART_UclkFreq 64000000 //UARTx GPIO #define DEBUG_USART_GPIO_CLK RCC_AHB_PERIPH_GPIOA #define DEBUG_USART_TX_GPIO_PORT CW_GPIOA #define DEBUG_USART_TX_GPIO_PIN GPIO_PIN_8 #define DEBUG_USART_RX_GPIO_PORT CW_GPIOA #define DEBUG_USART_RX_GPIO_PIN GPIO_PIN_9 //GPIO AF #define DEBUG_USART_AFTX PA08_AFx_UART1TXD() #define DEBUG_USART_AFRX PA09_AFx_UART1RXD() //中斷 #define DEBUG_USART_IRQ UART1_IRQn extern uint8_t u1_recv_buff[512]; // 接收緩沖區(qū) extern uint16_t u1_recv_length; // 接收數(shù)據(jù)長度 extern uint8_t u1_recv_flag; // 接收完成標(biāo)志位 void uart1_receive_clear(void); void uart1_init(uint32_t __rate);
在文件bsp_as608.c中,編寫如下代碼。
/*
* Change Logs:
* Date Author Notes
* 2024-06-19 LCKFB-LP first version
*/
#include "bsp_as608.h"
#include "stdio.h"
#include "string.h"
#include "bsp_uart.h"
volatile unsigned char FPM10A_RECEICE_BUFFER[32];
unsigned int finger_id = 0;
const unsigned char FPM10A_Get_Device[10] ={0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x00,0x1b};//口令驗證
const unsigned char FPM10A_Pack_Head[6] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF}; //協(xié)議包頭
const unsigned char FPM10A_Get_Img[6] = {0x01,0x00,0x03,0x01,0x00,0x05}; //獲得指紋圖像
const unsigned char FPM10A_Get_Templete_Count[6] ={0x01,0x00,0x03,0x1D,0x00,0x21 }; //獲得模版總數(shù)
const unsigned char FPM10A_Search[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x03,0xE7,0x00,0xF8}; //搜索指紋搜索范圍0 - 999,使用BUFFER1中的特征碼搜索
const unsigned char FPM10A_Search_0_9[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x00,0x13,0x00,0x21}; //搜索0-9號指紋
const unsigned char FPM10A_Img_To_Buffer1[7]={0x01,0x00,0x04,0x02,0x01,0x00,0x08}; //將圖像放入到BUFFER1
const unsigned char FPM10A_Img_To_Buffer2[7]={0x01,0x00,0x04,0x02,0x02,0x00,0x09}; //將圖像放入到BUFFER2
const unsigned char FPM10A_Reg_Model[6]={0x01,0x00,0x03,0x05,0x00,0x09}; //將BUFFER1跟BUFFER2合成特征模版
const unsigned char FPM10A_Delete_All_Model[6]={0x01,0x00,0x03,0x0d,0x00,0x11};//刪除指紋模塊里所有的模版
volatile unsigned char FPM10A_Save_Finger[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0B,0x00,0x19};//將BUFFER1中的特征碼存放到指定的位置
uint8_t u2_recv_buff[USART2_RECEIVE_LENGTH]; // 接收緩沖區(qū)
uint16_t u2_recv_length; // 接收數(shù)據(jù)長度
uint8_t u2_recv_flag; // 接收完成標(biāo)志位
/******************************************************************
* 函 數(shù) 名 稱:as608_gpio_config
* 函 數(shù) 說 明:初始化as608引腳
* 函 數(shù) 形 參:設(shè)置波特率 as608的默認波特率是57600
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:as608的默認波特率是57600
******************************************************************/
void as608_gpio_config(uint32_t band_rate)
{
GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結(jié)構(gòu)體
AS608_GPIO_RCC_ENABLE(); // 使能GPIO時鐘
AS608_UART_RCC_ENABLE(); // 使能UART時鐘
GPIO_InitStruct.Pins = AS608_TX_PIN; // GPIO引腳
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽輸出
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 輸出速度高
GPIO_Init(AS608_GPIO_PORT, &GPIO_InitStruct); // 初始化
GPIO_InitStruct.Pins = AS608_RX_PIN; // GPIO引腳
GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉輸入
GPIO_Init(AS608_GPIO_PORT, &GPIO_InitStruct); // 初始化
GPIO_InitStruct.Pins = AS608_TOUCH_PIN; // GPIO引腳
GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLDOWN;// 下拉輸入
GPIO_Init(AS608_GPIO_PORT, &GPIO_InitStruct); // 初始化
AS608_AF_UART_TX(); // UART_TX復(fù)用
AS608_AF_UART_RX(); // UART_RX復(fù)用
// 配置UART
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = band_rate; // 波特率
USART_InitStructure.USART_Over = USART_Over_16; // 配置USART的過采樣率。
USART_InitStructure.USART_Source = USART_Source_PCLK; // 設(shè)置時鐘源
USART_InitStructure.USART_UclkFreq = 64000000; //設(shè)置USART時鐘頻率(和主頻一致即可)
USART_InitStructure.USART_StartBit = USART_StartBit_FE; //RXD下降沿開始
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位1
USART_InitStructure.USART_Parity = USART_Parity_No ; // 不使用校驗
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收發(fā)模式
USART_Init(AS608_UART, &USART_InitStructure); // 初始化串口1
// 優(yōu)先級,無優(yōu)先級分組
NVIC_SetPriority(AS608_UART_IRQ, 0);
// UARTx中斷使能
NVIC_EnableIRQ(AS608_UART_IRQ);
// 使能UARTx RC中斷
USART_ITConfig(AS608_UART, USART_IT_RC, ENABLE);
}
/************************************************
函數(shù)名稱 : uart2_send_byte
功 能 : 串口發(fā)送一個字節(jié)
參 數(shù) : ucch:要發(fā)送的字節(jié)
返 回 值 :
作 者 : LC
*************************************************/
void uart2_send_byte(uint8_t ucch)
{
// 發(fā)送一個字節(jié)
USART_SendData_8bit(AS608_UART, (uint8_t)ucch);
// 等待發(fā)送完成
while( RESET == USART_GetFlagStatus(AS608_UART, USART_FLAG_TXE) ){}
}
/************************************************
函數(shù)名稱 : uart2_receive_clear
功 能 : 清除串口接收的全部數(shù)據(jù)
參 數(shù) : 無
返 回 值 : 無
作 者 : LC
*************************************************/
void uart2_receive_clear(void)
{
unsigned int i = 0;
for( i = 0; i < USART2_RECEIVE_LENGTH; i++ )
{
u2_recv_buff[ i ] = 0;
}
u2_recv_length = 0;
u2_recv_flag = 0;
}
/******************************************************************
* 函 數(shù) 名 稱:get_as608_touch
* 函 數(shù) 說 明:獲取是否有手指觸摸識別區(qū)
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:0沒有觸摸 1有觸摸
* 作 者:LC
* 備 注:無
******************************************************************/
char get_as608_touch(void)
{
if( TOUCH_IN == 1 )//觸摸為1
{
//printf("Touch-1rn");
return 1;
}
else
{
//printf("Touch-0rn");
}
return 0;
}
/******************************************************************
* 函 數(shù) 名 稱:FPM10A_Cmd_Send_Pack_Head
* 函 數(shù) 說 明:發(fā)送包頭
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:wu
* 作 者:LC
* 備 注:無
******************************************************************/
void FPM10A_Cmd_Send_Pack_Head(void)
{
int i;
for(i=0;i6;i++) //包頭
{
uart2_send_byte(FPM10A_Pack_Head[i]);
}
}
/******************************************************************
* 函 數(shù) 名 稱:FPM10A_Cmd_Check
* 函 數(shù) 說 明:發(fā)送指令
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:無
******************************************************************/
void FPM10A_Cmd_Check(void)
{
int i=0;
FPM10A_Cmd_Send_Pack_Head(); //發(fā)送通信協(xié)議包頭
for(i=0;i10;i++)
{
uart2_send_byte(FPM10A_Get_Device[i]);
}
}
/******************************************************************
* 函 數(shù) 名 稱:FPM10A_Receive_Data
* 函 數(shù) 說 明:接收反饋數(shù)據(jù)緩沖
* 函 數(shù) 形 參:ucLength 接收長度
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:無
******************************************************************/
void FPM10A_Receive_Data(unsigned char ucLength)
{
unsigned char i = 0;
unsigned int timeout = 1000;//超時時間,單位Ms
//等待數(shù)據(jù)接收完畢
while(u2_recv_flag==0 && timeout > 0 )
{
delay_ms(1);
timeout--;
}
delay_ms(100); // 一定要加延時!??!
if( u2_recv_flag == 1 )
{
u2_recv_flag = 0;
for (i=0;i>8;
FPM10A_Save_Finger[6] = (storeID&0x00FF);
for(i=0;i7;i++) //計算校驗和
{
temp = temp + FPM10A_Save_Finger[i];
}
FPM10A_Save_Finger[7]=(temp & 0x00FF00) >> 8; //存放校驗數(shù)據(jù)
FPM10A_Save_Finger[8]= temp & 0x0000FF;
FPM10A_Cmd_Send_Pack_Head(); //發(fā)送通信協(xié)議包頭
for(i=0;i9;i++)
{
//發(fā)送命令 將圖像轉(zhuǎn)換成 特征碼 存放在 CHAR_buffer1
uart2_send_byte(FPM10A_Save_Finger[i]);
}
}
/******************************************************************
* 函 數(shù) 名 稱:key_scanf
* 函 數(shù) 說 明:按鍵功能 確定-取消
* 函 數(shù) 形 參:
* 函 數(shù) 返 回:0=未動作 1=確定 2=取消
* 作 者:LC
* 備 注:當(dāng)前是使用串口來模擬按鍵,如果你有按鍵請自行修改
* 修改要求:按下確定鍵時返回1;按下取消鍵時,返回2。
******************************************************************/
char key_scanf(void)
{
/*************** 你的代碼 ***************/
if(strstr( (const char*)u1_recv_buff, "Yes") != NULL )
{
uart1_receive_clear();
printf("key_scanf-YESrn");
return 1;//返回 確定鍵被按下
}
if(strstr( (const char*)u1_recv_buff, "No") != NULL )
{
uart1_receive_clear();
printf("key_scanf-NOrn");
return 2;//返回 取消鍵被按下
}
/*************** 你的代碼 ***************/
return 0;
}
/******************************************************************
* 函 數(shù) 名 稱:FPM10A_Add_Fingerprint
* 函 數(shù) 說 明:添加指紋
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:無
******************************************************************/
void FPM10A_Add_Fingerprint(void)
{
// unsigned char id_show[3]={0,0,0};
unsigned char key_num= key_scanf();
finger_id=0;
printf("Do you want to add fingerprints? [Yes/No]rn");
while( key_num != 2 )//按返回鍵直接回到主菜單
{
key_num= key_scanf();
//按確認鍵開始錄入指紋信息
if( key_num == 1 )
{
printf("start addrn");
while( key_num != 2 )//按下返回鍵退出錄入返回fingerID調(diào)整狀態(tài)
{
key_num= key_scanf();
FPM10A_Cmd_Get_Img(); //獲得指紋圖像
FPM10A_Receive_Data(12);
//判斷接收到的確認碼,等于0指紋獲取成功
if(FPM10A_RECEICE_BUFFER[9]==0)
{
delay_ms(100);
FINGERPRINT_Cmd_Img_To_Buffer1();
FPM10A_Receive_Data(12);
delay_ms(1000);
while( key_num != 2 )
{
key_num= key_scanf();
FPM10A_Cmd_Get_Img(); //獲得指紋圖像
FPM10A_Receive_Data(12);
//判斷接收到的確認碼,等于0指紋獲取成功
if(FPM10A_RECEICE_BUFFER[9]==0)
{
delay_ms(200);
printf("successfully added, ID = %drn",finger_id);
FINGERPRINT_Cmd_Img_To_Buffer2();
FPM10A_Receive_Data(12);
FPM10A_Cmd_Reg_Model();//轉(zhuǎn)換成特征碼
FPM10A_Receive_Data(12);
//保存指紋
FPM10A_Cmd_Save_Finger(finger_id);
FPM10A_Receive_Data(12);
delay_ms(1000);
finger_id=finger_id+1;
break;
}
}
break;
}
}
}
}
}
/******************************************************************
* 函 數(shù) 名 稱:FPM10A_Find_Fingerprint
* 函 數(shù) 說 明:搜索指紋
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:指紋ID號
* 作 者:LC
* 備 注:255:未查到 其他:查找到了
******************************************************************/
unsigned int FPM10A_Find_Fingerprint(void)
{
unsigned int find_fingerid = 255;
// printf("Please put your finger inrn");
if( get_as608_touch() == 1 )//有手指觸摸識別區(qū)
{
FPM10A_Cmd_Get_Img(); //獲得指紋圖像
FPM10A_Receive_Data(12);
//判斷接收到的確認碼,等于0指紋獲取成功
if(FPM10A_RECEICE_BUFFER[9]==0)
{
delay_ms(100);
FINGERPRINT_Cmd_Img_To_Buffer1();
FPM10A_Receive_Data(12);
FPM10A_Cmd_Search_Finger();
FPM10A_Receive_Data(16);
if(FPM10A_RECEICE_BUFFER[9] == 0) //搜索成功
{
//拼接指紋ID數(shù)
find_fingerid = FPM10A_RECEICE_BUFFER[10]*256 + FPM10A_RECEICE_BUFFER[11];
printf("ID = %drn",find_fingerid);
delay_ms(500);
}
else //沒有找到
{
printf("not foundrn");
}
}
}
return find_fingerid;
}
/******************************************************************
* 函 數(shù) 名 稱:FPM10A_Delete_All_Fingerprint
* 函 數(shù) 說 明:刪除所有存貯的指紋庫
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:無
******************************************************************/
void FPM10A_Delete_All_Fingerprint(void)
{
unsigned char key_num=0;
printf("Whether to delete fingerprint ? [Yes/No]rn");
do
{
key_num = key_scanf();
if(key_num == 1 )//點擊確定鍵
{
printf("deletingrn");
delay_ms(300);
FINGERPRINT_Cmd_Delete_All_Model();
FPM10A_Receive_Data(12);
printf("Have all been clearedrn");
break;
}
if( u2_recv_flag == 1 )
{
u2_recv_flag = 0;
printf("rev = %srn", u2_recv_buff);
}
}while( key_num != 2 );//沒有點擊取消鍵,則繼續(xù)循環(huán)
}
/******************************************************************
* 函 數(shù) 名 稱:Device_Check
* 函 數(shù) 說 明:模塊檢查
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:0未檢測到模塊或者模塊異常 1檢測到模塊并且通信成功
* 作 者:LC
* 備 注:返回0時要注意接線是否正確、串口配置是否可用
******************************************************************/
char Device_Check(void)
{
FPM10A_RECEICE_BUFFER[9]=1; //串口數(shù)組第九位可判斷是否通信正常
FPM10A_Cmd_Check(); //單片機向指紋模塊發(fā)送校對命令
FPM10A_Receive_Data(12); //將串口接收到的數(shù)據(jù)轉(zhuǎn)存
if(FPM10A_RECEICE_BUFFER[9] == 0) //判斷數(shù)據(jù)低第9位是否接收到0
{
return 1;
}
return 0;
}
/******************************************************************
* 函 數(shù) 名 稱:AS608_UART_IRQHandler
* 函 數(shù) 說 明:串口2中斷服務(wù)函數(shù)
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:無
******************************************************************/
void AS608_UART_IRQHandler(void)
{
if(USART_GetITStatus(AS608_UART, USART_IT_RC) == SET)//判斷是不是真的有中斷發(fā)生
{
u2_recv_buff[u2_recv_length++] = USART_ReceiveData(AS608_UART);// 把接收到的數(shù)據(jù)放到緩沖區(qū)中
u2_recv_buff[u2_recv_length] = ''; // 數(shù)據(jù)接收完畢,數(shù)組結(jié)束標(biāo)志
u2_recv_flag = 1;
USART_ClearITPendingBit(AS608_UART, USART_IT_RC); //已經(jīng)處理就清楚標(biāo)志位
}
}
在文件bsp_as608.h中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-19 LCKFB-LP first version */ #ifndef _BSP_AS608_H_ #define _BSP_AS608_H_ #include "board.h" #define AS608_GPIO_RCC_ENABLE() __RCC_GPIOA_CLK_ENABLE() // GPIO時鐘 #define AS608_UART_RCC_ENABLE() __RCC_UART2_CLK_ENABLE() // 串口2的時鐘 #define AS608_AF_UART_TX() PA02_AFx_UART2TXD() #define AS608_AF_UART_RX() PA03_AFx_UART2RXD() #define AS608_GPIO_PORT CW_GPIOA // GPIO端口 #define AS608_TX_PIN GPIO_PIN_2 // 串口TX的引腳 #define AS608_RX_PIN GPIO_PIN_3 // 串口RX的引腳 #define AS608_TOUCH_PIN GPIO_PIN_1 // TOUCH的引腳 #define AS608_UART CW_UART2 // 串口2 #define AS608_UART_IRQ UART2_IRQn // 串口2中斷 #define AS608_UART_IRQHandler UART2_IRQHandler // 串口2中斷服務(wù)函數(shù) #define TOUCH_IN GPIO_ReadPin( AS608_GPIO_PORT, AS608_TOUCH_PIN ) /* 串口緩沖區(qū)的數(shù)據(jù)長度 */ #define USART2_RECEIVE_LENGTH 1024 extern uint8_t u2_recv_buff[USART2_RECEIVE_LENGTH]; // 接收緩沖區(qū) extern uint16_t u2_recv_length; // 接收數(shù)據(jù)長度 extern uint8_t u2_recv_flag; // 接收完成標(biāo)志位 void as608_gpio_config(uint32_t band_rate); char get_as608_touch(void); void uart2_receive_clear(void); char Device_Check(void); void FPM10A_Add_Fingerprint(void);//添加指紋 unsigned int FPM10A_Find_Fingerprint(void);//查找指紋 void FPM10A_Delete_All_Fingerprint(void); #endif
04移植驗證
在自己工程中的main主函數(shù)中,編寫如下。
/*
* Change Logs:
* Date Author Notes
* 2024-06-19 LCKFB-LP first version
*/
#include "board.h"
#include "stdio.h"
#include "bsp_uart.h"
#include "bsp_as608.h"
int32_t main(void)
{
board_init(); // 開發(fā)板初始化
uart1_init(57600U); // 串口1波特率115200
as608_gpio_config(57600U);
printf("AS608 demo startrn");
Device_Check();//模塊檢測
FPM10A_Delete_All_Fingerprint(); //是否刪除全部指紋
FPM10A_Add_Fingerprint();//是否添加指紋
while(1)
{
FPM10A_Find_Fingerprint();//查找指紋
}
}
上電現(xiàn)象:

模塊移植成功案例代碼:
鏈接:https://pan.baidu.com/s/13OYXBko_GfKrS4aRVg1VLg?pwd=LCKF
提取碼:LCKF
審核編輯 黃宇
-
傳感器
+關(guān)注
關(guān)注
2576文章
55014瀏覽量
791181 -
指紋識別傳感器
+關(guān)注
關(guān)注
0文章
20瀏覽量
14946 -
CW32
+關(guān)注
關(guān)注
1文章
299瀏覽量
1843
發(fā)布評論請先 登錄
CW32溫度傳感器的應(yīng)用
CW32單片機如何讓生活更便捷
CW32單片機在智能馬桶的應(yīng)用
CW32 MCU溫度監(jiān)測應(yīng)用
基于芯源CW32 MCU智能家居照明控制系統(tǒng)設(shè)計與實現(xiàn)
CW32 MCU用什么IDE開發(fā)?
CW32 MCU用什么仿真器開發(fā)?
怎么通過UART1對指紋識別模塊的控制
秒級喚醒指紋識別模塊方案
新品 | Unit Fingerprint2,高性能指紋識別傳感器單元
CW32電機控制基礎(chǔ)--無刷電機無位置傳感器的轉(zhuǎn)子位置檢測技術(shù)
CW32模塊使用 指紋識別傳感器
評論