GD32F470_AS608光学指纹识别模块 指纹采集/STM32 51单片机模块移植

news2024/11/20 11:16:21

2.7 指纹识别传感器
光学指纹识别传感器采用了国内著名指纹识别芯片公司杭州晟元芯片技术有限公司(Synochip) 的 AS608 指纹识别芯片。芯片内置 DSP 运算单元,集成了指纹识别算法,能高效快速采集 图像并识别指纹特征。模块配备了串口、USB 通讯接口,用户无需研究复杂的图像处理及及指纹识别算法,只需通过简单的串口、USB 按照通讯协议便可控制模块。本模块可应用于各种考勤机、保险箱柜、指纹门禁系统、指纹锁等场合。

2.7.1 模块来源
采购链接:
AS608光学指纹识别模块 指纹采集/STM32 51单片机
资料下载链接:
https://pan.baidu.com/s/1mCDdiU5nwtooxmHiPfYTFA
资料提取码:kj8o

2.7.2 规格参数
工作电压:3.0-3.6V
工作电流:30~60mA
指纹存容量:300 枚(ID:0~299)
认假率:<0.001%
搜索时间:<0.3(S)
控制方式:串口或USB
管脚数量:8 Pin(2.54mm间距排针)
工作电流:30~60mA
指纹存容量:300 枚(ID:0~299)
认假率:<0.001%
搜索时间:<0.3(S)
控制方式:串口或USB
管脚数量:8 Pin(2.54mm间距排针)

2.7.3 移植过程
我们的目标是在梁山派GD32F470上能够实现添加指纹、删除指纹和搜索指纹的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
2.7.3.1 查看资料
系统内设有一个72K字节的图像缓冲区与二个512bytes大小的特征文件缓冲区,名字分别称为:lmageBuffer,CharBuffer1和CharBuffer2。用户可以通过指令读写任意一个缓冲区。CharBufferl或 CharBuffer2既可以用于存放普通特征文件也可以用于存放模板特征文件。通过UART 口上传或下载图像时为了加快速度,只用到像素字节的高4位,即将两个像素合成一个字节传送。通过USB口则是整8位像素。
指纹库容量根据挂接的FLASH容量不同而改变,系统会自动判别。指纹模板按照序号存放,序号定义为:0—(N-1)(N为指纹库容量)。用户只能根据序号访问指纹库内容。
这里我们使用的是串口控制方式,USB的接口我们可以悬空不接。
在这里插入图片描述
1脚(红线):模块主电源,接3.3V供电(请勿接3.3V以上电源,否则烧毁模块!);
2脚(黄线):模块串口TX(发送端),接MCU或TTL串口的RX(接收端);
3脚(白线):模块串口RX(接收端),接MCU或TTL串口的TX(发送端);
4脚(黑线):模块电源地,接3.3V电源地(负极);
5脚(蓝线):模块触摸感应信号输出(高电平为检测到触摸),需接VTI到3.3V。
6脚(绿线):模块触摸感应电路电源(3.3V),可以与1脚(红线)并接。
7脚,8脚为USB信号线,使用串口控制模块时可以悬空不用。

2.7.3.2 引脚选择
想要使用串口,需要确定使用的引脚是否有串口外设功能。可以通过数据手册【GD32F450xx_Datasheet_Rev2.2.pdf】进行查看。文件下载见文件2.7.3.2-1 数据手册(GD32F450与GD32F470在功能与寄存器地址上没有区分)(梁山派开发板资料可在官网获取www.lckfb.com)

图2.7.3.2-1 数据手册来源
在数据手册的第28页结尾,是关于GD32F450Zx系列芯片引脚的功能定义示意图。
图2.7.3.2-2 引脚功能定义起始页
当前只有AO引脚需要使用到ADC接口,所以DO引脚可以使用开发板上其他的GPIO。这里选择使用PA2和PA3的附加串口1功能。在这里插入图片描述
在这里插入图片描述

指纹识别模块立创·梁山派
红线(3V3)3V3
黄线(TXD)PA3
白线(RXD)PA2
黑线(GND)黑线(GND)
蓝线(WAK)PC2
绿线(VTI)绿线(VTI)

在这里插入图片描述
2.7.3.3 移植至工程
移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为bsp_as608.c与bsp_as608.h。见2.2.3.3 移植至工程。这里不再过多讲述。移植完成后面修改相关代码。
在文件bsp_as608.c中,编写如下代码。

