日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32(HAL库 标准库通用) AS608光学指纹模块驱动

發布時間:2024/3/26 编程问答 194 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32(HAL库 标准库通用) AS608光学指纹模块驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

工作原理:

引腳連接:
AS608模塊 TXD 連接單片機RXT,RXD連接TXD,touch引腳可以隨便接一個IO 引腳,最后一根線接3.3V,touch引腳主要用于判斷是否有手指按下,本文測試沒用到,如果需要則需判斷該引腳狀態,然后再發送數據包,這樣可以有效提高代碼效率;本文測試使用STM32的串口3引腳作為AS608連接引腳。
如果想要直接看代碼,可以跳過原理,直接往下翻,代碼在最后
AS608主要通過串口通信
1、緩沖區與指紋庫
系統內設有一個 72K 字節的圖像緩沖區與二個 512bytes 大小的特征文件緩沖區,名字分別稱為:ImageBuffer,CharBuffer1 和 CharBuffer2。用戶可以通過指令讀寫任意一個緩沖區。
CharBuffer1 或 CharBuffer2 既可以用于存放普通特征文件也可以用于存放模板特征文件。通過 UART 口上傳或下載圖像時為了加快速度,只用到像素字節的高 4 位,即將兩個像素合
成一個字節傳送。通過 USB 口則是整 8 位像素。
指紋庫容量根據掛接的 FLASH 容量不同而改變,系統會自動判別。指紋模板按照序號存放,序號定義為:0—(N-1)(N 為指紋庫容量)。用戶只能根據序號訪問指紋庫內容。

2、用戶記事本
系統在 FLASH 中開辟了一個 512 字節的存儲區域作為用戶記事本,該記事本邏輯上被分成 16 頁,每頁 32 字節。上位機可以通過 PS_WriteNotepad 指令和 PS_ReadNotepad 指令
訪問任意一頁。注意寫記事本某一頁的時候,該頁 32 字節的內容被整體寫入,原來的內容被覆蓋。
3、隨機數產生器
系統內部集成了硬件 32 位隨機數生成器(不需要隨機數種子),用戶可以通過指令讓模塊產生一個隨機數并上傳給上位機。
4、模塊地址 (大小:4bytes ,屬性:讀寫)
模塊的默認地址為0xFFFFFFFF,可通過指令修改,數據包的地址域必須與該地址相配,命令包/數據包才被系統接收。 注:與上位機通訊必須是默認地址 0xFFFFFFFF !
5、模塊口令 (大小:4bytes ,屬性:寫)
系統默認口令為 0,可通過指令修改。若默認口令未被修改,則系統不要求驗證口令,
上位機和 MCU 與芯片通訊;若口令被修改,則上位機與芯片通訊的第一個指令必須是驗證
口令,只有口令驗證通過后,芯片才接收其它指令。 注:不建議修改口令!
6、數據包大小設置(大小:1bytes ,屬性:讀寫)
發送數據包和接收數據包的長度根據該值設定。
7、波特率數 系數 N 設置 (大小:1bytes ,屬性:讀寫)
USART 波特率=N×9600,N=1~12。
8、安全等級 level 設置(大小:1bytes ,屬性:讀寫)
系統根據安全等級設定比對閥值,level=1~5。安全等級為 1 時認假率最高,拒認率最低。
安全等級為 5 時認假率最低,拒認率最高。

指紋發送指令流程:獲取指紋圖像指令—>生成指紋特征指令----->搜索驗證指紋指令

指令圖解:

錄入圖像指令:

搜索指紋指令:

生成指紋特征指令:

指紋通信協議格式:
以上就是指紋進行通信時的一些指令,根據這幾張圖,就可以寫代碼了。

代碼部分:

我這里采用的是串口二,有需要自己改一下:
代碼部分我主要講把官方給的標準庫的代碼,進行簡單移植,變為HAL庫也能使用的代碼,末尾也會附上標準庫的代碼
as608.c

