几年前,我们曾经在科幻电影中看到过的指纹传感器现在已经变得非常普遍,可以用于各种目的的身份验证。目前,我们在日常生活中到处都能看到基于指纹的系统,例如在办公室出席,在银行进行员工验证,在ATM上提取现金或存款,在政府办公室进行身份验证等。我们已经将其与Arduino和通过Raspberry Pi,今天我们将使指纹传感器与PIC微控制器接口。使用此PIC微控制器PIC16f877A指纹系统,我们可以在系统中注册新指纹,并可以删除已经送入的指纹。视频中显示了系统的完整工作情况 在文章末尾给出。
所需组件
- PIC16f877A单片机
- 指纹模组
- 按钮或键盘
- 16x2 LCD
- 1万锅
- 18.432000 MHz晶体振荡器
- 面包板或PCB(从JLCPCB订购)
- 跳线
- LED(可选)
- 电阻150 ohm -1 k ohm(可选)
- 5v电源
电路图和说明
在此 PIC单片机指纹传感器接口项目中,我们使用了4个按钮:这些按钮用于多功能。密钥1用于在系统中存储或删除指纹时匹配指纹并增加指纹ID。密钥2用于在系统中存储或删除指纹时注册新指纹并减少指纹ID。键3用于从系统中删除存储的手指,键4用于OK。一个 LED 用于表示检测到或匹配指纹。在这里,我们使用了可在UART上工作的指纹模块。因此,这里我们以默认波特率为57600将该指纹模块与PIC微控制器连接。
因此,首先,我们需要进行所有必要的连接,如下电路图所示。连接很简单,我们只需将指纹模块连接到PIC微控制器的UART。16x2 LCD用于显示所有消息。LCD还使用一个10k的电位器来控制其对比度。16x2 LCD数据引脚连接到PORTA引脚。LCD的d4,d5,d6和d7引脚分别与PIC微控制器的RA0,RA1,RA2和RA3引脚连接。四个按钮(或小键盘)连接到PORTD的RD0,RD1,RD2和RD引脚。LED也连接在端口PORTC的RC3引脚上。在这里,我们使用了一个18.432000 MHz的外部晶体振荡器为微控制器提供时钟。
带PIC单片机的指纹传感器的操作
该项目的操作非常简单,只需在PIC编程器或刻录机(PIckit2或Pickit3或其他工具)的帮助下,将源代码生成的十六进制文件上传到PIC单片机中,然后您将在LCD上看到一些介绍性信息,然后用户系统将要求您输入操作选项。要匹配指纹,用户需要按键1,然后LCD会要求 将手指 放在指纹传感器上。现在,通过将手指放在指纹模块上,我们可以检查指纹是否已经存储。如果您的指纹已存储,则LCD将显示带有指纹的存储ID的消息,例如 “ ID:2”, 否则将显示 “未找到” 。
现在 要注册指纹 ,用户需要按注册按钮或键2并按照LCD屏幕上的指示信息进行操作。
如果用户要 删除任何指纹, 则需要按 Delete(删除) 按钮或按键3。 之后,LCD将询问要删除的指纹ID。现在,通过使用增量按钮或键1(匹配按钮或键1)和减量按钮或键2(注册按钮或键2)进行增量和减量,用户可以选择已保存指纹的ID,然后按OK。按钮删除该指纹。要了解更多信息,请查看 项目结尾处提供的 视频。
指纹接口注:对于初学者来说,该项目的程序有些复杂。但是它的简单接口代码是通过阅读r305指纹模块数据表制成的。数据表中给出了该指纹模块的所有功能说明。
在这里,我们使用帧格式与指纹模块进行通话。每当我们向指纹模块发送命令或数据请求帧时,它都会以相同的帧格式响应我们,其中包含与所应用命令相关的数据或信息。所有数据和命令帧格式已在用户手册或R305指纹模块的数据表中给出。
编程说明
在编程中,我们使用了以下帧格式。
我们通过设置配置位以及定义LCD,按钮和LED的宏和引脚来开始程序,您可以检入项目末尾给出的完整代码。如果您不熟悉PIC单片机,请从PIC单片机项目入门开始。
然后,我们声明并初始化了一些变量和数组,并制作了一个框架,供我们在本项目中使用以将指纹模块与PIC微控制器接口。
uchar buf; uchar buf1; 易失性uint索引= 0; volatile int标志= 0; uint msCount = 0; uint g_timerflag = 1; volatile uint count = 0; uchar数据; uint id = 1; 枚举 { CMD, DATA, SBIT_CREN = 4, SBIT_TXEN, SBIT_SPEN, }; const char passPack = {0xEF,0x1、0xFF,0xFF,0xFF,0xFF,0x1、0x0、0x7、0x13、0x0、0x0、0x0、0x0、0x0、0x1B} const char f_detect = {0xEF,0x1、0xFF,0xFF,0xFF,0xFF,0x1、0x0、0x3、0x1、0x0、0x5} const char f_imz2ch1 = {0xEF,0x1、0xFF,0xFF,0xFF,0xFF,0x1、0x0、0x4、0x2、0x1、0x0、0x8}; const char f_imz2ch2 = {0xEF,0x1、0xFF,0xFF,0xFF,0xFF,0x1、0x0、0x4、0x2、0x2、0x0、0x9}; const char f_createModel = {0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x3,0x5,0x0,0x9}; char f_storeModel = {0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x6,0x6,0x1,0x0,0x1,0x0,0xE}; const char f_search = {0xEF,0x1、0xFF,0xFF,0xFF,0xFF,0x1、0x0、0x8、0x1B,0x1、0x0、0x0、0x0、0xA3、0x0、0xC8} char f_delete = {0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x7,0xC,0x0,0x0,0x0,0x1,0x0,0x15};
之后,我们就已经有了LCD功能来驱动LCD。
无效lcdwrite (uchar ch,uchar rw ){ LCDPORT = ch >> 4&0x0F; RS = rw; EN = 1;__delay_ms(5); EN = 0; LCDPORT = ch&0x0F; EN = 1;__delay_ms(5); EN = 0; } lcdprint(char * str){ while(* str){ lcdwrite(* str ++,DATA); // __ delay_ms(20); } } lcdbegin(){ uchar lcdcmd = {0x02,0x28,0x0E,0x06,0x01}; uint i = 0; for(i = 0; i <5; i ++)lcdwrite(lcdcmd,CMD); }
给定功能用于初始化UART
void serialbegin (uint baudrate ) { SPBRG =(18432000UL /(long)(64UL * baudrate))-1; //波特率@ 18.432000Mhz Clock TXSTAbits.SYNC = 0; //设置异步模式,即UART RCSTAbits.SPEN = 1; //启用串行端口 TRISC7 = 1; //按照数据表 TRISC6 = 0的规定; //按照数据表 RCSTAbits.CREN = 1的规定; //启用连续接收 TXSTAbits.TXEN = 1; //启用传输 GIE = 1; // ENABLE中断 INTCONbits.PEIE = 1; //启用外设中断。 PIE1bits.RCIE = 1; //使能USART接收中断 PIE1bits.TXIE = 0; //禁用USART TX中断 PIR1bits.RCIF = 0; }
给定的功能用于将命令传输到指纹模块并从指纹模块接收数据。
void serialwrite (char ch) { while(TXIF == 0); //等待发送器寄存器为空 TXIF = 0; //清除发送器标志 TXREG = ch; //将要传输的字符加载到传输寄存器中 } serialprint(char * str) { while(* str) { serialwrite(* str ++); } } void interrupt SerialRxPinInterrupt(void) { if(((PIR1bits.RCIF == 1)&&(PIE1bits.RCIE == 1)) { uchar ch = RCREG; buf = ch; if(index> 0)标志= 1; RCIF = 0; //清除rx标志} } void serialFlush(){ for(int i = 0; i
之后,我们需要创建一个函数,该函数准备要传输到指纹的数据并解码来自指纹模块的数据。
int sendcmd2fp(char * pack,int len ) { uint res = ERROR; serialFlush(); 索引= 0; __delay_ms(100); for(int i = 0; i
现在,代码中有四个功能可用于四个不同的任务:
- 输入指纹ID的函数– 单位getId()
- 匹配手指的函数– void matchFinger()
- 注册新手指的功能– 无效的enrolFinger()
- 删除手指的函数– void deleteFinger()
最后给出了具有这四个功能的完整代码。
现在在主要功能中,我们初始化GPIO,LCD,UART,并检查指纹模块是否与微控制器连接。然后,它在LCD上显示一些介绍性消息。最后,在 while 循环中,我们读取所有键或按钮以操作项目。
int main() { void(* FP)(); ADCON1 = 0b00000110; LEDdir = 0; SWPORTdir = 0xF0; SWPORT = 0x0F; serialbegin(57600); LCDPORTDIR = 0x00; TRISE = 0; lcdbegin(); lcdprint(“ Fingerprint”); lcdwrite(192,CMD); lcdprint(“接口”); __delay_ms(2000); lcdwrite(1,CMD); lcdprint(“使用PIC16F877A”); lcdwrite(192,CMD); lcdprint(“ Circuit Digest”); __delay_ms(2000); 索引= 0; while(sendcmd2fp(&passPack,sizeof(passPack))) { lcdwrite(1,CMD); lcdprint(“未找到FP”); __delay_ms(2000); 索引= 0; } lcdwrite(1,CMD); lcdprint(“找到FP”); __delay_ms(1000); lcdinst(); while(1) { FP = match
完整的PIC代码和工作视频 如下。还要使用指纹传感器模块检查我们的其他项目:
- 使用Arduino的基于指纹的生物特征投票机
- 使用Arduino和指纹传感器的生物识别安全系统
- 使用Arduino的基于指纹的生物识别出勤系统
- 指纹传感器与Raspberry Pi的接口