#include "bsp_as608.h"
#include "stdio.h"
#include "bsp_usart.h"
#include "string.h"

volatile unsigned char FPM10A_RECEICE_BUFFER[32];
unsigned int finger_id = 0;

const unsigned char FPM10A_Get_Device[10] ={0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x00,0x1b};//口令验证
const unsigned char FPM10A_Pack_Head[6] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF};  //协议包头
const unsigned char FPM10A_Get_Img[6] = {0x01,0x00,0x03,0x01,0x00,0x05};    //获得指纹图像
const unsigned char FPM10A_Get_Templete_Count[6] ={0x01,0x00,0x03,0x1D,0x00,0x21 }; //获得模版总数
const unsigned char FPM10A_Search[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x03,0xE7,0x00,0xF8}; //搜索指纹搜索范围0 - 999,使用BUFFER1中的特征码搜索
const unsigned char FPM10A_Search_0_9[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x00,0x13,0x00,0x21}; //搜索0-9号指纹
const unsigned char FPM10A_Img_To_Buffer1[7]={0x01,0x00,0x04,0x02,0x01,0x00,0x08}; //将图像放入到BUFFER1
const unsigned char FPM10A_Img_To_Buffer2[7]={0x01,0x00,0x04,0x02,0x02,0x00,0x09}; //将图像放入到BUFFER2
const unsigned char FPM10A_Reg_Model[6]={0x01,0x00,0x03,0x05,0x00,0x09}; //将BUFFER1跟BUFFER2合成特征模版
const unsigned char FPM10A_Delete_All_Model[6]={0x01,0x00,0x03,0x0d,0x00,0x11};//删除指纹模块里所有的模版
volatile unsigned char  FPM10A_Save_Finger[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0B,0x00,0x19};//将BUFFER1中的特征码存放到指定的位置


uint8_t         u2_recv_buff[USART_RECEIVE_LENGTH];   // 接收缓冲区
uint16_t         u2_recv_length = 0;                                          // 接收数据长度
uint8_t                u2_recv_flag = 0;                                           // 接收数据完成标志位

/******************************************************************
 * 函 数 名 称:as608_gpio_config
 * 函 数 说 明:初始化as608引脚
 * 函 数 形 参:设置波特率 as608的默认波特率是57600
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:as608的默认波特率是57600      
******************************************************************/
void as608_gpio_config(uint32_t band_rate)
{
        /* 开启时钟 */
        rcu_periph_clock_enable(BSP_AS608_TX_RCU);   // 开启串口时钟
        rcu_periph_clock_enable(BSP_AS608_RX_RCU);   // 开启端口时钟
        rcu_periph_clock_enable(BSP_AS608_RCU);      // 开启端口时钟
        
    rcu_periph_clock_enable(RCU_GPIOC);   // 开启端口时钟    
        gpio_mode_set(GPIOC,GPIO_MODE_INPUT,GPIO_PUPD_NONE,GPIO_PIN_2);
    
        /* 配置GPIO复用功能 */
    gpio_af_set(BSP_AS608_TX_PORT,BSP_AS608_AF,BSP_AS608_TX_PIN);        
        gpio_af_set(BSP_AS608_RX_PORT,BSP_AS608_AF,BSP_AS608_RX_PIN);        
        
        /* 配置GPIO的模式 */
        /* 配置TX为复用模式 上拉模式 */
        gpio_mode_set(BSP_AS608_TX_PORT,GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_AS608_TX_PIN);
        /* 配置RX为复用模式 上拉模式 */
        gpio_mode_set(BSP_AS608_RX_PORT, GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_AS608_RX_PIN);
        
        /* 配置TX为推挽输出 50MHZ */
        gpio_output_options_set(BSP_AS608_TX_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,BSP_AS608_TX_PIN);
        /* 配置RX为推挽输出 50MHZ */
        gpio_output_options_set(BSP_AS608_RX_PORT,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, BSP_AS608_RX_PIN);

        /* 配置串口的参数 */
        usart_deinit(BSP_AS608);                                 // 复位串口
        usart_baudrate_set(BSP_AS608,band_rate);                 // 设置波特率
        usart_parity_config(BSP_AS608,USART_PM_NONE);            // 没有校验位
        usart_word_length_set(BSP_AS608,USART_WL_8BIT);          // 8位数据位
        usart_stop_bit_set(BSP_AS608,USART_STB_1BIT);                              // 1位停止位

  /* 使能串口 */
        usart_enable(BSP_AS608);                                 // 使能串口
        usart_transmit_config(BSP_AS608,USART_TRANSMIT_ENABLE);  // 使能串口发送
        usart_receive_config(BSP_AS608,USART_RECEIVE_ENABLE);    // 使能串口接收
        
        /* 中断配置 */
        nvic_irq_enable(BSP_AS608_IRQ, 2, 2);                                          // 配置中断优先级
        usart_interrupt_enable(BSP_AS608,USART_INT_RBNE);                 // 读数据缓冲区非空中断和溢出错误中断
        usart_interrupt_enable(BSP_AS608,USART_INT_IDLE);                 // 空闲检测中断
}

