【基础学习十五】智能门禁之AS608指纹模块详解
AS608指纹模块内置了传感器模块用于识别指纹特征,用户只需要对应用层进行开发即可。该模块页内置了一个Flash存储,用于用户记事本和指纹库的存储。下面看看用户记事本和指纹库的详细介绍:AS608指纹识别模块与单片机进行通信采用的是USART通信方式,所以要对串口进行相应的配置才能进行有效通信,具体配置要遵循官方手册:当然该模块的通信也给予了用户修改的权力,用户可以根据自己的需要自行修改。
1.基本知识解读
AS608指纹模块内置了传感器模块用于识别指纹特征,用户只需要对应用层进行开发即可。

该模块页内置了一个Flash存储,用于用户记事本和指纹库的存储。下面看看用户记事本和指纹库的详细介绍:

AS608指纹识别模块与单片机进行通信采用的是USART通信方式,所以要对串口进行相应的配置才能进行有效通信,具体配置要遵循官方手册:

当然该模块的通信也给予了用户修改的权力,用户可以根据自己的需要自行修改。
AS608指纹模块与单片机进行通信的数据格式为指令包加应答包模式,所有的指令功能都通过该模式实现,每个指令的指令包和应答包都有自己的格式,具体参考官方手册,下面呈现一直指令的包格式进行参考:

且在应答包中会有1字节的确认码用来对接收到的应答包进行分析,具体的确认码总览见下图:


