基于STM32單片機(jī)開發(fā)光學(xué)指紋識(shí)別模塊(FPM10A)全教程
首先我使用的是 奮斗 STM32 開發(fā)板 MINI板
本文引用地址:http://m.butianyuan.cn/article/201611/318656.htm光學(xué)指紋識(shí)別模塊(FPM10A)淘寶網(wǎng)址是:http://item.taobao.com/item.htm?id=5380075198
2.購(gòu)買指紋模塊,可以獲得三份資料
這樣只要把這個(gè)轉(zhuǎn)接板插入STM32,接上5V的電,就可以工作了,將模塊的發(fā)送端接轉(zhuǎn)接板的接收端,接收端接轉(zhuǎn)接板的發(fā)送端。
這樣,我們的硬件平臺(tái)就搭建好了!
4.模塊的測(cè)試工作
模塊成功上電后,指紋采集窗口會(huì)閃一下,表示自檢正常,如果不閃,請(qǐng)仔細(xì)檢查電源,是否接反,接錯(cuò)等。指紋模塊使用120MHZ的DSP全速工作,工作時(shí)芯片有一些熱,經(jīng)過嚴(yán)格的測(cè)試,這是沒有問題的可以放心使用,在不使用的時(shí)候可以關(guān)閉電源,以降低功耗。
5.現(xiàn)在我們要進(jìn)入編程環(huán)節(jié)了
指紋模塊主要是通過串口進(jìn)行控制,所以這里我們需要用到單片機(jī)的串口模塊。
我們需要用到兩個(gè)關(guān)鍵函數(shù)
1.使用串口發(fā)送一個(gè)字節(jié)的數(shù)據(jù)
2.使用串口接收一個(gè)字節(jié)的數(shù)據(jù)
這里我使用的STM32單片,所以這兩個(gè)程序如下:
- // 從 USART1 發(fā)送一個(gè)字節(jié)
- void USART1_SendByte(unsigned char temp)
- {
- USART_SendData(USART1, temp);
- while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
- }
- // 從 USART1 讀取一個(gè)字節(jié)
- unsigned char USART1_ReceivByte()
- {
- unsigned char recev;
- while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
- recev = USART_ReceiveData(USART1);
- return recev;
- }
6.查看FPM10A用戶手冊(cè) 我們來實(shí)現(xiàn)比對(duì)一個(gè)指紋(我們這里假設(shè)指紋模塊中已經(jīng)存在指紋模板)
首先我們需要讓指紋模塊檢測(cè)是否有指紋輸入(也就是是否有手指放在指紋模塊上檢測(cè))
我們來看手冊(cè)上給的操作說明:
我們需要發(fā)送給定的數(shù)據(jù)包給模塊,發(fā)送的數(shù)據(jù)已經(jīng)給我們了,現(xiàn)在我們參看給我們的C例程
- //應(yīng)答包數(shù)組
- unsigned char dat[18];
- //獲得指紋圖像
- unsigned char FP_Get_Img[6] ={0x01,0x00,0x03,0x01,0x0,0x05};
- //協(xié)議包頭
- unsigned char FP_Pack_Head[6] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF};
- //FINGERPRINT_獲得指紋圖像命令
- void FINGERPRINT_Cmd_Get_Img(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //發(fā)送包頭
- USART1_SendByte(FP_Pack_Head[i]);
- for(i=0;i<6;i++) //發(fā)送命令 0x1d
- USART1_SendByte(FP_Get_Img[i]);
- for(i=0;i<12;i++)//讀回應(yīng)答信息
- dat[i]=USART1_ReceivByte();
- }
說明:這個(gè)函數(shù)就是檢測(cè)是否有指紋輸入的信息,根據(jù)用戶手冊(cè),當(dāng)確認(rèn)碼返回值為0時(shí),表示成功錄入,所以,我們可以有下面的函數(shù):
- //檢測(cè)指紋模塊錄入指紋情況,返回00表示錄入成功;02無手指;03錄入失敗
- unsigned char test_fig()
- {
- unsigned char fig_dat;
- FINGERPRINT_Cmd_Get_Img();
- Delay_ms1(20);
- fig_dat=dat[9];
- return(fig_dat);
- }
- 因此,我們?cè)谥骱瘮?shù)中可以這樣調(diào)用:
- void main
- {
- if(test_fig()==0)
- {
- //do something
- }
- }
7.如何錄入一個(gè)新的指紋信息呢?
步驟如下
1.獲得指紋圖像
2.檢測(cè)是否成功的按了指紋
3.將圖像轉(zhuǎn)換成特征碼存放在Buffer1中
4.再次獲得指紋圖像
5.將圖像轉(zhuǎn)換成特征碼存放在Buffer2中
6.轉(zhuǎn)換成特征碼
7.存儲(chǔ)到指定地址上
同樣的,根據(jù)用戶手冊(cè),我們可以得到以下這樣的模塊:
當(dāng)調(diào)用的時(shí)候,你只要給這個(gè)函數(shù)附上兩個(gè)值就可以了,例如:
unsigned char FP_add_new_user(00,01);
如果你下次再次寫入這個(gè)地址,以前存儲(chǔ)的指紋模板信息將被覆蓋
- //添加一個(gè)新的指紋
- unsigned char FP_add_new_user(unsigned char ucH_user,unsigned char ucL_user)
- {
- do
- {
- FINGERPRINT_Cmd_Get_Img(); //獲得指紋圖像
- } while ( dat[9]!=0x0 ); //檢測(cè)是否成功的按了指紋
- FINGERPRINT_Cmd_Img_To_Buffer1(); //將圖像轉(zhuǎn)換成特征碼存放在Buffer1中
- do
- {
- FINGERPRINT_Cmd_Get_Img(); //獲得指紋圖像
- } while( dat[9]!=0x0 );
- FINGERPRINT_Cmd_Img_To_Buffer2(); //將圖像轉(zhuǎn)換成特征碼存放在Buffer2中
- FINGERPRINT_Cmd_Reg_Model(); //轉(zhuǎn)換成特征碼
- FINGERPRINT_Cmd_Save_Finger(ucH_user,ucL_user);
- return 0;
- }
- //存儲(chǔ)模版到特定地址
- void FINGERPRINT_Cmd_Save_Finger( unsigned char ucH_Char, unsigned char ucL_Char)
- {
- unsigned long temp = 0;
- unsigned char i;
- FP_Save_Finger[5] = ucH_Char;
- FP_Save_Finger[6] = ucL_Char;
- for(i=0;i<7;i++) //計(jì)算校驗(yàn)和
- temp = temp + FP_Save_Finger[i];
- FP_Save_Finger[7]=(temp & 0x00FF00) >> 8; //存放校驗(yàn)數(shù)據(jù)
- FP_Save_Finger[8]= temp & 0x0000FF;
- for(i=0;i<6;i++)
- USART1_SendByte(FP_Pack_Head[i]); //發(fā)送包頭
- for(i=0;i<9;i++)
- USART1_SendByte(FP_Save_Finger[i]) ;//發(fā)送命令將圖像轉(zhuǎn)換成特征碼存放CHAR_buffer1
- for(i=0;i<12;i++)
- dat[i]=USART1_ReceivByte();
- }
8.如何刪除一個(gè)模板?
- //刪除所有指紋模版
- void FINGERPRINT_Cmd_Delete_All_Model(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //發(fā)送包頭
- USART1_SendByte(FP_Pack_Head[i]);
- for(i=0;i<6;i++) //發(fā)送命令 0x1d
- USART1_SendByte(FP_Delet_All_Model[i]);
- for(i=0;i<12;i++)//讀回應(yīng)答信息
- dat[i]=USART1_ReceivByte();
- }
9.如何獲取已經(jīng)存取的指紋模板信息?
這個(gè)模塊一共可以存儲(chǔ)0~999枚指紋信息
- //搜索全部用戶999枚
- void FINGERPRINT_Cmd_Search_Finger(void)
- {
- unsigned char i;
- //發(fā)送命令搜索指紋庫(kù)
- for(i=0;i<6;i++)
- {
- USART1_SendByte(FP_Pack_Head[i]);
- }
- for(i=0;i<11;i++)
- {
- USART1_SendByte(FP_Search[i]);
- }
- for(i=0;i<16;i++)
- {
- dat[i]=USART1_ReceivByte();
- }
- }
根據(jù)用戶手冊(cè),我們可以從應(yīng)答包中得出模塊中已經(jīng)存在指紋數(shù)量的大小
這樣,我們就輕松把指紋模塊搞定!
下面我附上基于STM32單片機(jī)光學(xué)指紋識(shí)別模塊(FPM10A)打包好的函數(shù)庫(kù)
第一個(gè)是 FPM10A.c
- #include "stm32f10x.h"
- #include "stm32f10x_usart.h"
- #include "misc.h"
- unsigned char dat[18];
- //FINGERPRINT通信協(xié)議定義
- unsigned char FP_Pack_Head[6] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF}; //協(xié)議包頭
- unsigned char FP_Get_Img[6] = {0x01,0x00,0x03,0x01,0x0,0x05}; //獲得指紋圖像
- unsigned char FP_Templete_Num[6] ={0x01,0x00,0x03,0x1D,0x00,0x21 }; //獲得模版總數(shù)
- unsigned char FP_Search[11]={0x01,0x0,0x08,0x04,0x01,0x0,0x0,0x03,0xA1,0x0,0xB2}; //搜索指紋搜索范圍0 - 929
- unsigned char FP_Search_0_9[11]={0x01,0x0,0x08,0x04,0x01,0x0,0x0,0x0,0x13,0x0,0x21};//搜索0-9號(hào)指紋
- unsigned char FP_Img_To_Buffer1[7]={0x01,0x0,0x04,0x02,0x01,0x0,0x08}; //將圖像放入到BUFFER1
- unsigned char FP_Img_To_Buffer2[7]={0x01,0x0,0x04,0x02,0x02,0x0,0x09}; //將圖像放入到BUFFER2
- unsigned char FP_Reg_Model[6]={0x01,0x0,0x03,0x05,0x0,0x09}; //將BUFFER1跟BUFFER2合成特征模版
- unsigned char FP_Delet_All_Model[6]={0x01,0x0,0x03,0x0d,0x00,0x11}; //刪除指紋模塊里所有的模版
- unsigned char FP_Save_Finger[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0B,0x00,0x19}; //將BUFFER1中的特征碼存放到指定的位置
- unsigned char FP_Delete_Model[10]={0x01,0x00,0x07,0x0C,0x0,0x0,0x0,0x1,0x0,0x0}; //刪除指定的模版
- //從 USART1 發(fā)送一個(gè)字節(jié)
- void USART1_SendByte(unsigned char temp)
- {
- USART_SendData(USART1, temp);
- while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
- }
- //從 USART1 讀取一個(gè)字節(jié)
- unsigned char USART1_ReceivByte()
- {
- unsigned char recev;
- while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
- recev = USART_ReceiveData(USART1);
- return recev;
- }
- //FINGERPRINT命令字
- //FINGERPRINT_獲得指紋圖像命令
- void FINGERPRINT_Cmd_Get_Img(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //發(fā)送包頭
- USART1_SendByte(FP_Pack_Head[i]);
- for(i=0;i<6;i++) //發(fā)送命令 0x1d
- USART1_SendByte(FP_Get_Img[i]);
- for(i=0;i<12;i++)//讀回應(yīng)答信息
- dat[i]=USART1_ReceivByte();
- }
- //刪除所有指紋模版
- void FINGERPRINT_Cmd_Delete_All_Model(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //發(fā)送包頭
- USART1_SendByte(FP_Pack_Head[i]);
- for(i=0;i<6;i++) //發(fā)送命令 0x1d
- USART1_SendByte(FP_Delet_All_Model[i]);
- for(i=0;i<12;i++)//讀回應(yīng)答信息
- dat[i]=USART1_ReceivByte();
- }
- //講圖像轉(zhuǎn)換成特征碼存放在Buffer1中
- void FINGERPRINT_Cmd_Img_To_Buffer1(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //發(fā)送包頭
- {
- USART1_SendByte(FP_Pack_Head[i]);
- }
- for(i=0;i<7;i++) //發(fā)送命令 將圖像轉(zhuǎn)換成 特征碼 存放在 CHAR_buffer1
- {
- USART1_SendByte(FP_Img_To_Buffer1[i]);
- }
- for(i=0;i<12;i++)//讀應(yīng)答信息
- {
- dat[i]=USART1_ReceivByte();//把應(yīng)答數(shù)據(jù)存放到緩沖區(qū)
- }
- }
- //將圖像轉(zhuǎn)換成特征碼存放在Buffer2中
- void FINGERPRINT_Cmd_Img_To_Buffer2(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //發(fā)送包頭
- {
- USART1_SendByte(FP_Pack_Head[i]);
- }
- for(i=0;i<7;i++) //發(fā)送命令 將圖像轉(zhuǎn)換成 特征碼 存放在 CHAR_buffer1
- {
- USART1_SendByte(FP_Img_To_Buffer2[i]);
- }
- for(i=0;i<12;i++)
- {
- dat[i]=USART1_ReceivByte();//讀回應(yīng)答信息
- }
- }
- //將BUFFER1 跟 BUFFER2 中的特征碼合并成指紋模版
- void FINGERPRINT_Cmd_Reg_Model(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //包頭
- {
- USART1_SendByte(FP_Pack_Head[i]);
- }
- for(i=0;i<6;i++) //命令合并指紋模版
- {
- USART1_SendByte(FP_Reg_Model[i]);
- }
- for(i=0;i<12;i++)
- {
- dat[i]=USART1_ReceivByte();
- }
- }
- //存儲(chǔ)模版到特定地址
- void FINGERPRINT_Cmd_Save_Finger( unsigned char ucH_Char, unsigned char ucL_Char)
- {
- unsigned long temp = 0;
- unsigned char i;
- FP_Save_Finger[5] = ucH_Char;
- FP_Save_Finger[6] = ucL_Char;
- for(i=0;i<7;i++) //計(jì)算校驗(yàn)和
- temp = temp + FP_Save_Finger[i];
- FP_Save_Finger[7]=(temp & 0x00FF00) >> 8; //存放校驗(yàn)數(shù)據(jù)
- FP_Save_Finger[8]= temp & 0x0000FF;
- for(i=0;i<6;i++)
- USART1_SendByte(FP_Pack_Head[i]); //發(fā)送包頭
- for(i=0;i<9;i++)
- USART1_SendByte(FP_Save_Finger[i]); //發(fā)送命令 將圖像轉(zhuǎn)換成 特征碼 存放在 CHAR_buffer1
- for(i=0;i<12;i++)
- dat[i]=USART1_ReceivByte();
- }
- //獲得指紋模板數(shù)量
- void FINGERPRINT_Cmd_Get_Templete_Num(void)
- {
- unsigned int i;
- for(i=0;i<6;i++) //包頭
- USART1_SendByte(FP_Pack_Head[i]);
- //發(fā)送命令 0x1d
- for(i=0;i<6;i++)
- USART1_SendByte(FP_Templete_Num[i]);
- for(i=0;i<12;i++)
- dat[i]=USART1_ReceivByte();
- }
- //搜索全部用戶999枚
- void FINGERPRINT_Cmd_Search_Finger(void)
- {
- unsigned char i;
- //發(fā)送命令搜索指紋庫(kù)
- for(i=0;i<6;i++)
- {
- USART1_SendByte(FP_Pack_Head[i]);
- }
- for(i=0;i<11;i++)
- {
- USART1_SendByte(FP_Search[i]);
- }
- for(i=0;i<16;i++)
- {
- dat[i]=USART1_ReceivByte();
- }
- }
- //搜索用戶0~9枚
- void FINGERPRINT_Cmd_Search_Finger_Admin(void)
- {
- unsigned char i;
- for(i=0;i<6;i++) //發(fā)送命令搜索指紋庫(kù)
- {
- USART1_SendByte(FP_Pack_Head[i]);
- }
- for(i=0;i<11;i++)
- {
- USART1_SendByte(FP_Search_0_9[i]);
- }
- for(i=0;i<12;i++)
- dat[i]=USART1_ReceivByte();
- }
- //添加一個(gè)新的指紋
- unsigned char FP_add_new_user(unsigned char ucH_user,unsigned char ucL_user)
- {
- do
- {
- FINGERPRINT_Cmd_Get_Img(); //獲得指紋圖像
- } while ( dat[9]!=0x0 ); //檢測(cè)是否成功的按了指紋
- FINGERPRINT_Cmd_Img_To_Buffer1(); //將圖像轉(zhuǎn)換成特征碼存放在Buffer1中
- do
- {
- FINGERPRINT_Cmd_Get_Img(); //獲得指紋圖像
- } while( dat[9]!=0x0 );
- FINGERPRINT_Cmd_Img_To_Buffer2(); //將圖像轉(zhuǎn)換成特征碼存放在Buffer2中
- FINGERPRINT_Cmd_Reg_Model(); //轉(zhuǎn)換成特征碼
- FINGERPRINT_Cmd_Save_Finger(ucH_user,ucL_user);
- return 0;
- }
第2個(gè) FPM10A.h
- #ifndef _FPM10A_H
- #define _FPM10A_H
- #include
- extern unsigned char dat[18];
- extern void FINGERPRINT_Cmd_Get_Img();
- extern void FINGERPRINT_Cmd_Img_To_Buffer1();
- extern void FINGERPRINT_Cmd_Img_To_Buffer2();
- extern void FINGERPRINT_Cmd_Reg_Model();
- extern void FINGERPRINT_Cmd_Delete_All_Model(void);
- extern void FINGERPRINT_Cmd_Search_Finger(void);
- extern void FINGERPRINT_Cmd_Get_Templete_Num(void);
- extern void FINGERPRINT_Cmd_Search_Finger_Admin(void);
- extern void FINGERPRINT_Cmd_Save_Finger( unsigned char ucH_Char, unsigned char ucL_Char);
- extern unsigned char FP_add_new_user(unsigned char ucH_user,unsigned char ucL_user);
- extern void USART1_SendByte(unsigned char temp);
- extern unsigned char USART1_ReceivByte();
- extern void Delay_ms1(uint32_t nCount);
- void Delay_nus1(uint32_t nCount)
- {
- uint32_t j;
- while(nCount--)
- {
- j=8;
- while(j--);
- }
- }
- void Delay_ms1(uint32_t nCount)
- {
- while(nCount--)
- Delay_nus1(1100);
- }
- unsigned char test_fig()//檢測(cè)指紋模塊錄入指紋情況,返回00表示錄入成功;02無手指;03錄入失敗
- {
- unsigned char fig_dat;
- FINGERPRINT_Cmd_Get_Img();
- Delay_ms1(20);
- fig_dat=dat[9];
- return(fig_dat);
- }
- #endif
有了這兩個(gè)東西,加入到你的工程中,就可以直接調(diào)用啦!
評(píng)論