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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

STM32(HAL库 ) AS608光学指纹模块驱动(中断接收方式)

發(fā)布時(shí)間:2024/3/26 编程问答 87 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32(HAL库 ) AS608光学指纹模块驱动(中断接收方式) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

STM32 AS608 光學(xué)指紋模塊通過(guò)串口打印測(cè)試:(百分百HAL庫(kù))

引腳連接:
AS608模塊 TXD 連接單片機(jī)RXT,RXD連接TXD,touch引腳可以隨便接一個(gè)IO 引腳,最后一根線(xiàn)接3.3V,touch引腳主要用于判斷是否有手指按下,本文測(cè)試沒(méi)用到,如果需要?jiǎng)t需判斷該引腳狀態(tài),然后再發(fā)送數(shù)據(jù)包,這樣可以有效提高代碼效率;本文測(cè)試使用STM32的串口3引腳作為AS608連接引腳。

一、使用STM32CUBEMX配置
串口3作為AS608通信引腳配置如下:

中斷使能:

注意:上面引腳波特率應(yīng)該與你AS608模塊波特率一致,我這里使用115200
串口1作為DEBUG測(cè)試引腳配置如下:

時(shí)鐘配置:

配置完成生成工程代碼即可。
二、代碼編寫(xiě)
1、as608.c文件