/************************************************
函数名称 : uart_send_byte
功    能 : 串口发送一个字节
参    数 : ucch:要发送的字节
返 回 值 : 
作    者 : LC
*************************************************/
void uart_send_byte(uint8_t ucch)
{
        usart_data_transmit(BSP_AS608,(uint8_t)ucch);                                                         // 发送数据
        while(RESET == usart_flag_get(BSP_AS608,USART_FLAG_TBE));  // 等待发送数据缓冲区标志置位
}

/************************************************
函数名称 : uart_receive_clear
功    能 : 清除串口接收的全部数据
参    数 : 无
返 回 值 : 无
作    者 : LC
*************************************************/
void  uart_receive_clear(void)
{
    unsigned int i = 0;
    for( i = 0; i < USART_RECEIVE_LENGTH; i++ )
    {
        u2_recv_buff[ i ] = 0;
    }
    u2_recv_length = 0;
}

/******************************************************************
 * 函 数 名 称:get_as608_touch
 * 函 数 说 明:获取是否有手指触摸识别区
 * 函 数 形 参:无
 * 函 数 返 回:0没有触摸    1有触摸
 * 作       者:LC
 * 备       注:无
******************************************************************/
char get_as608_touch(void)
{
    if( TOUCH_IN == 1 )//触摸为1
    {
//        printf("1\r\n");   
        return 1;        
    }   
    return 0;
}

