门锁系统——指纹识别

接上篇2.门锁系统——屏幕显示_only_print的博客-CSDN博客

这一篇我们学习使用指纹模块来完成开锁。

目录

先来认识一下指纹模块——AS608

下边开始CobeMX设置

下来进行程序设计

格式函数的实现:

所有的指令函数代码如下:

这里贴出最终使用的函数:

贴上as608.h文件中的代码:

指纹操作部分代码:


先来认识一下指纹模块——AS608

这是用户手册给出的技术说明,这里面重要的是通讯方式为串口通讯,模块上自带存储空间,可以存储200个指纹,还有默认通讯的波特率为57600(这个后期可以自己修改,但是没必要,改了通讯可能出问题)。

接下来从外边认识一下:

这是它的一共8个引脚,这里有用的就是前6个,第5,6个引脚是用来在低功耗时使用的,这里因为我是插电使用的,所以不需要低功耗(不想多写代码)。所以我这里使用的就是前4个引脚。前四个就很简单了:

  1. VCC
  2. Tx(接开发板的Rx,我的开发板是PC11)
  3. Rx(接开发板的Tx,我的开发板是PC10)
  4. GND

按这样的接法接上线。

下边开始CobeMX设置

这里需要打开串口3,并开启中断,设置波特率为57600。具体配置如图:

完成后再开启串口1(用来与电脑连接,输出一些测试内容),如果不想与电脑连接也可以使用LCD输出,但是代码改动太多,这里就直接使用串口输出了,即使这里不使用,后边也得需要串口,所以这里干脆就不改了。

然后回到freertos一栏创建指纹对应的任务(具体的优先级配置如图):

到这里CobeMX的设置就全部完成了。

下来进行程序设计

这部分还是和之前一样先创建对应的文件夹(as608.c和as608.h),创建完成后需要先完成单片机通过串口3和指纹模块的通信。因为通信的数据量是不固定的,所以这里需要实现串口的不定项数据传输,这里使用串口空闲中断判断,在中断函数文件(stm32f1xx_it.c)中找到串口3的中断服务函数,在其中添加空闲中断的判断:

void USART3_IRQHandler(void)

{

  /* USER CODE BEGIN USART3_IRQn 0 */

       //串口接收不定长数据

              //判断是否为空闲中断,如果是就认为接收数据完成      

       if(__HAL_UART_GET_FLAG(&AS608_UART,UART_FLAG_IDLE) != RESET)

       {

              //认为数据接收完成,进行处理

              //1、清除空闲中断

              __HAL_UART_CLEAR_IDLEFLAG(&AS608_UART);

             

              //2、获取接收大小



              //3、清空接收状态



              AS608_UART.RxXferCount = sizeof(USART3_RX_BUF);

              AS608_UART.pRxBuffPtr = USART3_RX_BUF;

              USART3_RX_STA = 1;//接收数据完成

              return ; 

       }

  /* USER CODE END USART3_IRQn 0 */

  HAL_UART_IRQHandler(&huart3);

  /* USER CODE BEGIN USART3_IRQn 1 */



  /* USER CODE END USART3_IRQn 1 */

}

这部分需要一些宏定义,我们在刚才创建的as608.h和as608.c中定义,这部分等下再贴出。

现在可以实现指纹的识别功能了,这其实厂商给我们提供了模板,只要按照他的模板就可以完成函数的编写:

这是厂商给出的数据包格式,我们需要按照它的格式书写所有的函数,所以我们先得实现这些格式的函数。

格式函数的实现:

//串口发送一个字节

static uint8_t MYUSART_SendData(uint8_t data)

{

       if(HAL_UART_Transmit(&AS608_UART,&data,1,0xff) == HAL_OK)

              return 0;

       return 1;

}

//发送包头

static void SendHead(void)

{

       memset(USART3_RX_BUF,0,sizeof(USART3_RX_BUF));//发送前清空数据,因为所有都要发送包头,所以只需要在发送包头前清空即可

  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);

}

这些函数实现完成后,就可以完成各个部分函数的代码了,这些函数厂商也提供了模板:

以第一个为例:

我们只需要按照他的结构使用之前创建的格式函数就可以完成函数的实现。

所有的指令函数代码如下:

/*****************************************

函数名:uint8_t AS608_Check(void)

参数:无

功能描述:模块是否连接检测

返回值:模块连接了返回0 否则返回1

*****************************************/

static uint8_t AS608_Check(void)

{

       USART3_RX_BUF[9] = 1;

      

  SendHead();

  SendAddr();

       for(int i = 0; i < 10; i++)

       {

              MYUSART_SendData(Get_Device_Code[i]);

       }

       //HAL_UART_Receive(&AS608_UART,USART3_RX_BUF,12,100);//串口三接收12个数据

       HAL_Delay(200);//等待200ms

       if(USART3_RX_BUF[9] == 0)

              return 0;



  return 1;

}

/*指纹模块初始化*/

uint8_t as608_init(void)

{

       //设置uart3接收中断

  HAL_UART_Receive_IT(&AS608_UART,USART3_RX_BUF,sizeof( USART3_RX_BUF));//接收数据,且产生中断

       //使能空闲中断

       __HAL_UART_ENABLE_IT(&AS608_UART,UART_IT_IDLE);//

      

       return AS608_Check();

}

//判断中断接收的数组有没有应答包

//waittime为等待中断接收数据的时间(单位1ms)

//返回值:数据包首地址

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';

  USART3_RX_STA = 0;

  while(--waittime)

  {

    HAL_Delay(1);

    if(USART3_RX_STA) //接收到一次数据

    {

      USART3_RX_STA = 0;

      data = strstr((const char*)USART3_RX_BUF, (const char*)str);

      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);

  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 中的特征文件

//模块返回确认字

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

//说明:  模块返回确认字,页码(相配指纹模板)

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];

  }

  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);

  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];

  else

    ensure = 0xff;

  return ensure;

}

//删除模板 PS_DeletChar

//功能:  删除flash数据库中指定ID号开始的N个指纹模板

//参数:  PageID(指纹库模板号),N删除的模板个数。

//说明:  模块返回确认字

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];

  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);

  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)

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];

  }

  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

//说明:  模块返回确认字

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];

  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个字节)

//说明:  模块返回确认字

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];

  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);

  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(页数)

//说明:  模块返回确认字+页码(相配指纹模板)

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];

  }

  else

    ensure = 0xff;

  return ensure;

}

//读有效模板个数 PS_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;



  if(ensure == 0x00)

  {

    printf("\r\n有效指纹个数=%d", (data[10] << 8) + data[11]);

  }

  else

    printf("\r\n%s", EnsureMessage(ensure));

  return ensure;

}

//与AS608握手 PS_HandShake

//参数: PS_Addr地址指针

//说明: 模块返新地址(正确地址)

uint8_t PS_HandShake(uint32_t *PS_Addr)