#include <string.h> #include <stdio.h> #include "delay.h" #include "usart.h" #include "as608.h"/*串口接收中斷處理在stm32f1xx_it.c里面*/uint32_t AS608Addr = 0XFFFFFFFF;//默認(rèn)char str2[6] = {0};uint8_t USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收緩沖,最大USART3_MAX_RECV_LEN個(gè)字節(jié).uint8_t Get_Device_Code[10] ={0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x00,0x1b};//口令驗(yàn)證uint8_t USART3_RX_STA= 0;//串口是否接收到數(shù)據(jù)//串口發(fā)送一個(gè)字節(jié) static uint8_t MYUSART_SendData(uint8_t data) {if(HAL_UART_Transmit(&AS608_UART,&data,1,0xff) == HAL_OK)return 0;return 1; } //發(fā)送包頭 static void SendHead(void) {memset(USART3_RX_BUF,0,sizeof(USART3_RX_BUF));//發(fā)送前清空數(shù)據(jù),因?yàn)樗卸家l(fā)送包頭,所以只需要在發(fā)送包頭前清空即可MYUSART_SendData(0xEF);MYUSART_SendData(0x01); } //發(fā)送地址 static void SendAddr(void) {MYUSART_SendData(AS608Addr >> 24);MYUSART_SendData(AS608Addr >> 16);MYUSART_SendData(AS608Addr >> 8);MYUSART_SendData(AS608Addr); } //發(fā)送包標(biāo)識(shí), static void SendFlag(uint8_t flag) {MYUSART_SendData(flag); } //發(fā)送包長(zhǎng)度 static void SendLength(int length) {MYUSART_SendData(length >> 8);MYUSART_SendData(length); } //發(fā)送指令碼 static void Sendcmd(uint8_t cmd) {MYUSART_SendData(cmd); } //發(fā)送校驗(yàn)和 static void SendCheck(uint16_t check) {MYUSART_SendData(check >> 8);MYUSART_SendData(check); }/***************************************** 函數(shù)名:uint8_t AS608_Check(void) 參數(shù):無(wú) 功能描述:模塊是否連接檢測(cè) 返回值:模塊連接了返回0 否則返回1 *****************************************/ static uint8_t AS608_Check(void) {USART3_RX_BUF[9] = 1;SendHead();SendAddr();for(int i = 0; i < 10; i++){MYUSART_SendData(Get_Device_Code[i]);}//HAL_UART_Receive(&AS608_UART,USART3_RX_BUF,12,100);//串口三接收12個(gè)數(shù)據(jù)delay_ms(200);//等待200msif(USART3_RX_BUF[9] == 0)return 0;return 1; } /*指紋模塊初始化*/ uint8_t as608_init(void) {//設(shè)置uart3接收中斷HAL_UART_Receive_IT(&AS608_UART,USART3_RX_BUF,sizeof( USART3_RX_BUF));//接收數(shù)據(jù),且產(chǎn)生中斷//使能空閑中斷__HAL_UART_ENABLE_IT(&AS608_UART,UART_IT_IDLE);//return AS608_Check(); } //判斷中斷接收的數(shù)組有沒(méi)有應(yīng)答包 //waittime為等待中斷接收數(shù)據(jù)的時(shí)間(單位1ms) //返回值:數(shù)據(jù)包首地址 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';USART3_RX_STA = 0;while(--waittime){delay_ms(1);if(USART3_RX_STA) //接收到一次數(shù)據(jù){USART3_RX_STA = 0;data = strstr((const char*)USART3_RX_BUF, (const char*)str);if(data)return (uint8_t*)data;}}return 0; } //錄入圖像 PS_GetImage //功能:探測(cè)手指,探測(cè)到后錄入指紋圖像存于ImageBuffer。 //模塊返回確認(rèn)字 uint8_t PS_GetImage(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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 //參數(shù):BufferID --> charBuffer1:0x01 charBuffer1:0x02 //模塊返回確認(rèn)字 uint8_t PS_GenChar(uint8_t BufferID) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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; } //精確比對(duì)兩枚指紋特征 PS_Match //功能:精確比對(duì)CharBuffer1 與CharBuffer2 中的特征文件 //模塊返回確認(rèn)字 uint8_t PS_Match(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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中的特征文件搜索整個(gè)或部分指紋庫(kù).若搜索到,則返回頁(yè)碼。 //參數(shù): BufferID @ref CharBuffer1 CharBuffer2 //說(shuō)明: 模塊返回確認(rèn)字,頁(yè)碼(相配指紋模板) 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);//命令包標(biāo)識(shí)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中的特征文件合并生成 模板,結(jié)果存于CharBuffer1與CharBuffer2 //說(shuō)明: 模塊返回確認(rèn)字 uint8_t PS_RegModel(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)SendLength(0x03);Sendcmd(0x05);temp = 0x01 + 0x03 + 0x05;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //儲(chǔ)存模板 PS_StoreChar //功能:將 CharBuffer1 或 CharBuffer2 中的模板文件存到 PageID 號(hào)flash數(shù)據(jù)庫(kù)位置。 //參數(shù): BufferID @ref charBuffer1:0x01 charBuffer1:0x02 // PageID(指紋庫(kù)位置號(hào)) //說(shuō)明: 模塊返回確認(rèn)字 uint8_t PS_StoreChar(uint8_t BufferID, uint16_t PageID) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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數(shù)據(jù)庫(kù)中指定ID號(hào)開(kāi)始的N個(gè)指紋模板 //參數(shù): PageID(指紋庫(kù)模板號(hào)),N刪除的模板個(gè)數(shù)。 //說(shuō)明: 模塊返回確認(rèn)字 uint8_t PS_DeletChar(uint16_t PageID, uint16_t N) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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; } //清空指紋庫(kù) PS_Empty //功能: 刪除flash數(shù)據(jù)庫(kù)中所有指紋模板 //參數(shù): 無(wú) //說(shuō)明: 模塊返回確認(rèn)字 uint8_t PS_Empty(void) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)SendLength(0x03);Sendcmd(0x0D);temp = 0x01 + 0x03 + 0x0D;SendCheck(temp);data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;return ensure; } //寫(xiě)系統(tǒng)寄存器 PS_WriteReg //功能: 寫(xiě)模塊寄存器 //參數(shù): 寄存器序號(hào)RegNum:4\5\6 //說(shuō)明: 模塊返回確認(rèn)字 uint8_t PS_WriteReg(uint8_t RegNum, uint8_t DATA) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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設(shè)置參數(shù)成功!");elseprintf("\r\n%s", EnsureMessage(ensure));return ensure; } //讀系統(tǒng)基本參數(shù) PS_ReadSysPara //功能: 讀取模塊的基本參數(shù)(波特率,包大小等) //參數(shù): 無(wú) //說(shuō)明: 模塊返回確認(rèn)字 + 基本參數(shù)(16bytes) uint8_t PS_ReadSysPara(SysPara *p) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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對(duì)比等級(jí)=%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; } //設(shè)置模塊地址 PS_SetAddr //功能: 設(shè)置模塊地址 //參數(shù): PS_addr //說(shuō)明: 模塊返回確認(rèn)字 uint8_t PS_SetAddr(uint32_t PS_addr) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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; //發(fā)送完指令,更換地址data = JudgeStr(2000);if(data)ensure = data[9];elseensure = 0xff;AS608Addr = PS_addr;if(ensure == 0x00)printf("\r\n設(shè)置地址成功!");elseprintf("\r\n%s", EnsureMessage(ensure));return ensure; } //功能: 模塊內(nèi)部為用戶(hù)開(kāi)辟了256bytes的FLASH空間用于存用戶(hù)記事本, // 該記事本邏輯上被分成 16 個(gè)頁(yè)。 //參數(shù): NotePageNum(0~15),Byte32(要寫(xiě)入內(nèi)容,32個(gè)字節(jié)) //說(shuō)明: 模塊返回確認(rèn)字 uint8_t PS_WriteNotepad(uint8_t NotePageNum, uint8_t *Byte32) {uint16_t temp;uint8_t ensure, i;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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用戶(hù)區(qū)的128bytes數(shù)據(jù) //參數(shù): NotePageNum(0~15) //說(shuō)明: 模塊返回確認(rèn)字+用戶(hù)信息 uint8_t PS_ReadNotepad(uint8_t NotePageNum, uint8_t *Byte32) {uint16_t temp;uint8_t ensure, i;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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中的特征文件高速搜索整個(gè)或部分指紋庫(kù)。 // 若搜索到,則返回頁(yè)碼,該指令對(duì)于的確存在于指紋庫(kù)中 ,且登錄時(shí)質(zhì)量 // 很好的指紋,會(huì)很快給出搜索結(jié)果。 //參數(shù): BufferID, StartPage(起始頁(yè)),PageNum(頁(yè)數(shù)) //說(shuō)明: 模塊返回確認(rèn)字+頁(yè)碼(相配指紋模板) 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);//命令包標(biāo)識(shí)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; } //讀有效模板個(gè)數(shù) PS_ValidTempleteNum //功能:讀有效模板個(gè)數(shù) //參數(shù): 無(wú) //說(shuō)明: 模塊返回確認(rèn)字+有效模板個(gè)數(shù)ValidN uint8_t PS_ValidTempleteNum(uint16_t *ValidN) {uint16_t temp;uint8_t ensure;uint8_t *data;SendHead();SendAddr();SendFlag(0x01);//命令包標(biāo)識(shí)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有效指紋個(gè)數(shù)=%d", (data[10] << 8) + data[11]);}elseprintf("\r\n%s", EnsureMessage(ensure));return ensure; } //與AS608握手 PS_HandShake //參數(shù): PS_Addr地址指針 //說(shuō)明: 模塊返新地址(正確地址) uint8_t PS_HandShake(uint32_t *PS_Addr) {SendHead();SendAddr();MYUSART_SendData(0X01);MYUSART_SendData(0X00);MYUSART_SendData(0X00);delay_ms(200);if(USART3_RX_STA) //接收到數(shù)據(jù){if(//判斷是不是模塊返回的應(yīng)答包USART3_RX_BUF[0] == 0XEF&& USART3_RX_BUF[1] == 0X01&& USART3_RX_BUF[6] == 0X07){*PS_Addr = (USART3_RX_BUF[2] << 24) + (USART3_RX_BUF[3] << 16)+ (USART3_RX_BUF[4] << 8) + (USART3_RX_BUF[5]);USART3_RX_STA = 0;return 0;}USART3_RX_STA = 0;}return 1; } //模塊應(yīng)答包確認(rèn)碼信息解析 //功能:解析確認(rèn)碼錯(cuò)誤信息返回信息 //參數(shù): ensure const char *EnsureMessage(uint8_t ensure) {const char *p;switch(ensure){case 0x00:p = " OK ";break;case 0x01:p = " 數(shù)據(jù)包接收錯(cuò)誤 ";break;case 0x02:p = "傳感器上沒(méi)有手指";break;case 0x03:p = "錄入指紋圖像失敗";break;case 0x04:p = " 指紋太干或太淡 ";break;case 0x05:p = " 指紋太濕或太糊 ";break;case 0x06:p = " 指紋圖像太亂 ";break;case 0x07:p = " 指紋特征點(diǎn)太少 ";break;case 0x08:p = " 指紋不匹配 ";break;case 0x09:p = " 沒(méi)有搜索到指紋 ";break;case 0x0a:p = " 特征合并失敗 ";break;case 0x0b:p = "地址序號(hào)超出范圍";case 0x10:p = " 刪除模板失敗 ";break;case 0x11:p = " 清空指紋庫(kù)失敗 ";break;case 0x15:p = "緩沖區(qū)內(nèi)無(wú)有效圖";break;case 0x18:p = " 讀寫(xiě)FLASH出錯(cuò) ";break;case 0x19:p = " 未定義錯(cuò)誤 ";break;case 0x1a:p = " 無(wú)效寄存器號(hào) ";break;case 0x1b:p = " 寄存器內(nèi)容錯(cuò)誤 ";break;case 0x1c:p = " 記事本頁(yè)碼錯(cuò)誤 ";break;case 0x1f:p = " 指紋庫(kù)滿(mǎn) ";break;case 0x20:p = " 地址錯(cuò)誤 ";break;default :p = " 返回確認(rèn)碼有誤 ";break;}return p; }//顯示確認(rèn)碼錯(cuò)誤信息 void ShowErrMessage(uint8_t ensure) {//OLED_ShowCH(5,0,(uint8_t*)EnsureMessage(ensure));printf("%s\r\n",EnsureMessage(ensure)); }//錄指紋 void Add_FR(void) {uint8_t i, ensure, processnum = 0;uint8_t ID_NUM = 0;while(1){switch (processnum){case 0:i++;printf("請(qǐng)按手指\r\n");ensure = PS_GetImage();if(ensure == 0x00){ensure = PS_GenChar(CharBuffer1); //生成特征if(ensure == 0x00){printf("指紋正常\r\n");i = 0;processnum = 1; //跳到第二步}else ShowErrMessage(ensure);}else ShowErrMessage(ensure);break;case 1:i++;printf("請(qǐng)?jiān)侔匆淮蝄r\n");ensure = PS_GetImage();if(ensure == 0x00){ensure = PS_GenChar(CharBuffer2); //生成特征if(ensure == 0x00){printf("指紋正常\r\n");i = 0;processnum = 2; //跳到第三步}else ShowErrMessage(ensure);}else ShowErrMessage(ensure);break;case 2:printf("對(duì)比兩次指紋\r\n");ensure = PS_Match();if(ensure == 0x00){printf("對(duì)比成功\r\n");processnum = 3; //跳到第四步}else{printf("對(duì)比失敗\r\n");ShowErrMessage(ensure);i = 0;processnum = 0; //跳回第一步}delay_ms(500);break;case 3:printf("生成指紋模板\r\n");delay_ms(500);ensure = PS_RegModel();if(ensure == 0x00){printf("生成指紋模板成功\r\n");processnum = 4; //跳到第五步}else{processnum = 0;ShowErrMessage(ensure);}delay_ms(1000);break;case 4:printf("默認(rèn)選擇ID為1 \r\n");ID_NUM = 1;#if 0while(key_num != 3){key_num = KEY_Scan(0);if(key_num == 2){key_num = 0;if(ID_NUM > 0)ID_NUM--;}if(key_num == 4){key_num = 0;if(ID_NUM < 99)ID_NUM++;}OLED_ShowCH(40, 6, "ID=");OLED_ShowNum(65, 6, ID_NUM, 2, 1);}key_num = 0;#endifensure = PS_StoreChar(CharBuffer2, ID_NUM); //儲(chǔ)存模板if(ensure == 0x00){printf("錄入指紋成功\r\n");delay_ms(1500);return ;}else{processnum = 0;ShowErrMessage(ensure);}break;}delay_ms(400);if(i == 10) //超過(guò)5次沒(méi)有按手指則退出{break;}} }SysPara AS608Para;//指紋模塊AS608參數(shù) //刷指紋 void press_FR(void) {SearchResult seach;uint8_t ensure;char str[20];while(1){//key_num = KEY_Scan(0);ensure = PS_GetImage();if(ensure == 0x00) //獲取圖像成功{ensure = PS_GenChar(CharBuffer1);if(ensure == 0x00) //生成特征成功{ensure = PS_HighSpeedSearch(CharBuffer1, 0, 99, &seach);if(ensure == 0x00) //搜索成功{printf("指紋驗(yàn)證成功");sprintf(str, " ID:%d 得分:%d ", seach.pageID, seach.mathscore);printf("%s\r\n",str);delay_ms(1500);delay_ms(1500);}else{printf("驗(yàn)證失敗\r\n");delay_ms(1500);}}else{};printf("請(qǐng)按手指\r\n");}} }//刪除單個(gè)指紋 void Del_FR(void) {uint8_t ensure;uint16_t ID_NUM = 0;printf("單個(gè)刪除指紋開(kāi)始,默認(rèn)刪除ID為1");ID_NUM = 1;ensure = PS_DeletChar(ID_NUM, 1); //刪除單個(gè)指紋if(ensure == 0){printf("刪除指紋成功 \r\n");}elseShowErrMessage(ensure);delay_ms(1500);} /*清空指紋庫(kù)*/ void Del_FR_Lib(void) {uint8_t ensure;printf("刪除指紋庫(kù)開(kāi)始\r\n");ensure = PS_Empty(); //清空指紋庫(kù)if(ensure == 0){printf("清空指紋庫(kù)成功\r\n");}elseShowErrMessage(ensure);delay_ms(1500); }