/******************************************************************
 * 函 数 名 称:FPM10A_Cmd_Send_Pack_Head
 * 函 数 说 明:发送包头
 * 函 数 形 参:无
 * 函 数 返 回:wu
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Cmd_Send_Pack_Head(void)
{
        int i;        
        for(i=0;i<6;i++) //包头
   {
     uart_send_byte(FPM10A_Pack_Head[i]);   
    }                
}
/******************************************************************
 * 函 数 名 称:FPM10A_Cmd_Check
 * 函 数 说 明:发送指令
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Cmd_Check(void)
{
        int i=0;
        FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头
        for(i=0;i<10;i++)
         {                
                uart_send_byte(FPM10A_Get_Device[i]);
          }
}
/******************************************************************
 * 函 数 名 称:FPM10A_Receive_Data
 * 函 数 说 明:接收反馈数据缓冲
 * 函 数 形 参:ucLength 接收长度
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Receive_Data(unsigned char ucLength)
{
  unsigned char i = 0;
  unsigned int timeout = 1000;//超时时间,单位Ms
  //等待数据接收完毕
  while(u2_recv_flag==0 && timeout > 0 )
  {
      delay_1ms(1);
      timeout--; 
  }
    
  if( u2_recv_flag == 1 )
  {
      u2_recv_flag = 0;
      for (i=0;i<ucLength;i++)
      {
        FPM10A_RECEICE_BUFFER[i] = u2_recv_buff[i];
      }
      uart_receive_clear();
  }
  else
  {
      //Error, no data received
  }

}
/******************************************************************
 * 函 数 名 称:FPM10A_Cmd_Get_Img
 * 函 数 说 明:获得指纹图像命令
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Cmd_Get_Img(void)
{
    unsigned char i;
    FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头
    for(i=0;i<6;i++) //发送命令 0x1d
        {
       uart_send_byte(FPM10A_Get_Img[i]);
        }
}
/******************************************************************
 * 函 数 名 称:FINGERPRINT_Cmd_Img_To_Buffer1
 * 函 数 说 明:将图像转换成特征码存放在Buffer1中
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FINGERPRINT_Cmd_Img_To_Buffer1(void)
{
         unsigned char i;
        FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头      
           for(i=0;i<7;i++)   //发送命令 将图像转换成 特征码 存放在 CHAR_buffer1
     {
      uart_send_byte(FPM10A_Img_To_Buffer1[i]);
             }
}
/******************************************************************
 * 函 数 名 称:FINGERPRINT_Cmd_Img_To_Buffer2
 * 函 数 说 明:将图像转换成特征码存放在Buffer2中
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FINGERPRINT_Cmd_Img_To_Buffer2(void)
{
     unsigned char i;
     for(i=0;i<6;i++)    //发送包头
         {
            uart_send_byte(FPM10A_Pack_Head[i]);   
            }
     for(i=0;i<7;i++)   //发送命令 将图像转换成 特征码 存放在 CHAR_buffer1
     { 
              uart_send_byte(FPM10A_Img_To_Buffer2[i]);
            }
}
/******************************************************************
 * 函 数 名 称:FPM10A_Cmd_Search_Finger
 * 函 数 说 明:搜索全部用户999枚
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Cmd_Search_Finger(void)
{
    unsigned char i;                       
    FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头
    for(i=0;i<11;i++)
    {
        uart_send_byte(FPM10A_Search[i]);   
    }
}
/******************************************************************
 * 函 数 名 称:FPM10A_Cmd_Reg_Model
 * 函 数 说 明:将BUFFER1跟BUFFER2合成特征模版
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Cmd_Reg_Model(void)
{
    unsigned char i;           
    FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头
    for(i=0;i<6;i++)
    {
        uart_send_byte(FPM10A_Reg_Model[i]);   
    }
}
/******************************************************************
 * 函 数 名 称:FINGERPRINT_Cmd_Delete_All_Model
 * 函 数 说 明:删除指纹模块里的所有指纹模版
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FINGERPRINT_Cmd_Delete_All_Model(void)
{
     unsigned char i;    
    for(i=0;i<6;i++) //包头
    {
      uart_send_byte(FPM10A_Pack_Head[i]);
    }
    for(i=0;i<6;i++) //命令合并指纹模版
        {
      uart_send_byte(FPM10A_Delete_All_Model[i]);   
        }        
}
/******************************************************************
 * 函 数 名 称:FPM10A_Cmd_Save_Finger
 * 函 数 说 明:保存指纹
 * 函 数 形 参:保存指纹的位置(ID号)
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Cmd_Save_Finger( unsigned int storeID )
{
    unsigned long temp = 0;
    unsigned char i;
    FPM10A_Save_Finger[5] =(storeID&0xFF00)>>8;
    FPM10A_Save_Finger[6] = (storeID&0x00FF);
    for(i=0;i<7;i++)   //计算校验和
    {
        temp = temp + FPM10A_Save_Finger[i]; 
    }
    FPM10A_Save_Finger[7]=(temp & 0x00FF00) >> 8; //存放校验数据
    FPM10A_Save_Finger[8]= temp & 0x0000FF;                   
    FPM10A_Cmd_Send_Pack_Head(); //发送通信协议包头        
    for(i=0;i<9;i++)  
    {
        //发送命令 将图像转换成 特征码 存放在 CHAR_buffer1
        uart_send_byte(FPM10A_Save_Finger[i]);      
    }
}
/******************************************************************
 * 函 数 名 称:key_scanf
 * 函 数 说 明:按键功能  确定-取消
 * 函 数 形 参:
 * 函 数 返 回:0=未动作  1=确定  2=取消 
 * 作       者:LC
 * 备       注:当前是使用串口来模拟按键,如果你有按键请自行修改
 *              修改要求:按下确定键时返回1;按下取消键时,返回2。
******************************************************************/
char key_scanf(void)
{
    /***************    你的代码    ***************/
    if(strstr( (const char*)g_recv_buff, "Yes") != NULL )
    {
        usart_receive_clear();
        return 1;//返回 确定键被按下
    }
    if(strstr( (const char*)g_recv_buff, "No") != NULL )
    { 
        usart_receive_clear();
        return 2;//返回 取消键被按下
    }        
     /***************    你的代码    ***************/
    
    return 0;
}


