STM32传感器模块编程实践(一)AS608指纹模块简介及驱动源码

一.概要

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指纹模块编程,可以很方便应用到实际项目中,如指纹锁,门禁系统和考勤管理,可以实现指纹解锁和打卡功能。

### STM32F407 指纹传感器使用教程 #### 配置开发环境 为了在STM32F407上集成指纹识别功能,需要先设置好开发工具链。这包括安装并配置STM32CubeMX用于初始化硬件资源以及Keil MDK或其他IDE来进行软件编码工作。 #### 初始化硬件接口 对于AS608光学指纹模块而言,其通信依赖于UART协议。因此,在STM32CubeMX中应正确设定相应的USART外设参数以便与指纹设备建立稳定的数据交换通道[^1]。具体来说: - 将AS608的`TXD`端子连接至MCU上的接收引脚(`RXT`) - 把`RXD`接到发送引脚(`TXD`)上去 - `Touch`信号可以选择任意未占用GPIO口接入,但本案例并未涉及此部分逻辑处理 - 确认电源供电正常(通常为3.3V) #### 编写驱动函数 基于HAL库框架下的编程实践能够简化底层操作流程。下面给出段简单的C语言源码片段展示如何通过串口中断机制读取来自指纹仪的信息流,并执行基本命令交互过程[^2]: ```c #include "stm32f4xx_hal.h" // 声明全局变量存储接收到的数据帧 uint8_t rx_buffer[64]; volatile uint8_t new_data_flag = 0; void UART_Init(void){ /* USART3 Initialization Code Here */ } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if(huart->Instance==USART3){ // 当完成次完整的数据包传输后触发回调事件 new_data_flag = 1; HAL_UART_Receive_IT(&huart3,rx_buffer,sizeof(rx_buffer)); } } ``` 上述代码实现了异步接收模式下对指纹图像采集指令响应的基础架构搭建。每当检测到新的输入序列到达时就会调用指定的服务例程更新标志位通知应用程序层进步解析处理。 #### 发送控制指令 当准备向指纹模组发出特定请求之前,应当构建符合官方文档定义格式的有效载荷结构体实例化对象,随后借助预定义好的API封装方法将其推送出去等待回应确认。 ```c int SendCommand(uint8_t* cmd,uint16_t length){ int ret=-1; if(HAL_OK == HAL_UART_Transmit(&huart3,cmd,length,100)){ ret=0; }else{ Error_Handler(); } return ret; } ``` 以上就是关于STM32F407配合AS608实现生物特征认证解决方案的大致思路概述和技术要点说明。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值