2、as608.h文件

#ifndef __AS608_H #define __AS608_H#include "stm32f1xx_hal.h"#define CharBuffer1 0x01 #define CharBuffer2 0x02#define USART3_MAX_RECV_LEN 400 //最大接收緩存字節(jié)數(shù)#define AS608_UART huart3//AS608模塊所使用的串口extern uint8_t USART3_RX_BUF[USART3_MAX_RECV_LEN];extern uint8_t USART3_RX_STA;extern uint32_t AS608Addr;//模塊地址typedef struct {uint16_t pageID;//指紋IDuint16_t mathscore;//匹配得分 }SearchResult;typedef struct {uint16_t PS_max;//指紋最大容量uint8_t PS_level;//安全等級(jí)uint32_t PS_addr;uint8_t PS_size;//通訊數(shù)據(jù)包大小uint8_t PS_N;//波特率基數(shù)N }SysPara;uint8_t as608_init(void);uint8_t PS_GetImage(void); //錄入圖像 uint8_t PS_GenChar(uint8_t BufferID);//生成特征 uint8_t PS_Match(void);//精確比對(duì)兩枚指紋特征 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);//儲(chǔ)存模板 uint8_t PS_DeletChar(uint16_t PageID,uint16_t N);//刪除模板 uint8_t PS_Empty(void);//清空指紋庫(kù) uint8_t PS_WriteReg(uint8_t RegNum,uint8_t DATA);//寫(xiě)系統(tǒng)寄存器 uint8_t PS_ReadSysPara(SysPara *p); //讀系統(tǒng)基本參數(shù) uint8_t PS_SetAddr(uint32_t addr); //設(shè)置模塊地址 uint8_t PS_WriteNotepad(uint8_t NotePageNum,uint8_t *content);//寫(xiě)記事本 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);//讀有效模板個(gè)數(shù) uint8_t PS_HandShake(uint32_t *PS_Addr); //與AS608模塊握手const char *EnsureMessage(uint8_t ensure);//確認(rèn)碼錯(cuò)誤信息解析void Add_FR(void);void press_FR(void);void Del_FR(void);void Del_FR_Lib(void);#endif