/******************************************************************
 * 函 数 名 称:FPM10A_Add_Fingerprint
 * 函 数 说 明:添加指纹
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Add_Fingerprint(void)
{
        unsigned char id_show[]={0,0,0};
    unsigned char key_num= key_scanf();
        finger_id=0;  

    printf("Do you want to add fingerprints? [Yes/No]\r\n");
        while( key_num != 2 )//按返回键直接回到主菜单
        {
        key_num= key_scanf();
        //按切换键指纹iD值加1
//        if(KEY_DOWN == 0)
//        {
//                while(KEY_DOWN==0);
//                if(finger_id == 1000)
//                {
//                        finger_id = 0;
//                }
//                else
//                finger_id = finger_id + 1;
//        }
//    printf("当前刷新的ID :  %d   \r\n", finger_id);

         //按确认键开始录入指纹信息                                          
         if( key_num == 1 )
         {        
          printf("start add\r\n");

           while( key_num != 2 )//按下返回键退出录入返回fingerID调整状态 
                   {
                key_num= key_scanf();
                                FPM10A_Cmd_Get_Img(); //获得指纹图像
                                FPM10A_Receive_Data(12);
                                //判断接收到的确认码,等于0指纹获取成功
                                if(FPM10A_RECEICE_BUFFER[9]==0)
                                {
                                        delay_1ms(100);
                                        FINGERPRINT_Cmd_Img_To_Buffer1();
                                    FPM10A_Receive_Data(12);
                    printf("成功进入\r\n");
                                        delay_1ms(1000);
                                        while( key_num != 2 )
                                        {
                         key_num= key_scanf();
                         FPM10A_Cmd_Get_Img(); //获得指纹图像
                         FPM10A_Receive_Data(12);
                        //判断接收到的确认码,等于0指纹获取成功
                        if(FPM10A_RECEICE_BUFFER[9]==0)
                        {
                            delay_1ms(200);
                            printf("ID = %d\r\n",finger_id); 
                            FINGERPRINT_Cmd_Img_To_Buffer2();
                            FPM10A_Receive_Data(12);
                            FPM10A_Cmd_Reg_Model();//转换成特征码
                            FPM10A_Receive_Data(12); 
                            //保存指纹
                            FPM10A_Cmd_Save_Finger(finger_id);                                         
                            FPM10A_Receive_Data(12);
                            delay_1ms(1000);
                            finger_id=finger_id+1;
                            break;
                        }
                    }
                                   
                                break;
                }
            }
        }
    }
}
/******************************************************************
 * 函 数 名 称:FPM10A_Find_Fingerprint
 * 函 数 说 明:搜索指纹
 * 函 数 形 参:无
 * 函 数 返 回:指纹ID号
 * 作       者:LC
 * 备       注:255:未查到  其他:查找到了
******************************************************************/
unsigned int FPM10A_Find_Fingerprint(void)
{          
        unsigned int find_fingerid = 255;
      
//    printf("Please put your finger in\r\n");
    
    if( get_as608_touch() == 1 )//有手指触摸识别区
    {
        FPM10A_Cmd_Get_Img(); //获得指纹图像
        FPM10A_Receive_Data(12);                
        //判断接收到的确认码,等于0指纹获取成功
        if(FPM10A_RECEICE_BUFFER[9]==0)
        {                        
            delay_1ms(100);
            FINGERPRINT_Cmd_Img_To_Buffer1();
            FPM10A_Receive_Data(12);                
            FPM10A_Cmd_Search_Finger();
            FPM10A_Receive_Data(16);                        
            if(FPM10A_RECEICE_BUFFER[9] == 0) //搜索成功 
            {
                //拼接指纹ID数
                find_fingerid = FPM10A_RECEICE_BUFFER[10]*256 + FPM10A_RECEICE_BUFFER[11];
                printf("ID = %d\r\n",find_fingerid);        
                delay_1ms(500);                                
            }
            else //没有找到
            {
                printf("not found\r\n");
            }
        }
    }
    return find_fingerid;
}
/******************************************************************
 * 函 数 名 称:FPM10A_Delete_All_Fingerprint
 * 函 数 说 明:删除所有存贮的指纹库
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void FPM10A_Delete_All_Fingerprint(void)
{
        unsigned char key_num=0;
    printf("Whether to delete fingerprint ?  [Yes/No]\r\n");
    do
    {
        key_num = key_scanf();
        if(key_num == 1 )//点击确定键
        {
            printf("deleting\r\n");
            delay_1ms(300);
            FINGERPRINT_Cmd_Delete_All_Model();
            FPM10A_Receive_Data(12); 
            printf("Have all been cleared\r\n");    
            break;
        }
        if( g_recv_complete_flag == 1 )
        {
            g_recv_complete_flag = 0;
            printf("rev = %s\r\n", g_recv_buff);
        }
     }while( key_num != 2 );//没有点击取消键,则继续循环
}

/******************************************************************
 * 函 数 名 称:Device_Check
 * 函 数 说 明:模块检查
 * 函 数 形 参:无
 * 函 数 返 回:0未检测到模块或者模块异常  1检测到模块并且通信成功
 * 作       者:LC
 * 备       注:返回0时要注意接线是否正确、串口配置是否可用
******************************************************************/
char Device_Check(void)
{
                unsigned char i=0;
                FPM10A_RECEICE_BUFFER[9]=1;                                           //串口数组第九位可判断是否通信正常

        FPM10A_Cmd_Check();                                                                        //单片机向指纹模块发送校对命令
                FPM10A_Receive_Data(12);                                                        //将串口接收到的数据转存
                 if(FPM10A_RECEICE_BUFFER[9] == 0)                                        //判断数据低第9位是否接收到0
                {
            return 1;
                }
        return 0;
}
/************************************************
函数名称 : BSP_AS608_IRQHandler
功    能 : 串口1接收中断服务函数
参    数 : 无
返 回 值 : 无
作    者 : LC
*************************************************/
void BSP_AS608_IRQHandler(void)
{
        if(usart_interrupt_flag_get(BSP_AS608,USART_INT_FLAG_RBNE) == SET)   // 接收缓冲区不为空
        {
                u2_recv_buff[u2_recv_length++] = usart_data_receive(BSP_AS608);      // 把接收到的数据放到缓冲区中
    }
        
        if(usart_interrupt_flag_get(BSP_AS608,USART_INT_FLAG_IDLE) == SET)   // 检测到帧中断
        {
                usart_data_receive(BSP_AS608);                                  // 必须要读,读出来的值不能要
                u2_recv_buff[u2_recv_length] = '\0';                                                // 数据接收完毕,数组结束标志
                u2_recv_flag = 1;                                          // 接收完成 
        }
        
}