可见每一个确认码都有相应的说明,可以方便用户来进行一些的判断。
2.程序实现
我们知道了AS608模块的基本知识后,我们就要用程序来对指纹模块与单片机之间的通信进行实现啦。首先我们来看看USART配置程序:
void AS608_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 57600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //使能空闲中断
USART_Cmd(USART1, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
我们通过USART中断的方式来对模块返回的应答包进行接收并将接收到的数据存入接收缓存中,下面是中断服务程序代码:
uint8_t rx_index;
uint8_t rec_over;
uint8_t aRxBuffer[RXBUFF_SIZE];//接收缓冲
uint8_t RX_len;//接收字节计数
void USART1_IRQHandler(void)
{
uint8_t temp;
if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET){ //防止溢出中断
USART_ReceiveData(USART1);
}
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ //USART接收中断
temp = USART_ReceiveData(USART1);
if(rx_index > RXBUFF_SIZE){ //溢出不再接收数据
return;
}
aRxBuffer[rx_index++] = temp;
}
if(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET){ //USART空闲中断
USART_ReceiveData(USART1);
RX_len=rx_index;
rx_index=0;
}
}
接着就是对各个指令功能的函数实现,通过串口字节的发送来发送指令包,然后将接收到的应答包中的确认码以返回值的形式返回,便于我们后面进行判断,下面来看对指令功能进行函数封装的详细代码:
uint32_t AS608Addr = 0xFFFFFFFF; //指纹模块默认地址
//串口发送一个数据
//data:要发送的一个八位的数据
static void Com_SendData(uint8_t data)
{
USART_SendData(USART1, data);//发送数据
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
//发送包头
static void SendHead(void)
{
Com_SendData(0xEF);
Com_SendData(0x01);
}
//发送芯片地址
static void SendAddr(void)
{
Com_SendData(AS608Addr>>24);
Com_SendData(AS608Addr>>16);
Com_SendData(AS608Addr>>8);
Com_SendData(AS608Addr);
}
//发送包标识
static void SendFlag(uint8_t flag)
{
Com_SendData(flag);
}
//发送包长度
static void SendLength(uint16_t length)
{
Com_SendData(length>>8);
Com_SendData(length);
}
//发送指令码
static void SendCmd(uint8_t cmd)
{
Com_SendData(cmd);
}
//发送校验和
static void SendCheck(uint16_t check)
{
Com_SendData(check>>8);
Com_SendData(check);
}
//判断中断接收的数组有没有应答包
//waittime为等待中断接收数据的时间(单位1ms)
//返回值:数据包首地址
extern uint8_t RX_len;
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'; //07H应答包标志位
while(--waittime)
{
Delay_ms(1);
if(RX_len)
{
RX_len=0;
data = strstr((const char*)&aRxBuffer,(const char*)str); //strstr()函数的功能:在第一个字符串里面找第二个字符串,找到了返回该字符串的首地址,没有找到返回NULL
if(data)
{
return (uint8_t*)data;
}
}
}
return 0;
}
/*****************************************************底层功能函数封装****************************************************/
//录入图像 PS_GetImage
//功能:探测手指,探测后将指纹图像存入ImageBuffer
//返回值:应答包中的确认字
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];
else
ensure = 0xFF;
return ensure;
}
//生成特征 PS_GenChar
//功能:将ImageBuffer中的原始图像生成指纹特征文件存于CharBuffer1或CharBuffer2
//参数:BufferID --> charBuffer1:0x01 charBuffer1:0x02
//模块返回确认字
uint8_t PS_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;
}
//精确比对两枚指纹特征 PS_Match
//功能:精确比对CharBuffer1 与CharBuffer2 中的特征文件
//模块返回确认字
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];
else
ensure = 0xFF;
return ensure;
}
//搜索指纹 PS_Search
//功能:以CharBuffer1或CharBuffer2中的特征文件搜索整个或部分指纹库.若搜索到,则返回页码。
//参数: BufferID @ref CharBuffer1 CharBuffer2
//StartPage:起始页 PageNum:页数 P结构体指针
//说明: 模块返回确认字,页码(相配指纹模板)
uint8_t PS_Search(uint8_t BufferID,uint16_t StartPage,uint8_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);
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->MatchScore = (data[12]<<8) + data[13];
}
else
ensure = 0xFF;
return ensure;
}
//合并特征(生成模板)PS_RegModel
//功能:将CharBuffer1与CharBuffer2中的特征文件合并生成 模板,结果存于CharBuffer1与CharBuffer2
//说明: 模块返回确认字
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];
else
ensure = 0xFF;
return ensure;
}
//储存模板 PS_StoreChar
//功能:将 CharBuffer1 或 CharBuffer2 中的模板文件存到 PageID 号flash数据库位置。
//参数: BufferID @ref charBuffer1:0x01 charBuffer1:0x02
// PageID(指纹库位置号)
//说明: 模块返回确认字
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);
Com_SendData(BufferID);
Com_SendData(PageID>>8);
Com_SendData(PageID);
temp = 0x01+0x06+0x06+BufferID+(PageID>>8)+(uint8_t)PageID;
SendCheck(temp);
data = JudgeStr(2000);
if(data)
ensure = data[9];
else
ensure = 0xFF;
return ensure;
}
//删除模板 PS_DeletChar
//功能: 删除flash数据库中指定ID号开始的N个指纹模板
//参数: PageID(指纹库模板号),N删除的模板个数。
//说明: 模块返回确认字
uint8_t PS_DelectChar(uint16_t PageID,uint16_t N)
{
uint16_t temp;
uint8_t ensure;
uint8_t* data;
SendHead();
SendAddr();
SendFlag(0x01);
SendLength(0x07);
SendCmd(0x0c);
Com_SendData(PageID>>8);
Com_SendData(PageID);
Com_SendData(N>>8);
Com_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];
else
ensure = 0xFF;
return ensure;
}
//清空指纹库 PS_Empty
//功能: 删除flash数据库中所有指纹模板
//参数: 无
//说明: 模块返回确认字
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];
else
ensure = 0xFF;
return ensure;
}
//写系统寄存器 PS_WriteReg
//功能: 写模块寄存器
//参数: 寄存器序号RegNum:4\5\6
//说明: 模块返回确认字
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);
Com_SendData(RegNum);
Com_SendData(DATA);
temp = 0x01+0x05+0x0e+RegNum+DATA;
SendCheck(temp);
data = JudgeStr(2000);
if(data)
ensure = data[9];
else
ensure = 0xFF;
return ensure;
}
//读系统基本参数 PS_ReadSysPara
//功能: 读取模块的基本参数(波特率,包大小等)
//参数: 无
//说明: 模块返回确认字 + 基本参数(16bytes)
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(2000);
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;
return ensure;
}
//设置模块地址 PS_SetChipAddr
//功能: 设置模块地址
//参数: PS_addr
//说明: 模块返回确认字
uint8_t PS_SerChipAddr(uint32_t PS_addr)
{
uint16_t temp;
uint8_t ensure;
uint8_t* data;
SendHead();
SendAddr();
SendFlag(0x01);
SendLength(0x07);
SendCmd(0x15);
Com_SendData(PS_addr>>24);
Com_SendData(PS_addr>>16);
Com_SendData(PS_addr>>8);
Com_SendData(PS_addr);
temp = 0x01+0x07+0x15+(PS_addr>>24)+(uint8_t)(PS_addr>>16)+(uint8_t)(PS_addr>>8)+(uint8_t)(PS_addr);
SendCheck(temp);
data = JudgeStr(2000);
if(data)
ensure = data[9];
else
ensure = 0xFF;
AS608Addr = PS_addr;
if(ensure == 0) //设置地址成功
{
}
return ensure;
}
//写记事本 PS_WriteNotepad
//功能: 模块内部为用户开辟了256bytes的FLASH空间用于存用户记事本,
// 该记事本逻辑上被分成 16 个页。
//参数: NotePageNum(0~15),Byte32(要写入内容,32个字节)--32个字节的用户信息
//说明: 模块返回确认字
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);
Com_SendData(NotePageNum);
for(i = 0;i<32;i++)
{
Com_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)
//说明: 模块返回确认字+用户信息
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);
Com_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(页数)
//说明: 模块返回确认字+页码(相配指纹模板)
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);
Com_SendData(BufferID);
Com_SendData(StartPage>>8);
Com_SendData(StartPage);
Com_SendData(PageNum>>8);
Com_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->MatchScore = (data[12]<<8)+data[13];
}
else
ensure = 0xFF;
return ensure;
}
//读有效模板个数 GZ_ValidTempleteNum
//功能:读有效模板个数
//参数: 无
//说明: 模块返回确认字+有效模板个数ValidN
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];
}
else
ensure = 0xFF;
return ensure;
}
//与AS608握手 PS_HandShake
//参数: PS_Addr地址指针
//说明: 模块返新地址(正确地址)
uint8_t PS_HandShake(uint32_t *PS_Addr)
{
SendHead();
SendAddr();
Com_SendData(0X01);
Com_SendData(0X00);
Com_SendData(0X00);
Delay_ms(200);
if(RX_len)
{
RX_len=0;
if(//判断是不是模块返回的应答包
aRxBuffer[0]==0XEF
&&aRxBuffer[1]==0X01
&&aRxBuffer[6]==0X07
)
{
*PS_Addr=(aRxBuffer[2]<<24) + (aRxBuffer[3]<<16)
+(aRxBuffer[4]<<8) + (aRxBuffer[5]);
return 0;
}
}
return 1;
}
//模块应答包确认码信息解析
//功能:解析确认码错误信息返回信息
//参数: ensure
//返回值:解析出来的字符串地址
const char *EnsureMessage(uint8_t ensure)
{
const char *p;
switch(ensure)
{
case 0x00:
p="OK";break;
case 0x01:
p="数据包接收错误";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="缓冲区内没有有效原始图而生不成图像";break;
case 0x18:
p="读写 FLASH 出错";break;
case 0x19:
p="未定义错误";break;
case 0x1a:
p="无效寄存器号";break;
case 0x1b:
p="寄存器设定内容错误";break;
case 0x1c:
p="记事本页码指定错误";break;
case 0x1f:
p="指纹库满";break;
case 0x20:
p="地址错误";break;
default :
p="模块返回确认码有误";break;
}
return p;
}
接着看一下我对一些上层功能的实现进行封装的程序:
//在指定位置存储指纹模板
void Add_FR(uint16_t pageid)
{
uint8_t i=0,ensure,processnum=0; //i:计数变量用来进行超时计数,ensure:确认码接收,processnum:执行步骤计数用来判断步骤执行位置
uint16_t PageID; //PageID;指纹库ID号
while(1)
{
while(PS_HandShake(&AS608Addr))
{
Delay_ms(1000);
}
Delay_ms(1000);
switch(processnum)
{
case 0:
i++;
lcd_show_srting_or_chinese16(1,1,Red,White,"请放入手指__");
ensure = PS_GetImage();
if(ensure == 0x00) //录入图像成功
{
ensure = PS_GenChar(CharBuffer1);
if(ensure == 0x00) //生成特征成功
{
i=0;processnum=1;
}
}
break;
case 1:
i++;
ensure = PS_GetImage();
if(ensure == 0x00) //录入图像成功
{
ensure = PS_GenChar(CharBuffer2);
if(ensure == 0x00) //生成特征成功
{
i=0;processnum=2;
}
}
break;
case 2:
ensure = PS_Match();
if(ensure == 0x00) //比对两枚指纹特征成功
{
processnum = 3;
}
else
{
i=0;processnum = 0;
}
Delay_ms(1000);
break;
case 3:
ensure = PS_RegModel(); //生成指纹模板成功
if(ensure == 0x00)
{
processnum = 4;
}
else{processnum = 0;}
Delay_ms(1000);
break;
case 4:
PageID = pageid;
ensure = PS_StoreChar(CharBuffer2,PageID);
if(ensure == 0x00) //储存指纹模板成功
{
lcd_show_srting_or_chinese16(1,1,Red,White,"指纹存入成功");
Delay_ms(1500);
return ;
}
else{processnum = 0;}
break;
}
Delay_ms(800);
if(i == 10)
{
lcd_show_srting_or_chinese16(1,1,Red,White,"指纹存入失败");
break;
}
}
}
//验证指纹
void Press_FR(void)
{
SearchResult seach;
uint8_t ensure;
lcd_show_srting_or_chinese16(1, 1, Red,White,"请放入手指__");
ensure=PS_GetImage();
if(ensure==0x00)//获取图像成功
{
ensure=PS_GenChar(CharBuffer1);
if(ensure==0x00) //生成特征成功
{
ensure=PS_HighSpeedSearch(CharBuffer1,0,300,&seach);
if(ensure==0x00)//搜索成功
{
if(seach.MatchScore>100)
{
lcd_show_srting_or_chinese16(1, 1, Red,White,"指纹验证成功");
Delay_ms(5000);
}else
{
lcd_show_srting_or_chinese16(1, 1, Red,White,"指纹验证失败");
Delay_ms(5000);
}
}else
{
lcd_show_srting_or_chinese16(1, 1, Red,White,"指纹验证失败");
Delay_ms(5000);
}
}
}
}
//删除指定位置的指纹模板
void Delete_FR(uint16_t pageid)
{
uint8_t ensure;
uint16_t PageID;
PageID = pageid;
ensure =PS_DelectChar(PageID,1);
if(ensure == 0x00)
{
lcd_show_srting_or_chinese16(1, 1, Red,White,"删除指纹成功");
}
else
{
lcd_show_srting_or_chinese16(1, 1, Red,White,"删除指纹失败");
}
}
//清空指纹模板库
void Empty_FR(void)
{
uint8_t ensure;
ensure = PS_Empty();
if(ensure == 0x00)
{
lcd_show_srting_or_chinese16(1, 1, Red,White,"清空指纹成功");
}
else
{
lcd_show_srting_or_chinese16(1, 1, Red,White,"清空指纹成功");
}
}
可见包括啦在指定位置存储指纹模板,验证指纹,删除指定位置指纹模板,清空指纹模板等功能,当然若需要再实现其他功能可以进行自行封装。
3.在使用AS608指纹模块时的一些常见问题的解决和一些重要的注意事项
(1)指纹模块与单片机或者上位机通信不成功:首先一定要检查硬件接线,防止Tx和Rx接反,然后串口通信的配置一定要一样特别注意波特率的配置。
(2)握手不成功:握手不成功很大程度上也是通信不成功的原因,可能是配置问题,接线问题,指令包发错问题以及应答包解析错误问题
(3)串口接收多字节数据:我们采用的是利用串口的空闲中断来进行对应答包的多字节接收
更多推荐



所有评论(0)