AS608指纹模块于51单片机的二次开发

前言提要

记得好久之前听老师说:你们有一个学姐非常的上进,在我的指导下做了啊,用51单片机做了一个指纹锁,然后学姐凭借着这个在找工作面试的时候阿巴阿巴阿巴…
说实话我觉得老师说这种话向来是吹牛皮,或者说可能只是单纯的想让我们有学习的动力。只要结果是良性的我们可以不是很用在意过程。

综合各方面的原因之后我决定还是试着做一个,拿出已经积灰很久的实验板,淘宝上买好模块之后就开始怀疑人生的编写和调试吧!


对了,刚发现还有一个问题,我还不清楚为什么,现在这里说一下本篇不会有太多的照片展示,至于原因…我们结尾再说吧。本人水平有限,写博客完全希望能够借此帮助刚入手的同志们能够少走些弯路,以下内容欢迎各路大佬斧正以及理性的探讨交流,需要用到原码的同志们可以在评论区或者私信留言给我,看到留言之后我都会第一时间回复的!

一、初识AS608:

关于AS608的介绍之前有大佬已经介绍的很详细了,插一句话啊,其实没必要完全了解工作原理,基本上了解应答格式就可以开始编写了,为了照顾新手村选手,这里将用户手册中的引脚说明及应答包格式贴出来,如果还有同志不是很明白可以去看看大佬的介绍或者私信我。在这里插入图片描述
稍微说一下,这里的7和8一般是用不到的5和6根据自己的需求来,我在开发的过程中并没有使用到。也就是说在这个模块中我只用了4根线(VCC.GND还有就是TXD.RXD)。TXD.RXD如果自己没有把握确定具体怎么接线的话可以先随便接,这个接反了是不会烧坏的,但是应答包是一定接收不到的,在后续的测试中再尝试反接看能不能收到正确的应答包就行了。

在这里插入图片描述

这里介绍了一些相关参数,其中尤其需要注意波特率的设置,详细的情况写在下文。

在这里插入图片描述

这里介绍了指令及应答包的格式,以及确认码的定义。

二、设计

1.思路

我是想做一个指纹以及密码的双验证锁。在上电之后首先选择想要进行的验证模式(指纹验证或密码验证,本次密码初始为6个2),由LCD1602做显示。 密码验证:需要s1-s10输入0-9这十个数,其次有退位按键,确认按键,以及复位按键(软复位)。在这里补充一点:键盘s1-s16一共16个,利用行列扫描判断真值。两个独立按键k3及k4用以选择模式。 指纹验证:选择指纹验证模式之后由单片机向AS608握手,已返回值判断是否成功建立连接。连接成功之后再进入一个选择界面,可以分别是验证指纹,添加指纹,删除指纹,和一个软复位。添加指纹是需要输入一个储存的模板号,由软件设置初始值000,按键加减,该模式下包含一个确认按键。删除指纹可以同上,但是我选择的是清空指纹库。 经由以上资料再结合设计的实现方向不难发现我们现在还缺点东西。 电源模块用于提供3.3V电压,包含一个电源模块所需的适配器,我在这里没用适配器而选择的是一个直流可调的电压源。值得注意的是电源模块的输入电压需要比输出电压高至少1V。单片机采用5V供电,那么也就是说我们的直流电源输出应该在6V往上,但是最好不要达到8V以上,再往上10V会直接炸,别问我是怎么知道的。 一个可以实现逻辑控制的锁。我这里采用的是一个小型的电磁锁和一个L289N电机驱动芯片,同志们还可以用电机或者舵机来代替它们。我采用这种方法只是因为之前做的时候留下了一个L289N,再买一个电磁锁就行了,节省经费嘛,毕竟还有可能出现无法预知的突发状况。钱是人的胆!

2.上原理图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从原理图上能看到4个独立按键中的K1和K2占用了串口,所以就不考虑使用啦。

3.程序设计中需要注意的几个点:

串口:

代码如下(示例):

#ifndef __UART2_H
#define __UART2_H

#define uchar unsigned char 
#define uint unsigned int

sfr AUXR  = 0x8e;           //Auxiliary register
sfr S2CON = 0x9a;           //UART2 control register
sfr S2BUF = 0x9b;           //UART2 data buffer
sfr BRT   = 0x9c;           //Baudrate generator
sfr IE2   = 0xaf;           //Interrupt control 2

#define S2RI 0x01        //串口2接收中断请求标志位
#define S2TI 0x02        //串口2发送中断请求标志位
#define UART2_MAX_RECV_LEN		50					//最大接收缓存字节数
#define UART2_MAX_SEND_LEN		50					//最大发送缓存字节数
//串口接收缓存区 	
uchar  xdata UART2_RX_BUF[UART2_MAX_RECV_LEN]; 				//接收缓冲,最大USART3_MAX_RECV_LEN个字节.
uchar  xdata UART2_TX_BUF[UART2_MAX_SEND_LEN]; 			  //发送缓冲,最大USART3_MAX_SEND_LEN字节
uint   UART2_RX_STA=0;  

//串口2初始化
void UART2_Init()
{
	AUXR |= 0x08;		//使能波特率倍速位S2SMOD
	S2CON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xFB;		//独立波特率发生器时钟为Fosc/12,即12T
	BRT = 0xFF;		//设定独立波特率发生器重装值
	AUXR |= 0x10;		//启动独立波特率发生器
	IE2 =0x01;        //开串口2中断  ES2=1
	EA = 1;
}

void Timer1_Init()
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD |= 0x10;		//设置定时器模式
	TL1 = 0x00;		//设置定时初值
	TH1 = 0xDC;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 0;		//定时器1开始计时
	ET1 = 1;
}