在文件bsp_as608.h中,编写如下代码。

#ifndef _BSP_AS608_H_
#define _BSP_AS608_H_
 
#include "gd32f4xx.h"


#define BSP_AS608_TX_RCU  RCU_GPIOA   // 串口TX的端口时钟
#define BSP_AS608_RX_RCU  RCU_GPIOA   // 串口RX的端口时钟
#define BSP_AS608_RCU     RCU_USART1  // 串口1的时钟

#define BSP_AS608_TX_PORT GPIOA                                // 串口TX的端口
#define BSP_AS608_RX_PORT GPIOA                                // 串口RX的端口
#define BSP_AS608_AF           GPIO_AF_7   // 串口1的复用功能
#define BSP_AS608_TX_PIN  GPIO_PIN_2  // 串口TX的引脚
#define BSP_AS608_RX_PIN  GPIO_PIN_3 // 串口RX的引脚

#define BSP_AS608                                                 USART1                                                                      // 串口1
#define BSP_AS608_IRQ                     USART1_IRQn                                                                 // 串口1中断
#define BSP_AS608_IRQHandler  USART1_IRQHandler                                                // 串口1中断服务函数

#define TOUCH_IN    gpio_input_bit_get(GPIOC,GPIO_PIN_2)

/* 串口缓冲区的数据长度 */
#define USART_RECEIVE_LENGTH  4096

extern uint8_t  u2_recv_buff[USART_RECEIVE_LENGTH]; // 接收缓冲区
extern uint16_t u2_recv_length;                                                                                 // 接收数据长度
extern uint8_t  u2_recv_flag;                      // 接收完成标志位

void as608_gpio_config(uint32_t band_rate);
char get_as608_touch(void);
void  uart_receive_clear(void);