{

  SendHead();

  SendAddr();

  MYUSART_SendData(0X01);

  MYUSART_SendData(0X00);

  MYUSART_SendData(0X00);

  HAL_Delay(200);

  if(USART3_RX_STA & 0X8000) //接收到数据

  {

    if(//判断是不是模块返回的应答包

      USART3_RX_BUF[0] == 0XEF

      && USART3_RX_BUF[1] == 0X01

      && USART3_RX_BUF[6] == 0X07

    )

    {

      *PS_Addr = (USART3_RX_BUF[2] << 24) + (USART3_RX_BUF[3] << 16)

                 + (USART3_RX_BUF[4] << 8) + (USART3_RX_BUF[5]);

      USART3_RX_STA = 0;

      return 0;

    }

    USART3_RX_STA = 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 ShowErrMessage(uint8_t ensure)

{

  //OLED_ShowCH(5,0,(uint8_t*)EnsureMessage(ensure));

       printf("%s\r\n",EnsureMessage(ensure));

}

后面真正实现的函数就是利用上边的函数进行实现的,具体实现过程就是上边函数的组合。

这里贴出最终使用的函数:

//录指纹

void Add_FR(uint8_t ID_NUM)

{

  uint8_t i, ensure, processnum = 0;

  while(1)

  {

    switch (processnum)

    {

    case 0:

      i++;

             

                     printf("请按手指\r\n");

      ensure = PS_GetImage();

      if(ensure == 0x00)

      {

        ensure = PS_GenChar(CharBuffer1); //生成特征

        if(ensure == 0x00)

        {

                                   printf("指纹正常\r\n");

          i = 0;

          processnum = 1; //跳到第二步

        }

        else ShowErrMessage(ensure);

      }

      else ShowErrMessage(ensure);

      break;



    case 1:

      i++;

                printf("请再按一次\r\n");

      ensure = PS_GetImage();

      if(ensure == 0x00)

      {

        ensure = PS_GenChar(CharBuffer2); //生成特征

        if(ensure == 0x00)

        {

                                   printf("指纹正常\r\n");

          i = 0;

          processnum = 2; //跳到第三步

        }

        else ShowErrMessage(ensure);

      }

      else ShowErrMessage(ensure);

      break;



    case 2:

                printf("对比两次指纹\r\n");

      ensure = PS_Match();

      if(ensure == 0x00)

      {

                            printf("对比成功\r\n");

        processnum = 3; //跳到第四步

      }

      else

      {

                            printf("对比失败\r\n");

        ShowErrMessage(ensure);

        i = 0;

        processnum = 0; //跳回第一步

      }

      HAL_Delay(500);

      break;



    case 3:

                printf("生成指纹模板\r\n");

      HAL_Delay(500);

      ensure = PS_RegModel();

      if(ensure == 0x00)

      {

                            printf("生成指纹模板成功\r\n");

        processnum = 4; //跳到第五步

      }

      else

      {

        processnum = 0;

        ShowErrMessage(ensure);

      }

      HAL_Delay(1000);

      break;



    case 4:

                     printf("默认选择ID为1 \r\n");

              ID_NUM = 1;

              #if 0

      while(key_num != 3)

      {

        key_num = KEY_Scan(0);

        if(key_num == 2)

        {

          key_num = 0;

          if(ID_NUM > 0)

            ID_NUM--;

        }

        if(key_num == 4)

        {

          key_num = 0;

          if(ID_NUM < 99)

            ID_NUM++;

        }

        OLED_ShowCH(40, 6, "ID=");

        OLED_ShowNum(65, 6, ID_NUM, 2, 1);

      }

             

      key_num = 0;

                     #endif

      ensure = PS_StoreChar(CharBuffer2, ID_NUM); //储存模板

      if(ensure == 0x00)

      {

                            printf("录入指纹成功\r\n");

        HAL_Delay(1500);

        return ;

      }

      else

      {

        processnum = 0;

        ShowErrMessage(ensure);

      }

      break;

    }

    HAL_Delay(400);

    if(i == 10) //超过5次没有按手指则退出

    {

      break;

    }

  }

}



SysPara AS608Para;//指纹模块AS608参数

//刷指纹

void press_FR(void)

{

  SearchResult seach;

  uint8_t ensure;

  char str[20];

  while(1)

  {

    //key_num = KEY_Scan(0);

    ensure = PS_GetImage();

    if(ensure == 0x00) //获取图像成功

    {

      ensure = PS_GenChar(CharBuffer1);

      if(ensure == 0x00) //生成特征成功

      {

        ensure = PS_HighSpeedSearch(CharBuffer1, 0, 99, &seach);

        if(ensure == 0x00) //搜索成功

        {

                                   printf("指纹验证成功");

          sprintf(str, " ID:%d 得分:%d ", seach.pageID, seach.mathscore);

                                   printf("%s\r\n",str);

          HAL_Delay(500);

        }

        else

        {

                                   printf("验证失败\r\n");

          HAL_Delay(500);

        }

      }

      else

                     {};

                     printf("请按手指\r\n");

    }

  }

}



//删除单个指纹

void Del_FR(uint8_t ID_NUM)

{

  uint8_t  ensure;

       printf("单个删除指纹开始");

  ensure = PS_DeletChar(ID_NUM, 1); //删除单个指纹

  if(ensure == 0)

  {

              printf("删除指纹成功 \r\n");

  }

  else

    ShowErrMessage(ensure);

  HAL_Delay(1500);



}

/*清空指纹库*/

void Del_FR_Lib(void)

{

       uint8_t  ensure;

       printf("删除指纹库开始\r\n");

  ensure = PS_Empty(); //清空指纹库

  if(ensure == 0)

  {

              printf("清空指纹库成功\r\n");

  }

  else

     ShowErrMessage(ensure);

  HAL_Delay(1500);

}

这样就完成了整个函数的开发,在这里添加这个函数的头部定义的变量:

/*串口接收中断处理在stm32f1xx_it.c里面*/



uint32_t AS608Addr = 0XFFFFFFFF;//默认



char str2[6] = {0};



uint8_t USART3_RX_BUF[USART3_MAX_RECV_LEN];                          //接收缓冲,最大USART3_MAX_RECV_LEN个字节.



uint8_t Get_Device_Code[10] ={0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x00,0x1b};//口令验证



uint8_t USART3_RX_STA= 0;//串口是否接收到数据

贴上as608.h文件中的代码:

#ifndef __AS608_H

#define __AS608_H



#include "stm32f1xx_hal.h"

#include "main.h"



#define CharBuffer1 0x01

#define CharBuffer2 0x02



#define USART3_MAX_RECV_LEN        400                             //最大接收缓存字节数



#define AS608_UART     huart3//AS608模块所使用的串口



extern uint8_t USART3_RX_BUF[USART3_MAX_RECV_LEN];



extern uint8_t USART3_RX_STA;



extern uint32_t AS608Addr;//模块地址



typedef struct 

{

       uint16_t pageID;//指纹ID

       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;//波特率基数N

}SysPara;





uint8_t as608_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); //与AS608模块握手



const char *EnsureMessage(uint8_t ensure);//确认码错误信息解析

//录指纹

void Add_FR(uint8_t ID_NUM);



void press_FR(void);



//删除单个指纹

void Del_FR(uint8_t ID_NUM);



void Del_FR_Lib(void);



#endif

完成了这部分后,我们就可以实现之前屏幕部分设置的KEY2所对应的指纹设置了。

这部分函数在之前设置的bsp_lcd.c中定义,现在只是更改其中的代码。

指纹操作部分代码:

// 指纹设置

void Finger_Set(void)

{

       LCD_Fill(0, 0, 280, 100, WHITE);

       // 查看指纹

       LCD_ShowString(10,0, 240,16,16,(uint8_t*)"[1] View the fingerprint");

       // 删除指纹

       LCD_ShowString(10,20,240,16,16, (uint8_t*)"[2] Delete the fingerprint");

       // 添加指纹

       LCD_ShowString(10,40,240,16,16, (uint8_t*)"[3] Add a fingerprint");

       // 重置指纹

       LCD_ShowString(10,60, 240,16,16,(uint8_t*)"[4] Reset the fingerprint");

       uint16_t *ValidN = 0;  // 指纹个数

       uint8_t num = 0;

       uint8_t i = 1;

       HAL_Delay(1000);

       while(i)

       {

              curKey=ScanKeys(KEY_WAIT_ALWAYS);

              switch(curKey)

              {

                     case  KEY0:

                            break;

                     case       KEY1:// 查看指纹

                     {

                            printf("查看指纹");

                            PS_ValidTempleteNum(ValidN);

                            i = 0;

                            break;

                     }

                     case       KEY2:// 删除指纹

                     {

                            printf("删除指纹");

                            while(i)

                            {

                                   num = Touch_Num();

                                   if(num != 0)

                                   {

                                          Del_FR(num);

                                          i = 0;

                                          break;

                                   }

                            }

                            break;

                     }

                     case       KEY3:// 添加指纹

                     {

                            printf("添加指纹");

                            while(i)

                            {

                                   num = Touch_Num();

                                   if(num != 0)

                                   {

                                          Add_FR(num);

                                          i = 0;

                                          break;

                                   }

                            }

                            break;

                     }

                     case       KEY4:// 重置指纹

                     {

                            printf("重置指纹");

                            Del_FR_Lib();

                            i = 0;

                            break;

                     }

              }//end switch     

       }

}

这样就完成了整个部分的开发。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值