全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > MEMS传感器 >

如何将指纹传感器与PIC微控制器连接

时间:2022-11-07 16:08

人气:

作者:admin

标签: Raspber  arduino 

导读:目前,我们在日常生活中随处可见基于指纹的系统,例如办公室考勤,银行员工验证,自动取款机中的现金提取或存款,政府办公室的身份验证等。我们已经将其与Arduino和Raspberry Pi接口...

几年前我们在科幻电影中看到的指纹传感器,现在变得非常普遍,用于验证一个人出于各种目的的身份。目前,我们在日常生活中随处可见基于指纹的系统,例如办公室考勤,银行员工验证,自动取款机中的现金提取或存款,政府办公室的身份验证等。我们已经将其与Arduino和Raspberry Pi接口,今天我们将指纹传感器与PIC微控制器连接。

必需组件

PIC16f877A 微控制器

指纹模块

按钮或键盘

16x2 液晶显示器

10k锅

18.432000 MHz 晶体振荡器

面包板或印刷电路板(从JLCPCB订购)

跳线

指示灯(可选)

电阻 150 欧姆 -1 k 欧姆(可选)

5v 电源

pYYBAGNovQiAUgWZAACKZHbSl2s232.jpg

电路图及说明

在这个PIC微控制器指纹传感器接口项目中,我们使用了4个按钮:这些按钮用于多功能。密钥 1用于在系统中存储或删除指纹时匹配指纹和递增指纹 ID。密钥 2用于注册新指纹以及在系统中存储或删除指纹时递减指纹 ID。键 3 用于从系统中删除存储的手指,键 4 用于确定。LED用于指示检测到或匹配指纹。在这里,我们使用了适用于UART的指纹模块。因此,在这里,我们将此指纹模块与PIC微控制器连接,其默认波特率为57600。

poYBAGNovQmAWWB4AAA0F3vV_3M613.jpg

因此,首先,我们需要进行所有必需的连接,如下面的电路图所示。连接很简单,我们刚刚将指纹模块连接到PIC微控制器的UART。16x2 LCD 用于显示所有消息。10k电位器也与LCD一起使用,以控制其对比度。16x2 LCD 数据引脚是连接的 PORTA 引脚。LCD 的 d4、d5、d6 和 d7 引脚分别与 PIC 微控制器的引脚 RA0、RA1、RA2 和 RA3 连接。四个按钮(或键盘)连接到 PORTD 的引脚 RD0、RD1、RD2 和 RD,LED 也连接到端口 PORTC 的引脚 RC3。在这里,我们使用了一个18.432000 MHz的外部晶体振荡器来为微控制器提供时钟

pYYBAGNovQyAJfaVAADbukztGzg043.png

带PIC微控制器的指纹传感器的操作

该项目的操作很简单,只需在PIC编程器或刻录机(PIckit2或Pickit3或其他)的帮助下,将从源代码生成的十六进制文件上传到PIC微控制器中,然后您将通过LCD看到一些介绍消息,然后要求用户输入操作选项。要匹配指纹,用户需要按键1,然后LCD将要求将手指放在指纹传感器上。现在,通过将手指放在指纹模块上,我们可以检查我们的指纹是否已存储。如果您的指纹已存储,则LCD将显示带有类似指纹的“ID:2”存储ID的消息,否则将显示“未找到”。

现在要注册指纹,用户需要按注册按钮或键 2 并按照 LCD 屏幕上的说明消息进行操作。

如果用户想要删除任何指纹,则用户需要按删除按钮或键3。之后,LCD将询问要删除的指纹的ID。现在,通过使用递增按钮或键1(匹配按钮或键1)和递减按钮或键2(注册按钮或键2)进行递增和递减,用户可以选择保存的指纹的ID,然后按确定按钮删除该指纹。


pYYBAGNovQ6ATqYrAAB-9nYFFuo219.jpg

指纹接口 注意:这个项目的程序对于初学者来说有点复杂。但其简单的接口代码是利用读取r305指纹模块数据表制作的。该指纹模块的所有功能说明都在数据表中给出。

