AS608指纹模块详解,阿里、腾讯、华为、京东等多家大厂最新物联网嵌入式开发面试题

70 阅读10分钟

访问任意一页。注意写记事本某一页的时候,该页 32 字节的内容被整体写入,原来的内容被覆盖。 3. 随机数产生器
系统内部集成了硬件 32 位随机数生成器(不需要随机数种子),用户可以通过指令让模块产生一个随机数并上传给上位机。
五、 软件开发 4. 模块地址 (大小:4bytes ,属性:读写) )
模块的默认地址为0xFFFFFFFF,可通过指令修改,数据包的地址域必须与该地址相配,命令包/数据包才被系统接收。 注:与上位机通讯必须是默认地址 0xFFFFFFFF ! 5. 模块口令 (大小:4bytes ,属性:写)
系统默认口令为 0,可通过指令修改。若默认口令未被修改,则系统不要求验证口令,
上位机和 MCU 与芯片通讯;若口令被修改,则上位机与芯片通讯的第一个指令必须是验证
口令,只有口令验证通过后,芯片才接收其它指令。 注:不建议修改口令! 6. 数据包大小设置(大小:1bytes ,属性:读写)
发送数据包和接收数据包的长度根据该值设定。 7. 波特率数 系数 N 设置 (大小:1bytes ,属性:读写)
USART 波特率=N×9600,N=112。 8. 安全等级 level 设置(大小:1bytes ,属性:读写)
系统根据安全等级设定比对阀值,level=1
5。安全等级为 1 时认假率最高,拒认率最低。
安全等级为 5 时认假率最低,拒认率最高。

六、 开发流程

在这里插入图片描述
在这里插入图片描述

七、 使用原理

利用光的折射和反射原理,光从底部射向三棱镜,并经棱镜射出,射出的光线在手指表面指纹凹凸不平的线纹上折射的角度及反射回去的光线明暗就会不一样。CMOS或者CCD的光学器件就会收集到不同明暗程度的图片信息,就完成指纹的采集。

八、 STM32程序

  1. AS608.H
	#ifndef \_\_AS608\_H
	#define \_\_AS608\_H
	#include <stdio.h>
	#include "stm32f10x.h" 
	#define AS608\_USER 1
	#define PS\_Sta PAin(6)//读指纹模块状态引脚
	#define CharBuffer1 0x01
	#define CharBuffer2 0x02
	
	extern u32 AS608Addr;//模块地址

	typedef struct  
	{
		u16 pageID;//指纹ID
		u16 mathscore;//匹配得分
}SearchResult;
	typedef struct
	{
		u16 PS_max;//指纹最大容量
		u8  PS_level;//安全等级
	u32 PS_addr;
		u8  PS_size;//通讯数据包大小
		u8  PS_N;//波特率基数N
}SysPara;
	void PS\_StaGPIO\_Init(void);//初始化PA6读状态引脚
	u8 PS\_GetImage(void); //录入图像 
	u8 PS\_GenChar(u8 BufferID);//生成特征 
	u8 PS\_Match(void);//精确比对两枚指纹特征 
	u8 PS\_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult \*p);//搜索指纹 
	u8 PS\_RegModel(void);//合并特征(生成模板) 
	 
	u8 PS\_StoreChar(u8 BufferID,u16 PageID);//储存模板 
	u8 PS\_DeletChar(u16 PageID,u16 N);//删除模板 
u8 PS\_Empty(void);//清空指纹库 

	u8 PS\_WriteReg(u8 RegNum,u8 DATA);//写系统寄存器 
 
	u8 PS\_ReadSysPara(SysPara \*p); //读系统基本参数 

	u8 PS\_SetAddr(u32 addr);  //设置模块地址 
	
	u8 PS\_WriteNotepad(u8 NotePageNum,u8 \*content);//写记事本 

u8 PS\_ReadNotepad(u8 NotePageNum,u8 \*note);//读记事 
	
	u8 PS\_HighSpeedSearch(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult \*p);//高速搜索 
	  
	u8 PS\_ValidTempleteNum(u16 \*ValidN);//读有效模板个数 
	
	u8 PS\_HandShake(u32 \*PS_Addr); //与AS608模块握手
	
	const char \*EnsureMessage(u8 ensure);//确认码错误信息解析
	
	#endif

  1. AS608.c
#include <string.h>
#include "delay.h" 
#include "usart2.h"
#include "as608.h"