#include <string.h> #include <stdio.h> #include "usart.h" #include "as608.h" #include "oled.h" #include "key.h"uint32_t AS608Addr = 0XFFFFFFFF; //默認 char str2[6] = {0};//串口接收緩存區 uint8_t USART2_RX_BUF[USART2_MAX_RECV_LEN]; //接收緩沖,最大USART2_MAX_RECV_LEN個字節. uint8_t USART2_TX_BUF[USART2_MAX_SEND_LEN]; //發送緩沖,最大USART2_MAX_SEND_LEN字節//通過判斷接收連續2個字符之間的時間差不大于10ms來決定是不是一次連續的數據. //如果2個字符接收間隔超過10ms,則認為不是1次連續數據.也就是超過10ms沒有接收到 //任何數據,則表示此次接收完畢. //接收到的數據狀態 //[15]:0,沒有接收到數據;1,接收到了一批數據. //[14:0]:接收到的數據長度 __IO uint16_t USART2_RX_STA=0;//串口發送一個字節 static void MYUSART_SendData(uint8_t data) {while((USART2->SR & 0X40) == 0);USART2->DR = data; } //發送包頭 static void SendHead(void) {MYUSART_SendData(0xEF);MYUSART_SendData(0x01); } //發送地址 static void SendAddr(void) {MYUSART_SendData(AS608Addr >> 24);MYUSART_SendData(AS608Addr >> 16);MYUSART_SendData(AS608Addr >> 8);MYUSART_SendData(AS608Addr); } //發送包標識, static void SendFlag(uint8_t flag) {MYUSART_SendData(flag); } //發送包長度 static void SendLength(int length) {MYUSART_SendData(length >> 8);MYUSART_SendData(length); } //發送指令碼 static void Sendcmd(uint8_t cmd) {MYUSART_SendData(cmd); } //發送校驗和 static void SendCheck(uint16_t check) {MYUSART_SendData(check >> 8);MYUSART_SendData(check); } //判斷中斷接收的數組有沒有應答包 //waittime為等待中斷接收數據的時間(單位1ms) //返回值:數據包首地址 static uint8_t *JudgeStr(uint16_t waittime) {char *data;uint8_t str[8];str[0] = 0xef;str[1] = 0x01;str[2] = AS608Addr >> 24;str[3] = AS608Addr >> 16;str[4] = AS608Addr >> 8;str[5] = AS608Addr;str[6] = 0x07;str[7] = '\0'; // USART2_RX_STA = 0;//HAL庫的寫法HAL_UART_Receive(&huart2,(uint8_t *)USART2_RX_BUF,USART2_MAX_RECV_LEN,waittime/4);//串口三接收數據if(!memcmp(str,USART2_RX_BUF,7))//比對數據{data = strstr((const char*)USART2_RX_BUF, (const char*)str);if(data)return (uint8_t*)data;}// // while(--waittime) // { // HAL_Delay(1); // if(USART2_RX_STA & 0X8000) //接收到一次數據 // { // USART2_RX_STA = 0; // data = strstr((const char*)USART2_RX_BUF, (const char*)str); // if(data) // return (uint8_t*)data; // } // }return 0; } //錄入圖像 PS_GetImage //功能:探測手指,探測到后錄入指紋圖像存于ImageBuffer。 //模塊返回確認字 uint8_t PS_GetImage(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x03);Sendcmd(0x01);temp = 0x01 + 0x03 + 0x01;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //生成特征 PS_GenChar //功能:將ImageBuffer中的原始圖像生成指紋特征文件存于CharBuffer1或CharBuffer2 //參數:BufferID --> charBuffer1:0x01 charBuffer1:0x02 //模塊返回確認字 uint8_t PS_GenChar(uint8_t BufferID) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x04);Sendcmd(0x02);MYUSART_SendData(BufferID);temp = 0x01 + 0x04 + 0x02 + BufferID;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //精確比對兩枚指紋特征 PS_Match //功能:精確比對CharBuffer1 與CharBuffer2 中的特征文件 //模塊返回確認字 uint8_t PS_Match(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x03);Sendcmd(0x03);temp = 0x01 + 0x03 + 0x03;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //搜索指紋 PS_Search //功能:以CharBuffer1或CharBuffer2中的特征文件搜索整個或部分指紋庫.若搜索到,則返回頁碼。 //參數: BufferID @ref CharBuffer1 CharBuffer2 //說明: 模塊返回確認字,頁碼(相配指紋模板) uint8_t PS_Search(uint8_t BufferID, uint16_t StartPage, uint16_t PageNum, SearchResult *p) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x08);Sendcmd(0x04);MYUSART_SendData(BufferID);MYUSART_SendData(StartPage >> 8);MYUSART_SendData(StartPage);MYUSART_SendData(PageNum >> 8);MYUSART_SendData(PageNum);temp = 0x01 + 0x08 + 0x04 + BufferID+ (StartPage >> 8) + (uint8_t)StartPage+ (PageNum >> 8) + (uint8_t)PageNum;SendCheck(temp);data = JudgeStr(2000);if(data){ensure = data[9];p->pageID = (data[10] << 8) + data[11];p->mathscore = (data[12] << 8) + data[13];}elseensure = 0xff;return ensure; } //合并特征(生成模板)PS_RegModel //功能:將CharBuffer1與CharBuffer2中的特征文件合并生成 模板,結果存于CharBuffer1與CharBuffer2 //說明: 模塊返回確認字 uint8_t PS_RegModel(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x03);Sendcmd(0x05);temp = 0x01 + 0x03 + 0x05;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //儲存模板 PS_StoreChar //功能:將 CharBuffer1 或 CharBuffer2 中的模板文件存到 PageID 號flash數據庫位置。 //參數: BufferID @ref charBuffer1:0x01 charBuffer1:0x02 // PageID(指紋庫位置號) //說明: 模塊返回確認字 uint8_t PS_StoreChar(uint8_t BufferID, uint16_t PageID) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x06);Sendcmd(0x06);MYUSART_SendData(BufferID);MYUSART_SendData(PageID >> 8);MYUSART_SendData(PageID);temp = 0x01 + 0x06 + 0x06 + BufferID+ (PageID >> 8) + (uint8_t)PageID;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //刪除模板 PS_DeletChar //功能: 刪除flash數據庫中指定ID號開始的N個指紋模板 //參數: PageID(指紋庫模板號),N刪除的模板個數。 //說明: 模塊返回確認字 uint8_t PS_DeletChar(uint16_t PageID, uint16_t N) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x07);Sendcmd(0x0C);MYUSART_SendData(PageID >> 8);MYUSART_SendData(PageID);MYUSART_SendData(N >> 8);MYUSART_SendData(N);temp = 0x01 + 0x07 + 0x0C+ (PageID >> 8) + (uint8_t)PageID+ (N >> 8) + (uint8_t)N;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //清空指紋庫 PS_Empty //功能: 刪除flash數據庫中所有指紋模板 //參數: 無 //說明: 模塊返回確認字 uint8_t PS_Empty(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x03);Sendcmd(0x0D);temp = 0x01 + 0x03 + 0x0D;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //寫系統寄存器 PS_WriteReg //功能: 寫模塊寄存器 //參數: 寄存器序號RegNum:4\5\6 //說明: 模塊返回確認字 uint8_t PS_WriteReg(uint8_t RegNum, uint8_t DATA) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x05);Sendcmd(0x0E);MYUSART_SendData(RegNum);MYUSART_SendData(DATA);temp = RegNum + DATA + 0x01 + 0x05 + 0x0E;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;if(ensure == 0)printf("\r\n設置參數成功!");elseprintf("\r\n%s", EnsureMessage(ensure));return ensure; } //讀系統基本參數 PS_ReadSysPara //功能: 讀取模塊的基本參數(波特率,包大小等) //參數: 無 //說明: 模塊返回確認字 + 基本參數(16bytes) uint8_t PS_ReadSysPara(SysPara *p) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x03);Sendcmd(0x0F);temp = 0x01 + 0x03 + 0x0F;SendCheck(temp);data = JudgeStr(1000);if(data){ensure = data[9];p->PS_max = (data[14] << 8) + data[15];p->PS_level = data[17];p->PS_addr = (data[18] << 24) + (data[19] << 16) + (data[20] << 8) + data[21];p->PS_size = data[23];p->PS_N = data[25];}elseensure = 0xff;if(ensure == 0x00){printf("\r\n模塊最大指紋容量=%d", p->PS_max);printf("\r\n對比等級=%d", p->PS_level);printf("\r\n地址=%x", p->PS_addr);printf("\r\n波特率=%d", p->PS_N * 9600);}elseprintf("\r\n%s", EnsureMessage(ensure));return ensure; } //設置模塊地址 PS_SetAddr //功能: 設置模塊地址 //參數: PS_addr //說明: 模塊返回確認字 uint8_t PS_SetAddr(uint32_t PS_addr) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x07);Sendcmd(0x15);MYUSART_SendData(PS_addr >> 24);MYUSART_SendData(PS_addr >> 16);MYUSART_SendData(PS_addr >> 8);MYUSART_SendData(PS_addr);temp = 0x01 + 0x07 + 0x15+ (uint8_t)(PS_addr >> 24) + (uint8_t)(PS_addr >> 16)+ (uint8_t)(PS_addr >> 8) + (uint8_t)PS_addr;SendCheck(temp);AS608Addr = PS_addr; //發送完指令,更換地址data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;AS608Addr = PS_addr;if(ensure == 0x00)printf("\r\n設置地址成功!");elseprintf("\r\n%s", EnsureMessage(ensure));return ensure; } //功能: 模塊內部為用戶開辟了256bytes的FLASH空間用于存用戶記事本, // 該記事本邏輯上被分成 16 個頁。 //參數: NotePageNum(0~15),Byte32(要寫入內容,32個字節) //說明: 模塊返回確認字 uint8_t PS_WriteNotepad(uint8_t NotePageNum, uint8_t *Byte32) {uint16_t temp;uint8_t ensure, i;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(36);Sendcmd(0x18);MYUSART_SendData(NotePageNum);for(i = 0; i < 32; i++){MYUSART_SendData(Byte32[i]);temp += Byte32[i];}temp = 0x01 + 36 + 0x18 + NotePageNum + temp;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //讀記事PS_ReadNotepad //功能: 讀取FLASH用戶區的128bytes數據 //參數: NotePageNum(0~15) //說明: 模塊返回確認字+用戶信息 uint8_t PS_ReadNotepad(uint8_t NotePageNum, uint8_t *Byte32) {uint16_t temp;uint8_t ensure, i;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x04);Sendcmd(0x19);MYUSART_SendData(NotePageNum);temp = 0x01 + 0x04 + 0x19 + NotePageNum;SendCheck(temp);data = JudgeStr(2000);if(data){ensure = data[9];for(i = 0; i < 32; i++){Byte32[i] = data[10 + i];}}elseensure = 0xff;return ensure; } //高速搜索PS_HighSpeedSearch //功能:以 CharBuffer1或CharBuffer2中的特征文件高速搜索整個或部分指紋庫。 // 若搜索到,則返回頁碼,該指令對于的確存在于指紋庫中 ,且登錄時質量 // 很好的指紋,會很快給出搜索結果。 //參數: BufferID, StartPage(起始頁),PageNum(頁數) //說明: 模塊返回確認字+頁碼(相配指紋模板) uint8_t PS_HighSpeedSearch(uint8_t BufferID, uint16_t StartPage, uint16_t PageNum, SearchResult *p) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x08);Sendcmd(0x1b);MYUSART_SendData(BufferID);MYUSART_SendData(StartPage >> 8);MYUSART_SendData(StartPage);MYUSART_SendData(PageNum >> 8);MYUSART_SendData(PageNum);temp = 0x01 + 0x08 + 0x1b + BufferID+ (StartPage >> 8) + (uint8_t)StartPage+ (PageNum >> 8) + (uint8_t)PageNum;SendCheck(temp);data = JudgeStr(2000);if(data){ensure = data[9];p->pageID = (data[10] << 8) + data[11];p->mathscore = (data[12] << 8) + data[13];}elseensure = 0xff;return ensure; } //讀有效模板個數 PS_ValidTempleteNum //功能:讀有效模板個數 //參數: 無 //說明: 模塊返回確認字+有效模板個數ValidN uint8_t PS_ValidTempleteNum(uint16_t *ValidN) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標識SendLength(0x03);Sendcmd(0x1d);temp = 0x01 + 0x03 + 0x1d;SendCheck(temp);data = JudgeStr(2000);if(data){ensure = data[9];*ValidN = (data[10] << 8) + data[11];}elseensure = 0xff;if(ensure == 0x00){printf("\r\n有效指紋個數=%d", (data[10] << 8) + data[11]);}elseprintf("\r\n%s", EnsureMessage(ensure));return ensure; } //與AS608握手 PS_HandShake //參數: PS_Addr地址指針 //說明: 模塊返新地址(正確地址) uint8_t PS_HandShake(uint32_t *PS_Addr) {SendHead();SendAddr();MYUSART_SendData(0X01);MYUSART_SendData(0X00);MYUSART_SendData(0X00);HAL_Delay(200);if(USART2_RX_STA & 0X8000) //接收到數據{if(//判斷是不是模塊返回的應答包USART2_RX_BUF[0] == 0XEF&& USART2_RX_BUF[1] == 0X01&& USART2_RX_BUF[6] == 0X07){*PS_Addr = (USART2_RX_BUF[2] << 24) + (USART2_RX_BUF[3] << 16)+ (USART2_RX_BUF[4] << 8) + (USART2_RX_BUF[5]);USART2_RX_STA = 0;return 0;}USART2_RX_STA = 0;}return 1; } //模塊應答包確認碼信息解析 //功能:解析確認碼錯誤信息返回信息 //參數: ensure const char *EnsureMessage(uint8_t ensure) {const char *p;switch(ensure){case 0x00:p = " OK ";break;case 0x01:p = " 數據包接收錯誤 ";break;case 0x02:p = "傳感器上沒有手指";break;case 0x03:p = "錄入指紋圖像失敗";break;case 0x04:p = " 指紋太干或太淡 ";break;case 0x05:p = " 指紋太濕或太糊 ";break;case 0x06:p = " 指紋圖像太亂 ";break;case 0x07:p = " 指紋特征點太少 ";break;case 0x08:p = " 指紋不匹配 ";break;case 0x09:p = " 沒有搜索到指紋 ";break;case 0x0a:p = " 特征合并失敗 ";break;case 0x0b:p = "地址序號超出范圍";case 0x10:p = " 刪除模板失敗 ";break;case 0x11:p = " 清空指紋庫失敗 ";break;case 0x15:p = "緩沖區內無有效圖";break;case 0x18:p = " 讀寫FLASH出錯 ";break;case 0x19:p = " 未定義錯誤 ";break;case 0x1a:p = " 無效寄存器號 ";break;case 0x1b:p = " 寄存器內容錯誤 ";break;case 0x1c:p = " 記事本頁碼錯誤 ";break;case 0x1f:p = " 指紋庫滿 ";break;case 0x20:p = " 地址錯誤 ";break;default :p = " 返回確認碼有誤 ";break;}return p; }//顯示確認碼錯誤信息 void ShowErrMessage(uint8_t ensure) {//OLED_ShowMixedCH(5,0,(uint8_t*)EnsureMessage(ensure)); }//錄指紋 void Add_FR(void) {uint8_t i, ensure, processnum = 0;uint8_t ID_NUM = 0;uint8_t key_num = 0;while(1){switch (processnum){case 0:i++;OLED_FullyClear();OLED_ShowMixedCH(0, 16, " 請按手指 ");OLED_RefreshRAM();ensure = PS_GetImage();if(ensure == 0x00){ensure = PS_GenChar(CharBuffer1); //生成特征if(ensure == 0x00){OLED_ShowMixedCH(0, 16, " 指紋正常 ");OLED_ShowMixedCH(0, 16, " ");OLED_RefreshRAM();i = 0;processnum = 1; //跳到第二步}else ShowErrMessage(ensure);}else ShowErrMessage(ensure);break;case 1:i++;OLED_ShowMixedCH(0, 16, " 請再按一次 ");OLED_ShowMixedCH(0, 16, " ");OLED_RefreshRAM();ensure = PS_GetImage();if(ensure == 0x00){ensure = PS_GenChar(CharBuffer2); //生成特征if(ensure == 0x00){OLED_ShowMixedCH(0, 16, " 指紋正常 ");OLED_ShowMixedCH(0, 32, " ");OLED_RefreshRAM();i = 0;processnum = 2; //跳到第三步}else ShowErrMessage(ensure);}else ShowErrMessage(ensure);break;case 2:OLED_ShowMixedCH(0, 16, " 對比兩次指紋 ");OLED_ShowMixedCH(0, 32, " ");OLED_RefreshRAM();ensure = PS_Match();if(ensure == 0x00){OLED_ShowMixedCH(0, 16, " 對比成功 ");OLED_ShowMixedCH(0, 32, " ");OLED_RefreshRAM();processnum = 3; //跳到第四步}else{OLED_ShowMixedCH(0, 16, " 對比失敗 ");OLED_ShowMixedCH(0, 32, " ");OLED_RefreshRAM();ShowErrMessage(ensure);i = 0;processnum = 0; //跳回第一步}HAL_Delay(500);break;case 3:OLED_ShowMixedCH(0, 16, " 生成指紋模板 ");OLED_ShowMixedCH(0, 32, " ");OLED_RefreshRAM();HAL_Delay(500);ensure = PS_RegModel();if(ensure == 0x00){OLED_ShowMixedCH(0, 16, "生成指紋模板成功");OLED_ShowMixedCH(0, 32, " ");OLED_RefreshRAM();processnum = 4; //跳到第五步}else{processnum = 0;ShowErrMessage(ensure);}HAL_Delay(1000);break;case 4:OLED_FullyClear();OLED_ShowMixedCH(0, 0, " 按K4加,按K2減 ");OLED_ShowMixedCH(0, 16, " 按K3保存 ");OLED_ShowMixedCH(0, 32, " 0=< ID <=99 ");OLED_RefreshRAM();while(key_num != KEYENTER_PRES){key_num = key_scan();if(key_num == KEYDOWN_PRES){key_num = 0;if(ID_NUM > 0)ID_NUM--;}if(key_num == KEYUP_PRES){key_num = 0;if(ID_NUM < 99)ID_NUM++;}show_ID(40,48,ID_NUM);}key_num = 0;ensure = PS_StoreChar(CharBuffer2, ID_NUM); //儲存模板if(ensure == 0x00){OLED_FullyClear();OLED_ShowMixedCH(0, 16, " 錄入指紋成功 ");OLED_ShowMixedCH(0, 32, " ");OLED_RefreshRAM();HAL_Delay(1500);OLED_FullyClear();OLED_ShowMixedCH(0, 0, "指紋模塊測試程序");OLED_ShowMixedCH(16, 16, "K1鍵添加指紋");OLED_ShowMixedCH(16, 32, "K3鍵刪除指紋");OLED_ShowMixedCH(16, 48, "K5鍵驗證指紋");OLED_RefreshRAM();return ;}else{OLED_FullyClear();processnum = 0;ShowErrMessage(ensure);}break;}HAL_Delay(400);if(i == 10) //超過5次沒有按手指則退出{break;}} }SysPara AS608Para;//指紋模塊AS608參數 //刷指紋 void press_FR(void) {SearchResult seach;uint8_t ensure;char str[20];uint8_t key_num = 0;while(key_num != KEYBACK_PRES){key_num = key_scan();ensure = PS_GetImage();if(ensure == 0x00) //獲取圖像成功{ensure = PS_GenChar(CharBuffer1);if(ensure == 0x00) //生成特征成功{ensure = PS_HighSpeedSearch(CharBuffer1, 0, 99, &seach);if(ensure == 0x00) //搜索成功{OLED_FullyClear();OLED_ShowMixedCH(0, 16, " 指紋驗證成功 ");sprintf(str, " ID:%d 得分:%d ", seach.pageID, seach.mathscore);OLED_ShowMixedCH(0, 32, (uint8_t*)str);OLED_RefreshRAM();HAL_Delay(1500);HAL_Delay(1500);}else{OLED_ShowMixedCH(32, 16, "驗證失敗");OLED_RefreshRAM();HAL_Delay(1500);}}else{};OLED_FullyClear();OLED_ShowMixedCH(32, 16, "請按手指");OLED_RefreshRAM();}}OLED_FullyClear();OLED_ShowMixedCH(0, 0, "指紋模塊測試程序");OLED_ShowMixedCH(16, 16, "K1鍵添加指紋");OLED_ShowMixedCH(16, 32, "K3鍵刪除指紋");OLED_ShowMixedCH(16, 48, "K5鍵驗證指紋");OLED_RefreshRAM(); }//刪除指紋 void Del_FR(void) {uint8_t ensure;uint16_t ID_NUM = 0;uint8_t key_num = 0;OLED_FullyClear();OLED_ShowMixedCH(0, 16, "K4加 K2減 K3確認");OLED_ShowMixedCH(0, 32, "K1返回 0=<ID<=99");OLED_RefreshRAM();while(key_num != KEYENTER_PRES){key_num = key_scan();if(key_num == KEYDOWN_PRES){key_num = 0;if(ID_NUM > 0)ID_NUM--;}if(key_num == KEYUP_PRES){key_num = 0;if(ID_NUM < 99)ID_NUM++;}if(key_num == KEYBACK_PRES)goto MENU ; //返回主頁面show_ID(40,48,ID_NUM);}ensure = PS_DeletChar(ID_NUM, 1); //刪除單個指紋if(ensure == 0){OLED_FullyClear();OLED_ShowMixedCH(0, 16, " 刪除指紋成功 ");OLED_RefreshRAM();}elseShowErrMessage(ensure);HAL_Delay(1500); MENU:OLED_FullyClear();OLED_ShowMixedCH(0, 0, "指紋模塊測試程序");OLED_ShowMixedCH(16, 16, "K1鍵添加指紋");OLED_ShowMixedCH(16, 32, "K3鍵刪除指紋");OLED_ShowMixedCH(16, 48, "K5鍵驗證指紋");OLED_RefreshRAM();key_num = 0; }void delete_ALL(void) {uint8_t ensure;ensure = PS_Empty(); //清空指紋庫if(ensure == 0){OLED_FullyClear();OLED_ShowMixedCH(0, 16, " 清空指紋庫成功 ");OLED_RefreshRAM();}else{ShowErrMessage(ensure);HAL_Delay(1500);} }