在这里,我们使用帧格式与指纹模块通信。每当我们向指纹模块发送命令或数据请求帧时,它都会以相同的帧格式响应我们,其中包含与应用命令相关的数据或信息。所有数据和命令帧格式已在用户手册或R305指纹模块的数据表中给出。

编程说明

在编程中,我们使用了以下帧格式。

pYYBAGNovRSAIgBCAAC9FbVO6ZQ491.png

我们通过设置配置位并定义LCD,按钮和LED的宏和引脚来开始程序,您可以在该项目结束时给出的完整代码中签入。

然后我们声明并初始化了一些变量和数组,并制作了一个框架,我们需要在这个项目中使用它来连接指纹模块和PIC微控制器。

uchar buf[20];

uchar buf1[20];

volatile uint index=0;

volatile int flag=0;

uint msCount=0;

uint g_timerflag=1;

volatile uint count=0;

uchar data[10];

uint id=1;

enum

{

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。

void 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[5]={0x02,0x28,0x0E,0x06,0x01};

uint i=0;

for(i=0;i<5;i++)

lcdwrite(lcdcmd[i], CMD);

}

给定函数用于初始化UART

void serialbegin(uint baudrate)

{

SPBRG = (18432000UL/(long)(64UL*baudrate))-1; // baud rate @18.432000Mhz Clock

TXSTAbits.SYNC = 0; //Setting Asynchronous Mode, ie UART

RCSTAbits.SPEN = 1; //Enables Serial Port

TRISC7 = 1; //As Prescribed in Datasheet

TRISC6 = 0; //As Prescribed in Datasheet

RCSTAbits.CREN = 1; //Enables Continuous Reception

TXSTAbits.TXEN = 1; //Enables Transmission

GIE = 1; // ENABLE interrupts

INTCONbits.PEIE = 1; // ENable peripheral interrupts.

PIE1bits.RCIE = 1; // ENABLE USART receive interrupt

PIE1bits.TXIE = 0; // disable USART TX interrupt

PIR1bits.RCIF = 0;

}

给定函数用于将命令传输到指纹模块并从指纹模块接收数据。

void serialwrite(char ch)

{

while(TXIF==0); // Wait till the transmitter register becomes empty

TXIF=0; // Clear transmitter flag

TXREG=ch; // load the char to be transmitted into transmit reg

}

serialprint(char *str)

{

while(*str)

{

serialwrite(*str++);

}

}

void interrupt SerialRxPinInterrupt(void)

{

if((PIR1bits.RCIF == 1) && (PIE1bits.RCIE == 1))

{

uchar ch=RCREG;

buf[index++]=ch;

if(index>0)

flag=1;

RCIF = 0; // clear rx flag

}

}

void serialFlush()

