生活随笔
收集整理的這篇文章主要介紹了
STM32(HAL库 标准库通用) AS608光学指纹模块驱动
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
工作原理:
引腳連接:
AS608模塊 TXD 連接單片機RXT,RXD連接TXD,touch引腳可以隨便接一個IO 引腳,最后一根線接3.3V,touch引腳主要用于判斷是否有手指按下,本文測試沒用到,如果需要則需判斷該引腳狀態(tài),然后再發(fā)送數(shù)據(jù)包,這樣可以有效提高代碼效率;本文測試使用STM32的串口3引腳作為AS608連接引腳。
如果想要直接看代碼,可以跳過原理,直接往下翻,代碼在最后
AS608主要通過串口通信
1、緩沖區(qū)與指紋庫
系統(tǒng)內(nèi)設(shè)有一個 72K 字節(jié)的圖像緩沖區(qū)與二個 512bytes 大小的特征文件緩沖區(qū),名字分別稱為:ImageBuffer,CharBuffer1 和 CharBuffer2。用戶可以通過指令讀寫任意一個緩沖區(qū)。
CharBuffer1 或 CharBuffer2 既可以用于存放普通特征文件也可以用于存放模板特征文件。通過 UART 口上傳或下載圖像時為了加快速度,只用到像素字節(jié)的高 4 位,即將兩個像素合
成一個字節(jié)傳送。通過 USB 口則是整 8 位像素。
指紋庫容量根據(jù)掛接的 FLASH 容量不同而改變,系統(tǒng)會自動判別。指紋模板按照序號存放,序號定義為:0—(N-1)(N 為指紋庫容量)。用戶只能根據(jù)序號訪問指紋庫內(nèi)容。
2、用戶記事本
系統(tǒng)在 FLASH 中開辟了一個 512 字節(jié)的存儲區(qū)域作為用戶記事本,該記事本邏輯上被分成 16 頁,每頁 32 字節(jié)。上位機可以通過 PS_WriteNotepad 指令和 PS_ReadNotepad 指令
訪問任意一頁。注意寫記事本某一頁的時候,該頁 32 字節(jié)的內(nèi)容被整體寫入,原來的內(nèi)容被覆蓋。
3、隨機數(shù)產(chǎn)生器
系統(tǒng)內(nèi)部集成了硬件 32 位隨機數(shù)生成器(不需要隨機數(shù)種子),用戶可以通過指令讓模塊產(chǎn)生一個隨機數(shù)并上傳給上位機。
4、模塊地址 (大小:4bytes ,屬性:讀寫)
模塊的默認(rèn)地址為0xFFFFFFFF,可通過指令修改,數(shù)據(jù)包的地址域必須與該地址相配,命令包/數(shù)據(jù)包才被系統(tǒng)接收。 注:與上位機通訊必須是默認(rèn)地址 0xFFFFFFFF !
5、模塊口令 (大小:4bytes ,屬性:寫)
系統(tǒng)默認(rèn)口令為 0,可通過指令修改。若默認(rèn)口令未被修改,則系統(tǒng)不要求驗證口令,
上位機和 MCU 與芯片通訊;若口令被修改,則上位機與芯片通訊的第一個指令必須是驗證
口令,只有口令驗證通過后,芯片才接收其它指令。 注:不建議修改口令!
6、數(shù)據(jù)包大小設(shè)置(大小:1bytes ,屬性:讀寫)
發(fā)送數(shù)據(jù)包和接收數(shù)據(jù)包的長度根據(jù)該值設(shè)定。
7、波特率數(shù) 系數(shù) N 設(shè)置 (大小:1bytes ,屬性:讀寫)
USART 波特率=N×9600,N=1~12。
8、安全等級 level 設(shè)置(大小:1bytes ,屬性:讀寫)
系統(tǒng)根據(jù)安全等級設(shè)定比對閥值,level=1~5。安全等級為 1 時認(rèn)假率最高,拒認(rèn)率最低。
安全等級為 5 時認(rèn)假率最低,拒認(rèn)率最高。
指紋發(fā)送指令流程:獲取指紋圖像指令—>生成指紋特征指令----->搜索驗證指紋指令
指令圖解:
錄入圖像指令:
搜索指紋指令:
生成指紋特征指令:
指紋通信協(xié)議格式:
以上就是指紋進(jìn)行通信時的一些指令,根據(jù)這幾張圖,就可以寫代碼了。
代碼部分:
我這里采用的是串口二,有需要自己改一下:
代碼部分我主要講把官方給的標(biāo)準(zhǔn)庫的代碼,進(jìn)行簡單移植,變?yōu)镠AL庫也能使用的代碼,末尾也會附上標(biāo)準(zhǔn)庫的代碼
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
];
uint8_t USART2_TX_BUF
[USART2_MAX_SEND_LEN
];
__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
);
}
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_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
;}
return 0;
}
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
;
}
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
;
}
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
;
}
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
;
}
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
;
}
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
;
}
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
;
}
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
;
}
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設(shè)置參數(shù)成功!");elseprintf("\r\n%s", EnsureMessage(ensure
));return ensure
;
}
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
;
}
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設(shè)置地址成功!");elseprintf("\r\n%s", EnsureMessage(ensure
));return ensure
;
}
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
;
}
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
;
}
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
;
}
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有效指紋個數(shù)=%d", (data
[10] << 8) + data
[11]);}elseprintf("\r\n%s", EnsureMessage(ensure
));return ensure
;
}
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;
}
const char *EnsureMessage(uint8_t ensure
)
{const char *p
;switch(ensure
){case 0x00:p
= " OK ";break;case 0x01:p
= " 數(shù)據(jù)包接收錯誤 ";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
= "緩沖區(qū)內(nèi)無有效圖";break;case 0x18:p
= " 讀寫FLASH出錯 ";break;case 0x19:p
= " 未定義錯誤 ";break;case 0x1a:p
= " 無效寄存器號 ";break;case 0x1b:p
= " 寄存器內(nèi)容錯誤 ";break;case 0x1c:p
= " 記事本頁碼錯誤 ";break;case 0x1f:p
= " 指紋庫滿 ";break;case 0x20:p
= " 地址錯誤 ";break;default :p
= " 返回確認(rèn)碼有誤 ";break;}return p
;
}
void ShowErrMessage(uint8_t 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) {break;}}
}SysPara AS608Para
;
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確認(rèn)");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);}
}
上面是官方的代碼,我做了一點修改,代碼中有很多移位操作,那些就是上面幾個圖中的指令,感興趣的可以去移位算一下。
修改的函數(shù):
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_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
;}
return 0;
}
整個代碼中,需要用到HAL庫只需要改這一部分就可以使用了。因為官方代碼串口接收采用的中斷,所以用到HAL庫我就改為了阻塞接收,把原來官方給的中斷部分刪掉即可
as608.h:
#ifndef __AS608_H
#define __AS608_H
#include <stdio.h>
#include "stm32f1xx_hal.h"
#define CharBuffer1 0x01
#define CharBuffer2 0x02#define USART2_MAX_RECV_LEN 400
#define USART2_MAX_SEND_LEN 400
#define USART2_RX_EN 1 extern uint32_t AS608Addr
;typedef struct
{uint16_t pageID
;uint16_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
;
}SysPara
;void PS_StaGPIO_Init(void);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
); const char *EnsureMessage(uint8_t ensure
);void Add_FR(void);void press_FR(void);void Del_FR(void);void delete_ALL(void);#endif
以上就是通過標(biāo)準(zhǔn)庫移植為HAL庫之后的代碼
標(biāo)準(zhǔn)庫代碼鏈接: https://pan.baidu.com/s/1t5-VQ0BpBHGaw2MuOF7azA 提取碼: rbwe
HAL庫代碼鏈接: https://pan.baidu.com/s/1Bf-6KohsnX4jqrtybxpMNA 提取碼: 2iny
總結(jié)
以上是生活随笔為你收集整理的STM32(HAL库 标准库通用) AS608光学指纹模块驱动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。