上面是官方的代碼,我做了一點修改,代碼中有很多移位操作,那些就是上面幾個圖中的指令,感興趣的可以去移位算一下。
修改的函數:

//判斷中斷接收的數組有沒有應答包 //waittime為等待中斷接收數據的時間(單位1ms) //返回值:數據包首地址 static uint8_t *JudgeStr(uint16_t waittime) {char *data;uint8_t str[8];str[0] = 0xef;str[1] = 0x01;str[2] = AS608Addr >> 24;str[3] = AS608Addr >> 16;str[4] = AS608Addr >> 8;str[5] = AS608Addr;str[6] = 0x07;str[7] = '\0';//HAL庫的寫法HAL_UART_Receive(&huart2,(uint8_t *)USART2_RX_BUF,USART2_MAX_RECV_LEN,waittime/4);//串口三接收數據if(!memcmp(str,USART2_RX_BUF,7))//比對數據{data = strstr((const char*)USART2_RX_BUF, (const char*)str);if(data)return (uint8_t*)data;} // USART2_RX_STA = 0; // while(--waittime) // { // HAL_Delay(1); // if(USART2_RX_STA & 0X8000) //接收到一次數據 // { // USART2_RX_STA = 0; // data = strstr((const char*)USART2_RX_BUF, (const char*)str); // if(data) // return (uint8_t*)data; // } // }return 0; }