char Device_Check(void);
void FPM10A_Add_Fingerprint(void);//添加指纹
unsigned int FPM10A_Find_Fingerprint(void);//查找指纹
void FPM10A_Delete_All_Fingerprint(void);
#endif


2.7.4 移植验证
在自己工程中的main主函数中,编写如下。

/********************************************************************************
  * 文 件 名: main.c
  * 版 本 号: 初版
  * 修改作者: LC
  * 修改日期: 2023年04月06日
  * 功能介绍:          
  ******************************************************************************
  * 注意事项:
*********************************************************************************/

#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "bsp_as608.h"

int main(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组
    systick_config();                //滴答定时器初始化 1ms

    usart_gpio_config(57600U);
    as608_gpio_config(57600U);
    
    printf("AS608 demo start\r\n");
    
    Device_Check();//模块检测
    
    FPM10A_Delete_All_Fingerprint();  //是否删除全部指纹
    FPM10A_Add_Fingerprint();//是否添加指纹
    
    while(1)
    {
        FPM10A_Find_Fingerprint();//查找指纹

    }
}

移植现象:删除全部指纹->添加一个指纹->识别两次正确的指纹->识别3次错误的指纹。

在这里插入图片描述
移植成功示例,见文件2.7.4-1 。
文件2.7.4-1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1572755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Claude 3】This organization has been disabled.此组织已被禁用。(Claude无法对话的原因和解决办法)

Claude对话提示 This organization has been disabled.此组织已被禁用。 This organization has been disabled.此组织已被禁用。 This organization has been disabled.此组织已被禁用。 问题截图 问题原因 出现该页面&#xff0c;表示您的账户已经无法使用&#xff0c;可能…

Redis安装说明

Redis安装说明 大多数企业都是基于Linux服务器来部署项目&#xff0c;而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis. 此处选择的Linux版本为CentOS 7. Redis的官方网站地址&#xff1a;https://redis.io/ 1.单机安装Redis 1.1.…

99%的人不知道,Oracle resetlogs强制开库需要推进SCN?

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

IDEA2023创建SpringMVC项目

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 开发环境篇 ✨特色专栏&#xff1a; M…

1-32 异常

一 什么是异常? 1.含义:异与正常状态的显示,控制台显示的结果和预期的结果不一致 2.例如: int[] nums new int[2]; System.out.println(nums[2]); --抛出异常 二 异常分类 1.检测性异常:又称 非运行时异常,一般编写代码过程中编辑器直接报错 2.非检测性异常(常用):又称为…

[StartingPoint][Tier0]Preignition