//串口2发送一个字节
void UART2_SendData(uchar c)
{
    S2BUF = c;
    while(!(S2CON&S2TI));  //若S2TI=0,在此等待
    S2CON&=~S2TI;          //S2TI=0
}

//串口2发送字符串
//void UART2_SendString(char *s)
//{
//    while (*s)              //Check the end of the string
//    {
//        UART2_SendData(*s++);     //Send current char and increment string ptr
//    }
//}

/************串行口2中断处理函数*************/
void UART2_Interrupt(void) interrupt 8{
	uchar Res;
	if(S2CON&S2RI)
	{
		S2CON&=~S2RI;
		Res=S2BUF;
		if((UART2_RX_STA&(1<<15))==0)//接收未完成
    {
      if(UART2_RX_STA<50)	//还可以接收数据
      {
        TL1 = 0x00;		//设置定时初值
        TH1 = 0xDC;		//设置定时初值
        if(UART2_RX_STA==0)
        {
          TR1 = 1;//使能定时器
        }
        UART2_RX_BUF[UART2_RX_STA++]=Res;	//记录接收到的值
      }
      else
      {
        UART2_RX_STA|=1<<15;				//强制标记接收完成
      }
    }
	} 
}
void Timer1_Interrupt() interrupt 3{
	UART2_RX_STA|=1<<15;	//标记接收完成
	TL1 = 0x00;		//设置定时初值
	TH1 = 0xDC;		//设置定时初值
	TR1 = 0;		//定时器1开始计时
}
#endif
先说重点:上面内个程序我没有成功,我也不太清楚为什么,我将这段程序反反复复检查和改写,都不能让单片机与AS608取得正确的连接。 然后我扒出了这个例程:
//串口初始化
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);
}
这个串口初始化的程序是可以连接的,但是还存在一个问题就是单片机和AS608的第一次握手总是失败的。需要手动复位之后再次选择指纹验证模式,再尝试握手之后才可能成功。我的程序目前是这样,如果不成功的话可以尝试多次复位重连,我最初的时候需要复位3次左右!当然了,要是图省事可以在程序里面添一步,设立一个通信成功的标记,如果标记值不改变就循环执行。 波特率的问题我再调试这两种串口初始化之前就注意到了,所以基本可以排除。晶振由于年代久远,其上并没有标明,一般只有11.0592M和12M两种,以我现有的手段以及工具无法确定它的型号,但是误差计算之后这两种型号的晶振在波特率为9600时最小,好像是只差0.16%。在实际使用上这么小的误差应该是可以忽略不计的。所以在写这篇文章之是依旧无法确定具体是什么原因导致通信不成功。如果有大佬发现了错误并告知我,将不胜感激。

为了以防有同志再掉到坑里我在这里再贴一下吧。

在这里插入图片描述
先用模块和上位机连接做测试,打开设备之后注意左下角的波特率设置。这个设置值需要和软件中串口的设置值相符,否则是无法通信的。9600不是必须的,通讯没问题的话完全可以设置成其他的值,记得这里改了程序中的串口初始化也一定要改就行了。

啊…突然忘记了之前还想写啥来着,好像也没什么了吧

指纹模块的程序都是差不多的,写不出花来。 不过还可以再其他的地方做些更贴近与现实情况的设计,比如说在执行添加指纹或者删除指纹操作之前加设一个超级密码,或者说是管理员密码之类的,验证通过之后再继续执行。密码验证模式的时候也可以设计一个管理员密码验证之后更改下一级密码的操作。无限套娃........哈哈哈哈哈

上几张运行时的图片吧,再说一下刚发现的问题
在这里插入图片描述
开机初始化界面

在这里插入图片描述

选择指纹验证后的选择界面,选择要执行的程序,验证or添加or删除or复位 对了我把复位的程序贴在这里吧,省得有的同志再跑出去找
void reset(void){
	((void (code *)(void))0x0000)();
}

在这里插入图片描述

这个是指纹验证成功的显示


啊…我忘记剪指甲了。你也忘了吧…毕竟这不重要对吧。

在这里插入图片描述

密码验证模式时的密码输入。为了贴近现实所以做成这样,没有输入密码之前是空。输入一位密码多一个*

*的ASCII码是42 空格的ASCII码是32 对了,之前说为什么少上照片。我发现了一个奇怪的事情,在单片机复位之后按理来说呈现的应该是初始界面,就像第一张照片。但是它总会在复位之后转跳到指纹验证模式的选择界面,就很离谱! 后来我尝试了一下,是我手机的问题?每次复位之后手机靠近然后标记就会置1然后转跳界面???试了好几次,只有手机一个变量,把手机拿远一点之后就没问题了,舍友的iPhone也是这样。这是...涡流?感生电动势还是动生电动势来着。差点还以为今天就见到***了呢。

总结

唔…现在能想到的就这么多,大概就是这样吧。本人水平有限,能做到的就是这么多,想要源码做移植或者说是想要例程作参考或者说是想要上位机测试软件还有资料之类的东西都可以私聊我啊,看到之后都会第一时间回复的。这大概率是微处理器的最后一篇了,后面还有其他的事情要忙,应该很少上论坛了。要是再写这个专栏,可能就是毕设的做品了吧。反正也没啥人看,权当写给自己的日志吧。

都读到这里了,辛苦了呢。如果感觉这篇博客对你有帮助,还请点赞收藏,让更多人的人都能看的到,不胜感激!

写在文末:这是第二篇博客,还不是很熟练,所以看着比较单调吧。
老规矩,祝大家
学有所成!
别墅靠海!!
终成眷属!!!

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页