久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
51單片機的AS608指紋鎖源程序
[打印本頁]
作者:
Exception77
時間:
2020-6-17 16:01
標題:
51單片機的AS608指紋鎖源程序
AS608 指紋識別模塊主要是指采用了杭州晟元芯片技術有限公司(Synochip)的 AS608 指紋識別芯片 而做成的指紋模塊,模塊廠商只是基于該芯片設計外圍電路,集成一個可供2次開發的指紋模塊;所以,只要是基于AS608芯片的指紋模塊,其控制電路及控制協議幾乎是一樣的,只是廠家和性能不同而已。
制作出來的實物圖如下:
1.png
(544.35 KB, 下載次數: 61)
下載附件
2020-6-17 22:52 上傳
單片機源程序如下:
#include<reg52.h>
#include<intrins.h>
#define MAIN_Fosc 11059200//宏定義主時鐘頻率
#define LINE1 0x80 //1602屏地址定義 第一行地址
#define LINE2 0xc0 //1602屏地址定義 第二行地址
#define DataPort P0 //LCD1602操作位定義
typedef unsigned char INT8U;
typedef unsigned char uchar;
typedef unsigned int INT16U;
typedef unsigned int uint;
sbit EN = P3^4; //讀寫數據使能 0:停止 1:啟動
sbit RS = P3^5; //寄存器選擇 0:指令寄存器 1:數據寄存器
sbit RW = P3^6; //讀寫控制 0:寫 1:讀
sbit KEY_DOWN=P2^4;
sbit KEY_OK=P2^2;
sbit KEY_CANCEL=P2^0;
sbit beep=P2^6;
uchar flag=0;
extern char local_date=0; //全局變量,當前箭頭位置
extern unsigned int finger_id = 0;
//uart 函數
void Uart_Init(void)
{
SCON=0x50; //UART方式1:8位UART; REN=1:允許接收
PCON=0x00; //SMOD=0:波特率不加倍
TMOD=0x20; //T1方式2,用于UART波特率
TH1=0xFD;
TL1=0xFD; //UART波特率設置:FDFD,9600;FFFF,57600
TR1=1; //允許T1計數
EA=1; //開總中斷
}
void Uart_Send_Byte(unsigned char c)//UART Send a byte
{
SBUF = c;
while(!TI); //發送完為1
TI = 0;
}
unsigned char Uart_Receive_Byte()//UART Receive a byteg
{
unsigned char dat;
while(!RI); //接收完為1
RI = 0;
dat = SBUF;
return (dat);
}
//延時函數
void Delay_us(int i)
{
while(--i);
}
void Delay_ms(INT16U ms)
{
INT16U i;
do{
i = MAIN_Fosc / 96000;
while(--i); //96T per loop
}while(--ms);
}
//蜂鳴器函數
void Beep_Times(unsigned char times)
{
unsigned char i=0;
for(i=0;i<times;i++)
{
beep=0;
Delay_ms(200);
beep=1;
Delay_ms(200);
}
}
//按鍵操作函數
void Key_Init(void)
{
//定義按鍵輸入端口
KEY_DOWN=1; // 下一項
KEY_OK=1; // 確認
KEY_CANCEL=1; // 取消
}
// 1602液晶函數
//寫指令
void LCD1602_WriteCMD(unsigned char cmd)
{
EN=0;
RS=0;
RW=0;
Delay_us(10);
EN=1;
Delay_us(10);
DataPort=cmd;
Delay_us(10);
EN=0;
}
//寫數據
void LCD1602_WriteDAT(unsigned char dat)
{
EN=0;
RS=1;
RW=0;
Delay_us(10);
EN=1;
Delay_us(10);
DataPort=dat;
Delay_us(10);
EN=0;
}
//液晶繁忙檢測
void LCD1602_CheckBusy(void)
{
uchar busy;
DataPort=0xff;
RS=0;
RW=1;
do
{
EN=1;
busy=DataPort;
EN=0;
}while(busy&0x80);
}
//液晶初始化函數
void LCD1602_Init(void)
{
Delay_ms(15); //上電延時15ms
LCD1602_WriteCMD(0x38); //寫顯示指令(不檢測忙信號)
Delay_ms(5);
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x38); //寫顯示指令
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x01); //清屏
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x06); //顯示光標移動設置
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x0c); //顯示開及光標設置
}
//液晶顯示函數 入口參數:addr起始地址,pointer指針地址,index下標,num個數
void LCD1602_Display(unsigned char addr,unsigned char* pointer,unsigned char index,unsigned char num)
{
unsigned char i;
LCD1602_CheckBusy(); //判斷忙信號
LCD1602_WriteCMD(addr); //寫入地址
for(i=0;i<num;i++) //寫入數據
{
LCD1602_CheckBusy(); //判斷忙信號
LCD1602_WriteDAT(pointer[index+i]);//寫入數據
}
}
//AS608指紋模塊
volatile unsigned char AS608_RECEICE_BUFFER[32]; //volatile:系統總是重新從它所在的內存讀取數據,即使它前面的指令剛剛從該處讀取過數據
//FINGERPRINT通信協議定義
code unsigned char AS608_Get_Device[10] ={0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x00,0x1b};//口令驗證
code unsigned char AS608_Pack_Head[6] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF}; //協議包頭
code unsigned char AS608_Get_Img[6] = {0x01,0x00,0x03,0x01,0x00,0x05}; //獲得指紋圖像
code unsigned char AS608_Get_Templete_Count[6] ={0x01,0x00,0x03,0x1D,0x00,0x21 }; //獲得模版總數
code unsigned char AS608_Search[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x03,0xE7,0x00,0xF8}; //搜索指紋搜索范圍0 - 999,使用BUFFER1中的特征碼搜索
code unsigned char AS608_Search_0_9[11]={0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x00,0x13,0x00,0x21}; //搜索0-9號指紋
code unsigned char AS608_Img_To_Buffer1[7]={0x01,0x00,0x04,0x02,0x01,0x00,0x08}; //將圖像放入到BUFFER1
code unsigned char AS608_Img_To_Buffer2[7]={0x01,0x00,0x04,0x02,0x02,0x00,0x09}; //將圖像放入到BUFFER2
code unsigned char AS608_Reg_Model[6]={0x01,0x00,0x03,0x05,0x00,0x09}; //將BUFFER1跟BUFFER2合成特征模版
code unsigned char AS608_Delete_All_Model[6]={0x01,0x00,0x03,0x0d,0x00,0x11};//刪除指紋模塊里所有的模版
volatile unsigned char AS608_Save_Finger[9]={0x01,0x00,0x06,0x06,0x01,0x00,0x0B,0x00,0x19};//將BUFFER1中的特征碼存放到指定的位置
//code unsigned char AS608_num_of_finger_in_lib1[7]={0x01,0x00,0x04,0x1F,0x00,0x00,0x24};//查看指紋庫的命令
//code unsigned char AS608_num_of_finger_in_lib2[7]={0x01,0x00,0x04,0x1F,0x01,0x00,0x25};
//code unsigned char AS608_num_of_finger_in_lib3[7]={0x01,0x00,0x04,0x1F,0x02,0x00,0x26};
//code unsigned char AS608_num_of_finger_in_lib4[7]={0x01,0x00,0x04,0x1F,0x03,0x00,0x27};
//發送包頭
void AS608_Cmd_Send_Pack_Head(void)
{
int i;
for(i=0;i<6;i++) //包頭
{
Uart_Send_Byte(AS608_Pack_Head[i]);
}
}
//發送指令
void AS608_Cmd_Check(void)
{
int i=0;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<10;i++)
{
Uart_Send_Byte(AS608_Get_Device[i]);
}
}
//接收反饋數據緩沖
void AS608_Receive_Data(unsigned char ucLength)
{
unsigned char i;
for (i=0;i<ucLength;i++)
AS608_RECEICE_BUFFER[i] = Uart_Receive_Byte();
}
//FINGERPRINT_獲得指紋圖像命令
void AS608_Cmd_Get_Img(void)
{
unsigned char i;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<6;i++) //發送命令 0x1d
{
Uart_Send_Byte(AS608_Get_Img[i]);
}
}
//將圖像轉換成特征碼存放在Buffer1中
void FINGERPRINT_Cmd_Img_To_Buffer1(void)
{
unsigned char i;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<7;i++) //發送命令 將圖像轉換成 特征碼 存放在 CHAR_buffer1
{
Uart_Send_Byte(AS608_Img_To_Buffer1[i]);
}
}
//將圖像轉換成特征碼存放在Buffer2中
void FINGERPRINT_Cmd_Img_To_Buffer2(void)
{
unsigned char i;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<7;i++) //發送命令 將圖像轉換成 特征碼 存放在 CHAR_buffer1
{
Uart_Send_Byte(AS608_Img_To_Buffer2[i]);
}
}
//搜索全部用戶999枚
void AS608_Cmd_Search_Finger(void)
{
unsigned char i;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<11;i++)
{
Uart_Send_Byte(AS608_Search[i]);
}
}
//轉換成特征碼
void AS608_Cmd_Reg_Model(void)
{
unsigned char i;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<6;i++)
{
Uart_Send_Byte(AS608_Reg_Model[i]);
}
}
//刪除指紋模塊里的所有指紋模版
void FINGERPRINT_Cmd_Delete_All_Model(void)
{
unsigned char i;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<6;i++) //命令刪除指紋模版
{
Uart_Send_Byte(AS608_Delete_All_Model[i]);
}
}
//保存指紋
void AS608_Cmd_Save_Finger( unsigned int storeID )
{
unsigned long temp = 0;
unsigned char i;
AS608_Save_Finger[5] =(storeID&0xFF00)>>8;
AS608_Save_Finger[6] = (storeID&0x00FF);
for(i=0;i<7;i++) //計算校驗和
temp = temp + AS608_Save_Finger[i];
AS608_Save_Finger[7]=(temp & 0x00FF00) >> 8; //存放校驗數據
AS608_Save_Finger[8]= temp & 0x0000FF;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<9;i++)
Uart_Send_Byte(AS608_Save_Finger[i]); //發送命令 將圖像轉換成 特征碼 存放在 CHAR_buffer1
}
//查看當前指紋庫中指紋模板數
int AS608_number_of_fingers()
{
int num=1;//默認模板庫中有一個模板
uchar i=0;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<6;i++)
{
Uart_Send_Byte(AS608_Get_Templete_Count[i]);
}
AS608_RECEICE_BUFFER[9]=1;//方便后續判斷是否接收成功
AS608_Receive_Data(14);//接收數據
if(AS608_RECEICE_BUFFER[9]==0) //接收成功
{
num=AS608_RECEICE_BUFFER[10]*256+AS608_RECEICE_BUFFER[11];//拼接模板總個數
}
return num;
}
//另一種方法查看指紋庫中是否有模板 //本來應該查看所有1000個模板位置是否存在模板,但一般只用得到前256個,故從簡
/*
uchar AS608_notEmpty()
{
uchar exist=0;
char i=0;
AS608_Cmd_Send_Pack_Head(); //發送通信協議包頭
for(i=0;i<7;i++)
{
Uart_Send_Byte(AS608_num_of_finger_in_lib1[i]);
}
AS608_Receive_Data(10);//接收前10byte數據,除第10字節的確認碼外,其余全部丟棄
if(AS608_RECEICE_BUFFER[9]==0) //接收成功
{
AS608_Receive_Data(32);//接收后續32byte數據,此即0~255個模板為是否存在指紋模板的數據
for(i=0;i<32;i++)//查看這32byte數據,任何一個位置存在模板則返回值為真,否則為假
{
if(AS608_RECEICE_BUFFER[i])
exist=1;
}
return exist;
}
}
*/
//添加指紋
void AS608_Add_Fingerprint()
{
unsigned char id_show[]={0,0,0};
LCD1602_WriteCMD(0x01); //清屏
while(1)
{
LCD1602_Display(0x80," Add finger ",0,16);
LCD1602_Display(0xc0," ID is ",0,16);
//按返回鍵直接回到主菜單
if(KEY_CANCEL == 0)
{
Delay_ms(5);
if(KEY_CANCEL == 0)
{
while(KEY_CANCEL==0);
break;
}
}
//按切換鍵指紋iD值加1
if(KEY_DOWN == 0)
{
Delay_ms(5);
if(KEY_DOWN == 0)
{
while(KEY_DOWN==0);
if(finger_id == 1000)
{
finger_id = 1;
}
else
finger_id = finger_id + 1;
}
}
//指紋iD值顯示處理
LCD1602_WriteCMD(0xc0+10);
LCD1602_WriteDAT(finger_id/100+48);
LCD1602_WriteDAT(finger_id%100/10+48);
LCD1602_WriteDAT(finger_id%100%10+48);
//按確認鍵開始錄入指紋信息
if(KEY_OK == 0)
{
Delay_ms(5);
if(KEY_OK == 0)
{
while(KEY_OK==0);
LCD1602_Display(0x80," Please finger ",0,16);
LCD1602_Display(0xc0," ",0,16);
while(KEY_CANCEL == 1)
{
//按下返回鍵退出錄入返回fingerID調整狀態
if(KEY_CANCEL == 0)
{
Delay_ms(5);
if(KEY_CANCEL == 0)
{
while(KEY_CANCEL==0);
break;
}
}
AS608_Cmd_Get_Img(); //獲得指紋圖像
AS608_Receive_Data(12);
//判斷接收到的確認碼,等于0指紋獲取成功
if(AS608_RECEICE_BUFFER[9]==0)
{
Delay_ms(100);
FINGERPRINT_Cmd_Img_To_Buffer1();
AS608_Receive_Data(12);
LCD1602_Display(0x80,"Successful entry",0,16);
Beep_Times(1);
Delay_ms(1000);
LCD1602_Display(0x80," Please finger ",0,16);
LCD1602_Display(0xc0," ",0,16);
while(1)
{
if(KEY_CANCEL == 0)
{
Delay_ms(5);
if(KEY_CANCEL == 0)
{
while(KEY_CANCEL==0);
break;
}
}
AS608_Cmd_Get_Img(); //獲得指紋圖像
AS608_Receive_Data(12);
//判斷接收到的確認碼,等于0指紋獲取成功
if(AS608_RECEICE_BUFFER[9]==0)
{
Delay_ms(200);
LCD1602_Display(0x80,"Successful entry",0,16);
LCD1602_Display(0xc0," ID is ",0,16);
//指紋iD值顯示處理
LCD1602_WriteCMD(0xc0+10);
LCD1602_WriteDAT(finger_id/100+48);
LCD1602_WriteDAT(finger_id%100/10+48);
LCD1602_WriteDAT(finger_id%100%10+48);
FINGERPRINT_Cmd_Img_To_Buffer2();
AS608_Receive_Data(12);
AS608_Cmd_Reg_Model();//轉換成特征碼
AS608_Receive_Data(12);
AS608_Cmd_Save_Finger(finger_id);
AS608_Receive_Data(12);
Beep_Times(1);
Delay_ms(1000);
finger_id=finger_id+1;
break;
}
}
break;
}
}
}
}
}
}
//搜索指紋
void AS608_Find_Fingerprint()
{
unsigned int find_fingerid = 0;
unsigned char id_show[]={0,0,0};
do
{
LCD1602_Display(0x80," Please finger ",0,16);
LCD1602_Display(0xc0," ",0,16);
AS608_Cmd_Get_Img(); //獲得指紋圖像
AS608_Receive_Data(12);
//判斷接收到的確認碼,等于0指紋獲取成功
if(AS608_RECEICE_BUFFER[9]==0)
{
Delay_ms(100);
FINGERPRINT_Cmd_Img_To_Buffer1();
AS608_Receive_Data(12);
AS608_Cmd_Search_Finger();
AS608_Receive_Data(16);
if(AS608_RECEICE_BUFFER[9] == 0) //搜索到
{
//解鎖成功//
LCD1602_Display(0x80," Search success ",0,16);
LCD1602_Display(0xc0," ID is ",0,16);
Beep_Times(1);
//拼接指紋ID數
find_fingerid = AS608_RECEICE_BUFFER[10]*256 + AS608_RECEICE_BUFFER[11];
//指紋iD值顯示處理
LCD1602_WriteCMD(0xc0+10);
LCD1602_WriteDAT(find_fingerid/100+48);
LCD1602_WriteDAT(find_fingerid%100/10+48);
LCD1602_WriteDAT(find_fingerid%100%10+48);
//配置IO口,執行開鎖操作
if(flag)
{
P1=0xfe;
Delay_ms(3800);
P1=0xff; //電動機停止轉動
Delay_ms(1000);
P1=0xfd; //電動機反轉復位
Delay_ms(3600);//電機正轉阻力遠大于反轉,旋轉相同角度時,正轉需要更多時間
P1=0xff; //電動機停止轉動
}
flag=1; //允許后續相關操作:添加或刪除指紋模板
break;
}
else //沒有找到
{
LCD1602_Display(0x80," Search failed ",0,16);
LCD1602_Display(0xc0," ",0,16);
Beep_Times(3);
}
}
}while(KEY_CANCEL == 1);
}
//刪除所有存貯的指紋庫
void AS608_Delete_All_Fingerprint()
{
unsigned char i=0;
LCD1602_Display(0x80," empty all ",0,16);
LCD1602_Display(0xc0," Yes or no ? ",0,16);
do
{
if(KEY_OK==0)
{
Delay_ms(5);
if(KEY_OK==0)
{
while(KEY_OK==0);
LCD1602_Display(0x80," emptying ",0,16);
LCD1602_Display(0xc0," ",0,16);
Delay_ms(300);
LCD1602_WriteCMD(0xc0);
for(i=0;i<16;i++)
{
LCD1602_WriteDAT(42);// 即'*'
Delay_ms(100);
}
FINGERPRINT_Cmd_Delete_All_Model();
AS608_Receive_Data(12);
LCD1602_Display(0x80," All empty ",0,16);
LCD1602_Display(0xc0," ",0,16);
Beep_Times(3);
break;
}
}
}while(KEY_CANCEL==1);
}
void Device_Check(void)
{
unsigned char i=0;
AS608_RECEICE_BUFFER[9]=1; //串口數組第九位可判斷是否通信正常
LCD1602_Display(0xc0,"Loading",0,7); //設備加載中界面
for(i=0;i<8;i++) //進度條式更新,看起來美觀
{
LCD1602_WriteDAT(42); //42對應ASIC碼的 *
Delay_ms(20); //控制進度條速度
}
LCD1602_Display(0xc0,"Docking failure",0,16); //液晶先顯示對接失敗,如果指紋模塊插對的話會將其覆蓋
AS608_Cmd_Check(); //單片機向指紋模塊發送校對命令
AS608_Receive_Data(12); //將串口接收到的數據轉存
if(AS608_RECEICE_BUFFER[9] == 0) //判斷數據低第9位是否接收到0
{
LCD1602_Display(0xc0,"Docking success",0,16); //符合成功條件則顯示對接成功
}
}
//主函數
void main()
{
finger_id=0;
LCD1602_Init(); //初始化液晶
LCD1602_Display(0x80,"Fingerprint Test",0,16); //液晶開機顯示界面
Uart_Init(); //初始化串口
Key_Init(); //初始化按鍵
Delay_ms(200); //延時500MS,等待指紋模塊復位
Device_Check(); //校對指紋模塊是否接入正確,液晶做出相應的提示
Delay_ms(1000); //對接成功界面停留一定時間
while(1)
{
/**************進入主功能界面****************/
LCD1602_Display(0x80," search finger ",0,16); //第一排顯示搜索指紋
LCD1602_Display(0xc0," Add delete",0,16); //添加和刪除指紋
if(local_date==0)
{
LCD1602_Display(0x80, " *",0,2);
LCD1602_Display(0xc0, " ",0,2);
LCD1602_Display(0xc0+8," ",0,2);
}
else if(local_date==1)
{
LCD1602_Display(0x80, " ",0,2);
LCD1602_Display(0xc0, " *",0,2);
LCD1602_Display(0xc0+8," ",0,2);
}
else if(local_date==2)
{
LCD1602_Display(0x80, " ",0,2);
LCD1602_Display(0xc0, " ",0,2);
LCD1602_Display(0xc0+8," *",0,2);
}
//確認鍵
if(KEY_OK == 0)
{
Delay_ms(5);
if(KEY_OK == 0)
{
while(KEY_OK == 0);//等待松開按鍵
switch(local_date)
{
case 0: //搜索指紋
flag=1;
AS608_Find_Fingerprint();
break;
case 1: //添加指紋
flag=1; //flag=1,若指紋庫為空,則可以直接添加指紋
if(AS608_number_of_fingers())
{
flag=0;//flag置0由兩重作用:
//1、指紋庫中已有指紋,則需要搜索匹配成功,由AS608_Find_Fingerprint()將flag置1,才能添加指紋
//2、flag=0,則在搜索指紋成功后不執行開鎖操作
AS608_Find_Fingerprint();
}
if(flag)
{
AS608_Add_Fingerprint();
}
break;
case 2: //清空指紋
flag=0; //1、在搜索指紋成功后不執行開鎖操作;2、若搜索不成功,不執行清空操作
AS608_Find_Fingerprint();//搜索匹配成功后,函數內部將flag置1,才能清空指紋庫
if(flag)
{
AS608_Delete_All_Fingerprint();
}
break;
}
}
}
//切換鍵
if(KEY_DOWN == 0)
{
Delay_ms(5);
if(KEY_DOWN == 0)
{
while(KEY_DOWN == 0); //等待松開按鍵
if(local_date<=2)
{
local_date++;
if(local_date==3) local_date=0;
}
}
}
Delay_ms(100); //延時判斷100MS檢測一次
}
}
復制代碼
作者:
Vistor
時間:
2023-2-20 23:36
實測有用
作者:
wkman
時間:
2023-12-6 15:06
指紋打卡,,,
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
h视频在线看
|
日韩一区二区不卡
|
亚洲小说图片
|
亚洲毛片在线观看
|
在线视频一区二区
|
亚洲精品九九
|
日日日视频
|
日本中文字幕在线视频
|
在线观看国产视频
|
一区二区国产精品
|
国产日韩欧美在线观看
|
日韩欧美中文
|
欧美日韩国产一区二区三区
|
91精品久久久久久综合五月天
|
久久久精品一区二区
|
www.久久精品视频
|
欧美高清免费
|
免费黄色av
|
日韩伦理一区二区
|
国外激情av
|
精品久久久久一区二区国产
|
亚洲一区二区三区久久久
|
久久精品视频一区二区三区
|
国产精品久久久久久久久免费樱桃
|
国产免费一区二区
|
国产一区二区三区久久久久久久久
|
国产特一级黄色片
|
免费一区
|
伊人色综合久久天天五月婷
|
99爱在线观看
|
欧美一区二区三区大片
|
国产中文
|
亚州精品天堂中文字幕
|
免费中文字幕日韩欧美
|
给我免费的视频在线观看
|
2019天天操
|
国产一区
|
一区二区三区四区在线
|
天堂一区二区三区
|
久久久www成人免费无遮挡大片
|
91在线看片
|