{

for(int i=0;i

{

buf[i]=0;

}

}

之后,我们需要创建一个函数来准备要传输到指纹的数据并解码来自指纹模块的数据。

int sendcmd2fp(char *pack, int len)

{

uint res=ERROR;

serialFlush();

index=0;

__delay_ms(100);

for(int i=0;i

{

serialwrite(*(pack+i));

}

__delay_ms(1000);

if(flag == 1)

{

if(buf[0] == 0xEF && buf[1] == 0x01)

{

if(buf[6] == 0x07) // ack

{

if(buf[9] == 0)

{

uint data_len= buf[7];

data_len<<=8;

data_len|=buf[8];

for(int i=0;i

data[i]=0;

for(int i=0;i

{

data[i]=buf[10+i];

}

res=PASS;

}

else

{

res=ERROR;

}

}

}

现在,代码中有四个函数可用于四个不同的任务:

输入指纹ID的函数 –单位getId()

匹配手指的函数 –void matchFinger()

注册新手指的函数 – 无效注册手指()

删除手指的函数 –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("Interfacing");

__delay_ms(2000);

lcdwrite(1,CMD);

lcdprint("Using PIC16F877A");

lcdwrite(192,CMD);

lcdprint("Circuit Digest");

__delay_ms(2000);

index=0;

while(sendcmd2fp(&passPack[0],sizeof(passPack)))

{

lcdwrite(1,CMD);

lcdprint("FP Not Found");

__delay_ms(2000);

index=0;

}

lcdwrite(1,CMD);

lcdprint("FP Found");

__delay_ms(1000);

lcdinst();

while(1)

{

FP=match

FP();

}

return 0;

}

#define _XTAL_FREQ 18432000


#include

#include

#include

#include


// BEGIN CONFIG

#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)

#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)

#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)

#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)

#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)

#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)

#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)

#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

//END CONFIG


#define uchar unsigned char

#define uint unsigned int


#define LCDPORTDIR TRISA

#define LCDPORT PORTA

#define RS RE1

#define EN RE0


#define SWPORTdir TRISD

#define SWPORT PORTD

#define enrol RD4

#define match RD5

#define delet RD7


#define ok RD6

#define up RD5

#define down RD4


#define LEDdir TRISC3

#define LED RC3


#define HIGH 1

#define LOW 0


#define PASS 0

#define ERROR 1


#define checkKey(id) id=up


uchar buf[20];

uchar buf1[20];

volatile uint index=0;

volatile int flag=0;

uint msCount=0;

uint g_timerflag=1;

volatile uint count=0;

uchar data[10];

uint id=1;


enum

{

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






void 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[5]={0x02,0x28,0x0E,0x06,0x01};

uint i=0;

for(i=0;i<5;i++) 

lcdwrite(lcdcmd[i], CMD);

}


void lcdinst()

{

lcdwrite(0x80, CMD);

lcdprint("1-Match 2-Enroll");

lcdwrite(0xc0, CMD);

lcdprint("3-delete Finger");

__delay_ms(10);

}


void serialbegin(uint baudrate)

{

SPBRG = (18432000UL/(long)(64UL*baudrate))-1; // baud rate @18.432000Mhz Clock

TXSTAbits.SYNC = 0; //Setting Asynchronous Mode, ie UART

RCSTAbits.SPEN = 1; //Enables Serial Port

TRISC7 = 1; //As Prescribed in Datasheet

TRISC6 = 0; //As Prescribed in Datasheet

RCSTAbits.CREN = 1; //Enables Continuous Reception

TXSTAbits.TXEN = 1; //Enables Transmission


GIE = 1; // ENABLE interrupts

INTCONbits.PEIE = 1; // ENable peripheral interrupts.

PIE1bits.RCIE = 1; // ENABLE USART receive interrupt

PIE1bits.TXIE = 0; // disable USART TX interrupt


PIR1bits.RCIF = 0;



}


void serialwrite(char ch)

{

while(TXIF==0); // Wait till the transmitter register becomes empty

TXIF=0; // Clear transmitter flag

TXREG=ch; // load the char to be transmitted into transmit reg

}


serialprint(char *str)

{

while(*str)

{

serialwrite(*str++);

}

}


void interrupt SerialRxPinInterrupt(void)

{

if((PIR1bits.RCIF == 1) && (PIE1bits.RCIE == 1))

{



uchar ch=RCREG;

buf[index++]=ch;

if(index>0)

flag=1;

RCIF = 0; // clear rx flag

}

}


void serialFlush()

{

for(int i=0;i

{

buf[i]=0;

}

}


int sendcmd2fp(char *pack, int len)

{

uint res=ERROR;

serialFlush();

index=0;

__delay_ms(100);

for(int i=0;i

{

serialwrite(*(pack+i));

}

__delay_ms(1000);

if(flag == 1)

{

if(buf[0] == 0xEF && buf[1] == 0x01)

{

if(buf[6] == 0x07) // ack

{

if(buf[9] == 0)

{

uint data_len= buf[7];

data_len<<=8; 

data_len|=buf[8];

for(int i=0;i

data[i]=0;

for(int i=0;i

{

data[i]=buf[10+i];

}

res=PASS;

}


else

{

res=ERROR;

}

}

}

index=0;

flag=0;

return res;

}

}


uint getId()

{

uint id=0;

lcdwrite(1, CMD);

while(1)

{

lcdwrite(0x80, CMD);

checkKey(id);

sprintf(buf1,"Enter Id:%d ",id);

lcdprint(buf1);

__delay_ms(200);

if(ok == LOW)

return id;

}

}


void matchFinger()

{

lcdwrite(1,CMD);

lcdprint("Place Finger");

lcdwrite(192,CMD);

__delay_ms(2000);

if(!sendcmd2fp(&f_detect[0],sizeof(f_detect)))

{

if(!sendcmd2fp(&f_imz2ch1[0],sizeof(f_imz2ch1)))

{

if(!sendcmd2fp(&f_search[0],sizeof(f_search)))

{

lcdwrite(1,CMD);

lcdprint("Finger Found");

uint id= data[0];

id<<=8; 

id+=data[1];

uint score=data[2];

score<<=8; 

score+=data[3];

sprintf(buf1,"Id:%d Score:%d",id,score);

lcdwrite(192,CMD);

lcdprint(buf1);

LED=1;

__delay_ms(1000);

LED=0;

}



else

{

lcdwrite(1,CMD);

lcdprint("Not Found");

}

}

}



else

{

lcdprint("No Finger");

}

__delay_ms(2000);

}


void enrolFinger()

{

lcdwrite(1,CMD);

lcdprint("Enroll Finger");

__delay_ms(2000);

lcdwrite(1,CMD);

lcdprint("Place Finger");

lcdwrite(192,CMD);

__delay_ms(1000);

if(!sendcmd2fp(&f_detect[0],sizeof(f_detect)))

{

if(!sendcmd2fp(&f_imz2ch1[0],sizeof(f_imz2ch1)))

{

lcdprint("Finger Detected");

__delay_ms(1000);

lcdwrite(1,CMD);

lcdprint("Place Finger");

lcdwrite(192,CMD);

lcdprint(" Again ");

__delay_ms(2000);

if(!sendcmd2fp(&f_detect[0],sizeof(f_detect)))

{

if(!sendcmd2fp(&f_imz2ch2[0],sizeof(f_imz2ch2)))

{

lcdwrite(1,CMD);

lcdprint("Finger Detected");

__delay_ms(1000);

if(!sendcmd2fp(&f_createModel[0],sizeof(f_createModel)))

{

id=getId();

f_storeModel[11]= (id>>8) & 0xff;

f_storeModel[12]= id & 0xff;

f_storeModel[14]= 14+id;

if(!sendcmd2fp(&f_storeModel[0],sizeof(f_storeModel)))

{

lcdwrite(1,CMD);

lcdprint("Finger Stored");

sprintf(buf1,"Id:%d",id);

lcdwrite(192,CMD);

lcdprint(buf1);

__delay_ms(1000);

}



else

{

lcdwrite(1,CMD);

lcdprint("Finger Not Stored");

}

}

else

lcdprint("Error");

}

else

lcdprint("Error");

}

else

lcdprint("No Finger");

}

}

else

{

lcdprint("No Finger");

}

__delay_ms(2000);

}


void deleteFinger()

{

id=getId();

f_delete[10]=id>>8 & 0xff;

f_delete[11]=id & 0xff;

f_delete[14]=(21+id)>>8 & 0xff;

f_delete[15]=(21+id) & 0xff;

if(!sendcmd2fp(&f_delete[0],sizeof(f_delete)))

{

lcdwrite(1,CMD);

sprintf(buf1,"Finger ID %d ",id);

lcdprint(buf1);

lcdwrite(192, CMD);

lcdprint("Deleted Success");



}

else

{

lcdwrite(1,CMD);

lcdprint("Error");

}

__delay_ms(2000);

}




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("Interfacing");

__delay_ms(2000);

lcdwrite(1,CMD);

lcdprint("Using PIC16F877A");

lcdwrite(192,CMD);

lcdprint("Circuit Digest");

__delay_ms(2000);

index=0;

while(sendcmd2fp(&passPack[0],sizeof(passPack)))

{

lcdwrite(1,CMD);

lcdprint("FP Not Found");

__delay_ms(2000);

index=0;

}

lcdwrite(1,CMD);

lcdprint("FP Found");

__delay_ms(1000);

lcdinst();

while(1)

{

FP=match

FP();

}

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信