u32 AS608Addr = 0XFFFFFFFF; //默认

//初始化PA6为下拉输入 
//读摸出感应状态(触摸感应时输出高电平信号)
void PS\_StaGPIO\_Init(void)
{   
	RCC->APB1ENR |= 1<<2;//使能PORTA时钟
	GPIOA->CRL &=0XF0FFFFFF;//复位PA6
	GPIOA->CRL |=0X08000000;//输入模式,默认下拉
	GPIOA->ODR &=~(1<<6);//下拉
}
//串口发送一个字节
static void MYUSART\_SendData(u8 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(u8 flag)
{
	MYUSART\_SendData(flag);
}
//发送包长度
static void SendLength(int length)
{
	MYUSART\_SendData(length>>8);
	MYUSART\_SendData(length);
}
//发送指令码
static void Sendcmd(u8 cmd)
{
	MYUSART\_SendData(cmd);
}
//发送校验和
static void SendCheck(u16 check)
{
	MYUSART\_SendData(check>>8);
	MYUSART\_SendData(check);
}
//判断中断接收的数组有没有应答包
//waittime为等待中断接收数据的时间(单位1ms)
//返回值:数据包首地址
static u8 \*JudgeStr(u16 waittime)
{
	char \*data;
	u8 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;
	while(--waittime)
	{
		delay\_ms(1);
		if(USART2_RX_STA&0X8000)//接收到一次数据
		{
			USART2_RX_STA=0;
			data=strstr((const char\*)USART2_RX_BUF,(const char\*)str);
			if(data)
				return (u8\*)data;	
		}
	}
	return 0;
}
//录入图像 PS\_GetImage
//功能:探测手指,探测到后录入指纹图像存于ImageBuffer。 
//模块返回确认字
u8 PS\_GetImage(void)
{
  u16 temp;
  u8  ensure;
	u8  \*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;
}
//生成特征 PS\_GenChar
//功能:将ImageBuffer中的原始图像生成指纹特征文件存于CharBuffer1或CharBuffer2 
//参数:BufferID --> charBuffer1:0x01 charBuffer1:0x02 
//模块返回确认字
u8 PS\_GenChar(u8 BufferID)
{
	u16 temp;
  u8  ensure;
	u8  \*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];
	else
		ensure=0xff;
	return ensure;
}
//精确比对两枚指纹特征 PS\_Match
//功能:精确比对CharBuffer1 与CharBuffer2 中的特征文件 
//模块返回确认字
u8 PS\_Match(void)
{
	u16 temp;
  u8  ensure;
	u8  \*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;
}
//搜索指纹 PS\_Search
//功能:以CharBuffer1或CharBuffer2中的特征文件搜索整个或部分指纹库.若搜索到,则返回页码。 
//参数: BufferID @ref CharBuffer1 CharBuffer2
//说明: 模块返回确认字,页码(相配指纹模板)
u8 PS\_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult \*p)
{
	u16 temp;
  u8  ensure;
	u8  \*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)+(u8)StartPage
	+(PageNum>>8)+(u8)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;	
}
//合并特征(生成模板)PS\_RegModel
//功能:将CharBuffer1与CharBuffer2中的特征文件合并生成 模板,结果存于CharBuffer1与CharBuffer2 
//说明: 模块返回确认字
u8 PS\_RegModel(void)
{
	u16 temp;
  u8  ensure;
	u8  \*data;
	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x05);
	temp = 0x01+0x03+0x05;
	SendCheck(temp);
	data=JudgeStr(2000);
	if(data)
		ensure=data[9];
	else
		ensure=0xff;
	return ensure;		
}
//储存模板 PS\_StoreChar
//功能:将 CharBuffer1 或 CharBuffer2 中的模板文件存到 PageID 号flash数据库位置。 
//参数: BufferID @ref charBuffer1:0x01 charBuffer1:0x02
// PageID(指纹库位置号)
//说明: 模块返回确认字
u8 PS\_StoreChar(u8 BufferID,u16 PageID)
{
	u16 temp;
  u8  ensure;
	u8  \*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)+(u8)PageID;
	SendCheck(temp);
	data=JudgeStr(2000);
	if(data)
		ensure=data[9];
	else
		ensure=0xff;
	return ensure;	
}
//删除模板 PS\_DeletChar
//功能: 删除flash数据库中指定ID号开始的N个指纹模板
//参数: PageID(指纹库模板号),N删除的模板个数。
//说明: 模块返回确认字
u8 PS\_DeletChar(u16 PageID,u16 N)
{
	u16 temp;
  u8  ensure;
	u8  \*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)+(u8)PageID
	+(N>>8)+(u8)N;
	SendCheck(temp);
	data=JudgeStr(2000);
	if(data)
		ensure=data[9];
	else
		ensure=0xff;
	return ensure;
}
//清空指纹库 PS\_Empty
//功能: 删除flash数据库中所有指纹模板
//参数: 无
//说明: 模块返回确认字
u8 PS\_Empty(void)
{
	u16 temp;
  u8  ensure;
	u8  \*data;
	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x0D);
	temp = 0x01+0x03+0x0D;
	SendCheck(temp);
	data=JudgeStr(2000);
	if(data)
		ensure=data[9];
	else
		ensure=0xff;
	return ensure;
}
//写系统寄存器 PS\_WriteReg
//功能: 写模块寄存器
//参数: 寄存器序号RegNum:4\5\6
//说明: 模块返回确认字
u8 PS\_WriteReg(u8 RegNum,u8 DATA)
{
	u16 temp;
  u8  ensure;
	u8  \*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];
	else
		ensure=0xff;
	if(ensure==0)
		printf("\r\n设置参数成功!");
	else
		printf("\r\n%s",EnsureMessage(ensure));
	return ensure;
}
//读系统基本参数 PS\_ReadSysPara
//功能: 读取模块的基本参数(波特率,包大小等)
//参数: 无
//说明: 模块返回确认字 + 基本参数(16bytes)
u8 PS\_ReadSysPara(SysPara \*p)
{
	u16 temp;
  u8  ensure;
	u8  \*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];
	}		
	else
		ensure=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);
	}
	else 
			printf("\r\n%s",EnsureMessage(ensure));
	return ensure;
}
//设置模块地址 PS\_SetAddr
//功能: 设置模块地址
//参数: PS\_addr
//说明: 模块返回确认字
u8 PS\_SetAddr(u32 PS_addr)
{
	u16 temp;
  u8  ensure;
	u8  \*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
	+(u8)(PS_addr>>24)+(u8)(PS_addr>>16)
	+(u8)(PS_addr>>8) +(u8)PS_addr;				
	SendCheck(temp);
	AS608Addr=PS_addr;//发送完指令,更换地址
  data=JudgeStr(2000);
	if(data)
		ensure=data[9];
	else
		ensure=0xff;	
		AS608Addr = PS_addr;
	if(ensure==0x00)
		printf("\r\n设置地址成功!");
	else
		printf("\r\n%s",EnsureMessage(ensure));
	return ensure;
}
//功能: 模块内部为用户开辟了256bytes的FLASH空间用于存用户记事本,
// 该记事本逻辑上被分成 16 个页。
//参数: NotePageNum(0~15),Byte32(要写入内容,32个字节)
//说明: 模块返回确认字
u8 PS\_WriteNotepad(u8 NotePageNum,u8 \*Byte32)
{
	u16 temp;
  u8  ensure,i;
	u8  \*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];
	else
		ensure=0xff;
	return ensure;
}
//读记事PS\_ReadNotepad
//功能: 读取FLASH用户区的128bytes数据
//参数: NotePageNum(0~15)
//说明: 模块返回确认字+用户信息
u8 PS\_ReadNotepad(u8 NotePageNum,u8 \*Byte32)
{
	u16 temp;
  u8  ensure,i;
	u8  \*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];
		}
	}
	else
		ensure=0xff;
	return ensure;
}
//高速搜索PS\_HighSpeedSearch
//功能:以 CharBuffer1或CharBuffer2中的特征文件高速搜索整个或部分指纹库。
// 若搜索到,则返回页码,该指令对于的确存在于指纹库中 ,且登录时质量
// 很好的指纹,会很快给出搜索结果。
//参数: BufferID, StartPage(起始页),PageNum(页数)


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8a58c62698b447dd83ae7e8e87d48f5d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771257554&x-signature=N3s8h904rm1eojcDhtYKNNC1nMM%3D)
![img](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/dd0df0f5f47d4bd783a5ea5543200cd6~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771257554&x-signature=SEjznxGHvCYHhvg6ai5mUdOE1aw%3D)

**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**