文章目录
- 一.概要
- 二.AS608模块主要技术指标
- 三.AS608模块接线说明
- 四.AS608模块通讯协议介绍
- 五.AS608模块指纹录入与刷指纹流程
- 六.STM32单片机与AS608模块指纹录入与刷指纹实验
- 1.硬件准备
- 2.软件工程
- 3.软件主要代码
- 4.实验效果
- 七.CubeMX工程源代码下载
- 八.小结
一.概要
AS608 指纹识别模块主要是指采用了杭州晟元芯片技术有限公司(Synochip)的 AS608 指纹识别芯片 而做成的指纹模块,模块厂商只是基于该芯片设计外围电路,集成一个可供2次开发的指纹模块。
AS608 指纹识别模块是一款高性能的光学指纹识别模块。芯片内置DSP 运算单元,集成了指纹识别算法,能高效快速采集图像并识别指纹特征。模块配备了串口、USB 通讯接口,只需通过简单的串口、USB 按照通讯协议便可控制模块,本模块可应用于各种考勤机、保险箱柜、指纹门禁系统、指纹锁等场合。
二.AS608模块主要技术指标
三.AS608模块接线说明
AS608模块与单片机只要4根线就能连接
单片机开发板 指纹模块
3.3V-----------------------红色线
GND----------------------黑色线
PA9-----------------------白色线
PA10---------------------黄色线
四.AS608模块通讯协议介绍
串口通讯参数:57600波特率,8位数据,1位停止位,无校验。
MCU与模块通讯发送与接收模块指令和数据按照模块指令格式打包,MCU对接收到的数据包数据解析也按照模块指令格式。
模块指令格式分为三种:命令包格式、数据包格式、结束包格式。
一般指令包是由MCU发送到模块上,模块接收到指令包后,返回对应的数据包。
包长度=包长度至校验和(指令、参数或数据)的总字节数,包含校验和,但不包含包长度本身的字节数。
校验和是从包标识至校验和之间所有字节之和。
模块芯片地址在没有生成之前为缺省的 0xFFFFFFFF,一旦MCU通过指令配置了新的芯片地址,则所有的数据包都必须按照生成的地址收发,模块将拒绝地址错误的数据包,一般我们都是以默认0xFFFFFFFF为地址,不需要配置地址。
命令包格式:
常用命令集及功能描述
数据包格式:
结束包格式:
模块应答是将有关命令执行情况与结果上报给MCU,应答包含有参数,并可跟后续数据包。
MCU只有在收到模块的应答包后才能确认模块收包情况与指令执行情况。模块应答包中包含一个参数:确认码。确认码表示执行指令完毕的情况。
模块应答包格式:
确认码定义:
00H:表示指令执行完毕或OK;
01H:表示数据包接收错误;
02H:表示传感器上没有手指;
03H:表示录入指纹图像失败;
07H:表示指纹图像正常,但特征点太少(或面积太小)而生不成特征;
08H:表示指纹不匹配;
09H:表示没搜索到指纹;
我们以录入图像为例,具体收发指令协议如下:
五.AS608模块指纹录入与刷指纹流程
单片机与AS608模块握手成功之后,说明通讯没问题,就可以进行指纹录入与刷指纹的操作。
指纹录入操作流程
在系统里面录入指纹信息主要以下步骤:
录入图像->生成特征->快速查找图像->自动注册模板。
录指纹代码实现
//录指纹
void Add_FR(void)
{
uint8_t i=0,ensure ,processnum=0;
uint16_t ID;
while(1)
{
switch (processnum)
{
case 0:
i++;
OLED_ShowCHinese(36,3,5);//请
OLED_ShowCHinese(52,3,6);//按
OLED_ShowCHinese(68,3,7);//手
OLED_ShowCHinese(84,3,8);//指
ensure=GZ_GetImage();
if(ensure==0x00)
{
ensure=GZ_GenChar(CharBuffer1);//生成特征
if(ensure==0x00)
{
i=0;
processnum=1;//跳到第二步
}
}
break;
case 1:
i++;
ensure=GZ_GetImage();
if(ensure==0x00)
{
ensure=GZ_GenChar(CharBuffer2);//生成特征
if(ensure==0x00)
{
i=0;
processnum=2;//跳到第三步
}
}
break;
case 2:
ensure=GZ_Match();
if(ensure==0x00)
{
processnum=3;//跳到第四步
}
else
{
i=0;
processnum=0;//跳回第一步
}
HAL_Delay(1000);
break;
case 3:
ensure=GZ_RegModel();
if(ensure==0x00)
{
processnum=4;//跳到第五步
}else {processnum=0;}
HAL_Delay(1000);
break;
case 4:
ID=0;
ensure=GZ_StoreChar(CharBuffer2,ID);//储存模板
if(ensure==0x00)
{
OLED_ShowCHinese(36,3,9);//录
OLED_ShowCHinese(52,3,10);//入
OLED_ShowCHinese(68,3,11);//成
OLED_ShowCHinese(84,3,12);//功
GZ_ValidTempleteNum(&ValidN);//读库指纹个数
HAL_Delay(1500);//延时后清除显示
return ;
}else {processnum=0;}
break;
}
HAL_Delay(800);
if(i==10)//超过10次没有按手指则退出
{
OLED_ShowCHinese(36,3,13);//录
OLED_ShowCHinese(52,3,14);//入
OLED_ShowCHinese(68,3,15);//超
OLED_ShowCHinese(84,3,16);//时
break;
}
}
}
刷指纹流程
刷指纹,就是匹配已经存进去的指纹数据,高速搜索指纹库数据进行匹配,匹配得分高,说明刷的指纹跟录入指纹一致。
录入图像->生成特征->高速搜索指纹库进行匹配。
刷指纹代码实现
//刷指纹
void press_FR(void)
{
SearchResult seach;
uint8_t ensure;
char *str;
OLED_ShowCHinese(36,3,17);//请
OLED_ShowCHinese(52,3,18);//刷
OLED_ShowCHinese(68,3,19);//指
OLED_ShowCHinese(84,3,20);//纹
ensure=GZ_GetImage();
if(ensure==0x00)//获取图像成功
{
ensure=GZ_GenChar(CharBuffer1);
if(ensure==0x00) //生成特征成功
{
ensure=GZ_HighSpeedSearch(CharBuffer1,0,300,&seach);
if(ensure==0x00)//搜索成功
{
if(seach.mathscore>100)匹配得分大于100,说明匹配成功
{
OLED_ShowCHinese(52,6,21);//匹
OLED_ShowCHinese(68,6,22);//配
HAL_Delay(20000);
}else
{
OLED_ShowCHinese(52,6,23);//错
OLED_ShowCHinese(68,6,24);//误
}
}else
{
OLED_ShowCHinese(52,6,23);//错
OLED_ShowCHinese(68,6,24);//误
}
}
}
}
六.STM32单片机与AS608模块指纹录入与刷指纹实验
1.硬件准备
STLINK接STM32F103C8T6开发板,STLINK接电脑USB口。
指纹模块与单片机开发板接线:
单片机开发板
3.3V-----------------------模块红色线
GND----------------------模块黑色线
PA9-----------------------模块白色线
PA10---------------------模块黄色线
2.软件工程
打开STM32CubeMX软件,新建工程
Part Number处输入STM32F103C8,再双击就创建新的工程
配置下载口引脚
配置外部晶振引脚
配置系统主频
配置串口1,57600波特率,8位数据,1位停止位,无校验
串口1中断使能
配置工程文件名,保存路径,KEIL5工程输出方式
生成工程
用Keil5打开工程
添加代码
添加串口中断接收相关代码
空闲中断使能
添加应用相关代码
3.软件主要代码
串口数据接收相关代码
uint8_t aRxBuffer[RXBUFFERSIZE];//接收缓冲
uint8_t RX_len;//接收字节计数
void UsartReceive_IDLE(UART_HandleTypeDef *huart)//空闲中断回调函数
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除中断
RX_len = RXBUFFERSIZE - huart1.RxXferCount; //计算接收数据长度
HAL_UART_AbortReceive_IT(huart); //终止接收
HAL_UART_Receive_IT(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE); //接收完数据后再次打开中断接收函数
}
/**
* @brief Start Receive operation in interrupt mode.
* @note This function could be called by all HAL UART API providing reception in Interrupt mode.
* @note When calling this function, parameters validity is considered as already checked,
* i.e. Rx State, buffer address, ...
* UART Handle is assumed as Locked.
* @param huart UART handle.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @retval HAL status
*/
HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->RxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
/* Process Unlocked */
__HAL_UNLOCK(huart);
/* Enable the UART Parity Error Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_PE);
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
/* Enable the UART Data Register not empty Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);//空闲中断打开,为了方便收一帧数据,串口接收的时候空闲,说明收到完整一帧数据
return HAL_OK;
}
main函数代码
int main(void)
{
/* USER CODE BEGIN 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();//8M外部晶振,72M主频
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();//串口1配置,PA9-> USART1_TX,PA10-> USART1_RX ,57600波特率,8位数据,1位停止位,无校验
/* USER CODE BEGIN 2 */
if (HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//接收中断打开,空闲中断打开
{
}
OLED_Init();//OLED初始化
OLED_Clear();//清屏
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
OLED_Clear();//清屏
OLED_ShowCHinese(18,0,0);//光
OLED_ShowCHinese(36,0,1);//子
OLED_ShowCHinese(54,0,2);//物
OLED_ShowCHinese(72,0,3);//联
OLED_ShowCHinese(90,0,4);//网
/* USER CODE BEGIN 3 */
while(GZ_HandShake(&AS608Addr))//与AS608模块握手
{
HAL_Delay(1000);//等待1秒
}
HAL_Delay(100);
GZ_ValidTempleteNum(&ValidN);//读库指纹个数
GZ_ReadSysPara(&AS608Para); //读AS608模块参数
Add_FR();//录入指纹
HAL_Delay(1000);
while(1)
{
press_FR();//刷指纹
}
}
/* USER CODE END 3 */
}
AS608配置相关
//录入图像 GZ_GetImage
//功能:探测手指,探测到后录入指纹图像存于ImageBuffer。
//模块返回确认字
uint8_t GZ_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];
else
ensure=0xff;
return ensure;
}
//生成特征 GZ_GenChar
//功能:将ImageBuffer中的原始图像生成指纹特征文件存于CharBuffer1或CharBuffer2
//参数:BufferID --> charBuffer1:0x01 charBuffer1:0x02
//模块返回确认字
uint8_t GZ_GenChar(uint8_t BufferID)
{
uint16_t temp;
uint8_t ensure;
uint8_t *data;
SendHead();
SendAddr();
SendFlag(0x01);//命令包标识
SendLength(0x04);
Sendcmd(0x02);
Com_SendData(BufferID);
temp = 0x01+0x04+0x02+BufferID;
SendCheck(temp);
data=JudgeStr(2000);
if(data)
ensure=data[9];
else
ensure=0xff;
return ensure;
}
//精确比对两枚指纹特征 GZ_Match
//功能:精确比对CharBuffer1 与CharBuffer2 中的特征文件
//模块返回确认字
uint8_t GZ_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];
else
ensure=0xff;
return ensure;
}
//搜索指纹 GZ_Search
//功能:以CharBuffer1或CharBuffer2中的特征文件搜索整个或部分指纹库.若搜索到,则返回页码。
//参数: BufferID @ref CharBuffer1 CharBuffer2
//说明: 模块返回确认字,页码(相配指纹模板)
uint8_t GZ_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);
Com_SendData(BufferID);
Com_SendData(StartPage>>8);
Com_SendData(StartPage);
Com_SendData(PageNum>>8);
Com_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];
}
else
ensure = 0xff;
return ensure;
}
//录指纹
void Add_FR(void)
{
uint8_t i=0,ensure ,processnum=0;
uint16_t ID;
while(1)
{
switch (processnum)
{
case 0:
i++;
OLED_ShowCHinese(36,3,5);//请
OLED_ShowCHinese(52,3,6);//按
OLED_ShowCHinese(68,3,7);//手
OLED_ShowCHinese(84,3,8);//指
ensure=GZ_GetImage();
if(ensure==0x00)
{
ensure=GZ_GenChar(CharBuffer1);//生成特征
if(ensure==0x00)
{
i=0;
processnum=1;//跳到第二步
}
}
break;
case 1:
i++;
ensure=GZ_GetImage();
if(ensure==0x00)
{
ensure=GZ_GenChar(CharBuffer2);//生成特征
if(ensure==0x00)
{
i=0;
processnum=2;//跳到第三步
}
}
break;
case 2:
ensure=GZ_Match();
if(ensure==0x00)
{
processnum=3;//跳到第四步
}
else
{
i=0;
processnum=0;//跳回第一步
}
HAL_Delay(1000);
break;
case 3:
ensure=GZ_RegModel();
if(ensure==0x00)
{
processnum=4;//跳到第五步
}else {processnum=0;}
HAL_Delay(1000);
break;
case 4:
ID=0;
ensure=GZ_StoreChar(CharBuffer2,ID);//储存模板
if(ensure==0x00)
{
OLED_ShowCHinese(36,3,9);//录
OLED_ShowCHinese(52,3,10);//入
OLED_ShowCHinese(68,3,11);//成
OLED_ShowCHinese(84,3,12);//功
GZ_ValidTempleteNum(&ValidN);//读库指纹个数
HAL_Delay(1500);//延时后清除显示
return ;
}else {processnum=0;}
break;
}
HAL_Delay(800);
if(i==10)//超过10次没有按手指则退出
{
OLED_ShowCHinese(36,3,13);//录
OLED_ShowCHinese(52,3,14);//入
OLED_ShowCHinese(68,3,15);//超
OLED_ShowCHinese(84,3,16);//时
break;
}
}
}
//刷指纹
void press_FR(void)
{
SearchResult seach;
uint8_t ensure;
char *str;
OLED_ShowCHinese(36,3,17);//请
OLED_ShowCHinese(52,3,18);//刷
OLED_ShowCHinese(68,3,19);//指
OLED_ShowCHinese(84,3,20);//纹
ensure=GZ_GetImage();
if(ensure==0x00)//获取图像成功
{
ensure=GZ_GenChar(CharBuffer1);
if(ensure==0x00) //生成特征成功
{
ensure=GZ_HighSpeedSearch(CharBuffer1,0,300,&seach);
if(ensure==0x00)//搜索成功
{
if(seach.mathscore>100)
{
OLED_ShowCHinese(52,6,21);//匹
OLED_ShowCHinese(68,6,22);//配
HAL_Delay(20000);
}else
{
OLED_ShowCHinese(52,6,23);//错
OLED_ShowCHinese(68,6,24);//误
}
}else
{
OLED_ShowCHinese(52,6,23);//错
OLED_ShowCHinese(68,6,24);//误
}
}
}
}
4.实验效果
1.会提示请按手指
2.手指按到指纹模块上,会提示录入成功
3.录入成功后,板子会提示再刷指纹
4.仍旧用原先的手指刷指纹,会提示匹配,用别的手指会提示匹配错误,说明指纹录入跟刷指纹都正确了
七.CubeMX工程源代码下载
通过网盘分享的文件:指纹识别实验(HAL库).rar
链接: https://pan.baidu.com/s/15xXp2_aj3ERzfxp3BlTF1g 提取码: b6t4
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行
八.小结
学会AS608指纹模块编程,可以很方便应用到实际项目中,如指纹锁,门禁系统和考勤管理,可以实现指纹解锁和打卡功能。