整個代碼中,需要用到HAL庫只需要改這一部分就可以使用了。因為官方代碼串口接收采用的中斷,所以用到HAL庫我就改為了阻塞接收,把原來官方給的中斷部分刪掉即可
as608.h:

#ifndef __AS608_H #define __AS608_H #include <stdio.h> #include "stm32f1xx_hal.h"//#define PS_Sta PAin(6)//讀指紋模塊狀態引腳 #define CharBuffer1 0x01 #define CharBuffer2 0x02#define USART2_MAX_RECV_LEN 400 //最大接收緩存字節數 #define USART2_MAX_SEND_LEN 400 //最大發送緩存字節數 #define USART2_RX_EN 1 //0,不接收;1,接收.extern uint32_t AS608Addr;//模塊地址typedef struct {uint16_t pageID;//指紋IDuint16_t mathscore;//匹配得分 }SearchResult;typedef struct {uint16_t PS_max;//指紋最大容量uint8_t PS_level;//安全等級uint32_t PS_addr;uint8_t PS_size;//通訊數據包大小uint8_t PS_N;//波特率基數N }SysPara;void PS_StaGPIO_Init(void);//初始化PA6讀狀態引腳uint8_t PS_GetImage(void); //錄入圖像 uint8_t PS_GenChar(uint8_t BufferID);//生成特征 uint8_t PS_Match(void);//精確比對兩枚指紋特征 uint8_t PS_Search(uint8_t BufferID,uint16_t StartPage,uint16_t PageNum,SearchResult *p);//搜索指紋 uint8_t PS_RegModel(void);//合并特征(生成模板) uint8_t PS_StoreChar(uint8_t BufferID,uint16_t PageID);//儲存模板 uint8_t PS_DeletChar(uint16_t PageID,uint16_t N);//刪除模板 uint8_t PS_Empty(void);//清空指紋庫 uint8_t PS_WriteReg(uint8_t RegNum,uint8_t DATA);//寫系統寄存器 uint8_t PS_ReadSysPara(SysPara *p); //讀系統基本參數 uint8_t PS_SetAddr(uint32_t addr); //設置模塊地址 uint8_t PS_WriteNotepad(uint8_t NotePageNum,uint8_t *content);//寫記事本 uint8_t PS_ReadNotepad(uint8_t NotePageNum,uint8_t *note);//讀記事 uint8_t PS_HighSpeedSearch(uint8_t BufferID,uint16_t StartPage,uint16_t PageNum,SearchResult *p);//高速搜索 uint8_t PS_ValidTempleteNum(uint16_t *ValidN);//讀有效模板個數 uint8_t PS_HandShake(uint32_t *PS_Addr); //與AS608模塊握手const char *EnsureMessage(uint8_t ensure);//確認碼錯誤信息解析void Add_FR(void);void press_FR(void);void Del_FR(void);void delete_ALL(void);#endif

以上就是通過標準庫移植為HAL庫之后的代碼

標準庫代碼鏈接: https://pan.baidu.com/s/1t5-VQ0BpBHGaw2MuOF7azA 提取碼: rbwe
HAL庫代碼鏈接: https://pan.baidu.com/s/1Bf-6KohsnX4jqrtybxpMNA 提取碼: 2iny

總結

以上是生活随笔為你收集整理的STM32(HAL库 标准库通用) AS608光学指纹模块驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。