如果串口使用不一樣,只需修改頭文件中宏定義:
#define AS608_UART huart3//AS608模塊所使用的串口
即可。
由于通信接收用的是中斷接收,所以還需編寫(xiě)中斷接收部分代碼,并且在不知道要接收多長(zhǎng)的數(shù)據(jù)前提下,只能利用串口空閑中斷方式來(lái)進(jìn)行不定長(zhǎng)數(shù)據(jù)接收;

空閑中斷:

顧名思義,就是需要判斷串口接收總線(xiàn)狀態(tài)、如果處于繁忙狀態(tài),則還有數(shù)據(jù)正在發(fā)送過(guò)來(lái),如果處于空閑,則表明數(shù)據(jù)接收完成;所以只需要判斷串口接收總線(xiàn)的狀態(tài)。
在使用之前需要對(duì)該串口進(jìn)行初始化,初始化函數(shù)如下:

/***************************************** 函數(shù)名:uint8_t AS608_Check(void) 參數(shù):無(wú) 功能描述:模塊是否連接檢測(cè) 返回值:模塊連接了返回0 否則返回1 *****************************************/ static uint8_t AS608_Check(void) {USART3_RX_BUF[9] = 1;SendHead();SendAddr();for(int i = 0; i < 10; i++){MYUSART_SendData(Get_Device_Code[i]);}//HAL_UART_Receive(&AS608_UART,USART3_RX_BUF,12,100);//串口三接收12個(gè)數(shù)據(jù)delay_ms(200);//等待200msif(USART3_RX_BUF[9] == 0)return 0;return 1; } /*指紋模塊初始化*/ uint8_t as608_init(void) {//設(shè)置uart3接收中斷HAL_UART_Receive_IT(&AS608_UART,USART3_RX_BUF,sizeof( USART3_RX_BUF));//接收數(shù)據(jù),且產(chǎn)生中斷//使能空閑中斷__HAL_UART_ENABLE_IT(&AS608_UART,UART_IT_IDLE);//return AS608_Check(); }

在初始化時(shí)需要使能中斷接收,以及使能空閑中斷,之后對(duì)模塊進(jìn)行檢測(cè),調(diào)用模塊檢測(cè)函數(shù)發(fā)送相關(guān)指令、如果模塊錯(cuò)誤或者未連接返回1,成功返回0。

中斷處理函數(shù)如下,只需在對(duì)應(yīng)的串口中斷添加以下代碼即可:

/*** @brief This function handles USART3 global interrupt.*/ void USART3_IRQHandler(void) {/* USER CODE BEGIN USART3_IRQn 0 *///串口接收不定長(zhǎng)數(shù)據(jù)//判斷是否為空閑中斷,如果是就認(rèn)為接收數(shù)據(jù)完成 if(__HAL_UART_GET_FLAG(&AS608_UART,UART_FLAG_IDLE) != RESET){//認(rèn)為數(shù)據(jù)接收完成,進(jìn)行處理//1、清除空閑中斷__HAL_UART_CLEAR_IDLEFLAG(&AS608_UART);//2、獲取接收大小//3、清空接收狀態(tài)AS608_UART.RxXferCount = sizeof(USART3_RX_BUF);AS608_UART.pRxBuffPtr = USART3_RX_BUF;USART3_RX_STA = 1;//接收數(shù)據(jù)完成return ; }/* USER CODE END USART3_IRQn 0 */HAL_UART_IRQHandler(&huart3);/* USER CODE BEGIN USART3_IRQn 1 *//* USER CODE END USART3_IRQn 1 */ }

驅(qū)動(dòng)程序到此編寫(xiě)完成。

實(shí)際應(yīng)用示例:

main.c

/* USER CODE BEGIN Header */ /********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "usart.h" #include "gpio.h"/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "as608.h" #include <stdio.h> /* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD *//* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /***************************************** 函數(shù)名: 參數(shù):無(wú) 功能描述:printf輸出重定向到串口1 返回值: *****************************************/ int fputc(int ch,FILE *f){uint8_t temp[1]={ch};HAL_UART_Transmit(&huart1,temp,1,2);return ch; } /* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/ int main(void) {/* USER CODE BEGIN 1 */uint8_t res = 1;/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();MX_USART3_UART_Init();/* USER CODE BEGIN 2 */printf("AS608指紋模塊測(cè)試開(kāi)始\r\n");res = as608_init();if(res == 0){printf("AS608指紋模塊初始化成功\r\n");}elseprintf("AS608指紋模塊初始化失敗\r\n");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///注意:這里測(cè)試都是通過(guò)串口,沒(méi)有按鍵和OLED,所以測(cè)試時(shí)只能一個(gè)函數(shù)一個(gè)函數(shù)測(cè)試//Add_FR();//添加指紋,默認(rèn)ID為1, 可根據(jù)實(shí)際需要修改press_FR();//刷指紋測(cè)試//Del_FR_Lib();//刪除指紋庫(kù)}/* USER CODE END 3 */ }/*** @brief System Clock Configuration* @retval None*/ void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();} }/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/ void Error_Handler(void) {/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */ }#ifdef USE_FULL_ASSERT /*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/ void assert_failed(uint8_t *file, uint32_t line) {/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */

測(cè)試結(jié)果:


測(cè)試成功。
完整工程鏈接:
https://pan.baidu.com/s/1NYAyaCEsx5vJbCZV6vQ3lQ 提取碼: rqgq

總結(jié)

以上是生活随笔為你收集整理的STM32(HAL库 ) AS608光学指纹模块驱动(中断接收方式)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。