Task 1 Directory Brute-forcing is a technique used to check a lot of paths on a web server to find hidden pages. Which is another name for this? (i) Local File Inclusion, (ii) dir busting, (iii) hash cracking. (目录暴力破解是一种用于检查 Web 服务器上的大…

【Python使用】嘿马头条完整开发md笔记第4篇:数据库,1 方案选择【附代码文档】

嘿马头条项目从到完整开发笔记总结完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;课程简介&#xff0c;ToutiaoWeb虚拟机使用说明1 产品介绍,2 原型图与UI图,3 技术架构,4 开发,1 需求,2 注意事项。数据库&#xff0c;理解ORM1 简介,2 安装,3 数据库连接…

MPLS基本转发过程,隧道特性、对TTL的处理、BGP路由黑洞

MPLS基本转发过程&#xff0c;隧道特性 标签操作类型包括标签压入&#xff08;Push&#xff09;、标签交换&#xff08;Swap&#xff09;和标签弹出&#xff08;Pop&#xff09;&#xff0c;它们是标签转发的基本动作。 倒数第二跳弹出特性PHP&#xff08;Penultimate Hop Popp…

并查集python实现及题目练习

文章目录 1. 并查集概念1.1 理解并查集&#xff1a;简介与应用场景1.2 Python 实现并查集及优化策略1.3 扁平化栈实现1.4 分析并查集的时间复杂度 2. 情侣牵手3. 相似字符串4. 岛屿数量 如果想了解并查集基础推荐去看左程云大神的算法讲解&#xff0c;非常不错&#xff0c;b站和…

InterlliJ Debug方式启动 method breakpoints may dramatically show down debugging

使用idea在DEBUG的时候出现Method breakpoints may dramatically slow down debugging&#xff0c; 如图&#xff1a; 根据语义可能是断点打在方法上面了&#xff0c;导致在某个断点卡住了。 重启服务器和重启idea已然无解。 打开Breakpoints面板看看&#xff0c;(快捷键&…

递归实现排列型枚举(acwing)

题目描述&#xff1a; 把 1∼n 这 n 个整数排成一行后随机打乱顺序&#xff0c;输出所有可能的次序。 输入格式&#xff1a; 一个整数 n。 输出格式&#xff1a; 按照从小到大的顺序输出所有方案&#xff0c;每行 1 个。 首先&#xff0c;同一行相邻两个数用一个空格隔开…

mac、windows 电脑安装使用多个版本的node

我们为啥要安装多个不同版本的node&#xff1f; 开发旧项目时&#xff0c;使用低版本Nodejs。开发新项目时&#xff0c;需使用高版本Node.js。可使用n同时安装多个版本Node.js&#xff0c;并切换到指定版本Node.js。 mac电脑安装 一、全局安装 npm install -g n 二、mac电脑…

淘宝优惠券领取软件叫什么?

草柴返利APP是一款淘宝优惠券领取软件。用户可以通过草柴淘宝优惠券领取软件轻松查找领取淘宝大额隐藏优惠券&#xff0c;领取成功后再购物可享受券后价优惠。同时&#xff0c;通过草柴APP领券购买成功&#xff0c;确认收货后再回到草柴APP提取购物返利&#xff0c;享受双重省钱…

idea maven 打包 内存溢出 报 GC overhead limit exceeded -> [Help 1]

idea 使用maven打包 报GC overhead limit exceeded -> [Help 1] 解决方法&#xff1a; 打开settings -> 点开如同所示 将 vm Options 参数 设为 -Xmx8g

记第一次eudsrc拿到RCE(下)

目录 前言 个人介绍 挖洞公式 漏洞介绍 信息泄露漏洞 任意文件读取漏洞 远程命令执行&#xff08;RCE&#xff09;漏洞 漏洞详情 漏洞点1 漏洞点2 漏洞点3 修复建议 总结 前言 免责声明 以下漏洞均已经上报漏洞平台。请勿利用文章内的相关技术从事非法测试。若因…

Autosar BswM 模式管理

EcuMs管理ECU上下电状态,BswM管理模式,协同工作。当使用EcuM - Fixed时,它将向BswM指示当前ECU状态 有了BswM,从图可以更加直观看出,BswM管理各个模块,每个模块独立,降低耦合。 BswM 的主要功能包括: 模式管理:BswM 可以管理和控制 ECU 的不同模式,例如正常模式、备…

AJAX 原理

一、AJAX原理 - XMLHttpRequest 定义&#xff1a; 关系&#xff1a;axios 内部采用 XMLHttpRequest 与服务器交互。 好处&#xff1a;掌握使用 XHR 与服务器进行数据交互&#xff0c;了解 axios 内部原理。 1.1 使用 XMLHttpRequest&#xff1a; 步骤&#xff1a; 1. 创建 XM…

免注册,ChatGPT可即时访问了!

AI又有啥进展&#xff1f;一起看看吧 Apple进军个人家用机器人 Apple在放弃自动驾驶汽车项目并推出混合现实头显后&#xff0c;正在进军个人机器人领域&#xff0c;处于开发家用环境机器人的早期阶段 报告中提到了两种可能的机器人设计。一种是移动机器人&#xff0c;可以跟…

【机器学习300问】60、图像分类任务中,训练数据不足会带来什么问题?如何缓解图像数据不足带来的问题?

在机器学习中&#xff0c;绝大部分模型都需要大量的数据进行训练和学习&#xff08;包括有监督学习和无监督学习&#xff09;&#xff0c;然而在实际应用中经常会遇到训练数据不足的问题。就比如图像分类这样的计算机视觉任务&#xff0c;确实依赖于大规模且多样化的训练数据以…

Java笔试总结

. 操作系统中关于竞争和死锁的关系下面描述正确的是&#xff1f; A 竞争一定会导致死锁 B 死锁一定由竞争引起 C 竞争可能引起死锁 D 预防死锁可以防止竞争 答案: C 进程的控制信息和描述信息存放在()。 A JCB B PCB C AFT D SFT 答案: B 当系统发生抖动&#xff08;thrash…