目录

AS608指纹模块

stm32f103c8t6最小系统板以及其他外设

工程资料

遇到的问题


AS608指纹模块

光学指纹模块更好用一点,电容式指纹模块的通信协议有一点不一样。

网上可以搜到相关的串口通信协议用户手册

首先可以尝试通过usb转串口让AS608与电脑串口通信,看通信协议,用电脑串口发送指令完成指纹录入等的操作。

通信协议在手册里,按照格式写命令。

具体串口通信如下:

AS608模块代码如下(包括.c和.h文件):

//AS608.c//正点原子版权所属  // #include "string.h"#include "Delay.h" #include "usart2.h"#include "as608.h"u32 AS608Addr = 0XFFFFFFFF; //默认//初始化PA8为下拉输入    //读摸出感应状态(触摸感应时输出高电平信号)void PS_StaGPIO_Init(void){     GPIO_InitTypeDef  GPIO_InitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能USART1,GPIOA时钟    //初始化读状态引脚GPIOA8  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  //IPD  下拉输入  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz   GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO}//串口发送一个字节static void MYUSART_SendData(u8 data){while((USART2->SR&0X40)==0); USART2->DR = data;}//发送包头static void SendHead(void){MYUSART_SendData(0xEF);MYUSART_SendData(0x01);}//发送地址static void SendAddr(void){MYUSART_SendData(AS608Addr>>24);MYUSART_SendData(AS608Addr>>16);MYUSART_SendData(AS608Addr>>8);MYUSART_SendData(AS608Addr);}//发送包标识static void SendFlag(u8 flag){MYUSART_SendData(flag);}//发送包长度static void SendLength(int length){MYUSART_SendData(length>>8);MYUSART_SendData(length);}//发送指令码static void Sendcmd(u8 cmd){MYUSART_SendData(cmd);}//发送校验和static void SendCheck(u16 check){MYUSART_SendData(check>>8);MYUSART_SendData(check);}//判断中断接收的数组有没有应答包//waittime为等待中断接收数据的时间(单位1ms)//返回值:数据包首地址static u8 *JudgeStr(u16 waittime){char *data;u8 str[8];str[0]=0xef;str[1]=0x01;str[2]=AS608Addr>>24;str[3]=AS608Addr>>16;str[4]=AS608Addr>>8;str[5]=AS608Addr;str[6]=0x07;str[7]='\0';USART2_RX_STA=0;while(--waittime){Delay_ms(1);if(USART2_RX_STA&0X8000)//接收到一次数据{USART2_RX_STA=0;data=strstr((const char*)USART2_RX_BUF,(const char*)str);if(data)return (u8*)data;}}return 0;}//录入图像 PS_GetImage//功能:探测手指,探测到后录入指纹图像存于ImageBuffer。 //模块返回确认字u8 PS_GetImage(void){  u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x03);Sendcmd(0x01);  temp =  0x01+0x03+0x01;SendCheck(temp);data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;return ensure;}//生成特征 PS_GenChar//功能:将ImageBuffer中的原始图像生成指纹特征文件存于CharBuffer1或CharBuffer2 //参数:BufferID --> charBuffer1:0x01charBuffer1:0x02//模块返回确认字u8 PS_GenChar(u8 BufferID){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x04);Sendcmd(0x02);MYUSART_SendData(BufferID);temp = 0x01+0x04+0x02+BufferID;SendCheck(temp);data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;return ensure;}//精确比对两枚指纹特征 PS_Match//功能:精确比对CharBuffer1 与CharBuffer2 中的特征文件 //模块返回确认字u8 PS_Match(void){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x03);Sendcmd(0x03);temp = 0x01+0x03+0x03;SendCheck(temp);data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;return ensure;}//搜索指纹 PS_Search//功能:以CharBuffer1或CharBuffer2中的特征文件搜索整个或部分指纹库.若搜索到,则返回页码。//参数:  BufferID @ref CharBuffer1CharBuffer2//说明:  模块返回确认字,页码(相配指纹模板)u8 PS_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x08);Sendcmd(0x04);MYUSART_SendData(BufferID);MYUSART_SendData(StartPage>>8);MYUSART_SendData(StartPage);MYUSART_SendData(PageNum>>8);MYUSART_SendData(PageNum);temp = 0x01+0x08+0x04+BufferID+(StartPage>>8)+(u8)StartPage+(PageNum>>8)+(u8)PageNum;SendCheck(temp);data=JudgeStr(2000);if(data){ensure = data[9];p->pageID   =(data[10]<mathscore=(data[12]<>8);MYUSART_SendData(PageID);temp = 0x01+0x06+0x06+BufferID+(PageID>>8)+(u8)PageID;SendCheck(temp);data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;return ensure;}//删除模板 PS_DeletChar//功能:  删除flash数据库中指定ID号开始的N个指纹模板//参数:  PageID(指纹库模板号),N删除的模板个数。//说明:  模块返回确认字u8 PS_DeletChar(u16 PageID,u16 N){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x07);Sendcmd(0x0C);MYUSART_SendData(PageID>>8);MYUSART_SendData(PageID);MYUSART_SendData(N>>8);MYUSART_SendData(N);temp = 0x01+0x07+0x0C+(PageID>>8)+(u8)PageID+(N>>8)+(u8)N;SendCheck(temp);data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;return ensure;}//清空指纹库 PS_Empty//功能:  删除flash数据库中所有指纹模板//参数:  无//说明:  模块返回确认字u8 PS_Empty(void){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x03);Sendcmd(0x0D);temp = 0x01+0x03+0x0D;SendCheck(temp);data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;return ensure;}//写系统寄存器 PS_WriteReg//功能:  写模块寄存器//参数:  寄存器序号RegNum:4\5\6//说明:  模块返回确认字u8 PS_WriteReg(u8 RegNum,u8 DATA){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x05);Sendcmd(0x0E);MYUSART_SendData(RegNum);MYUSART_SendData(DATA);temp = RegNum+DATA+0x01+0x05+0x0E;SendCheck(temp);data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;if(ensure==0)printf("\r\n设置参数成功!");elseprintf("\r\n%s",EnsureMessage(ensure));return ensure;}//读系统基本参数 PS_ReadSysPara//功能:  读取模块的基本参数(波特率,包大小等)//参数:  无//说明:  模块返回确认字 + 基本参数(16bytes)u8 PS_ReadSysPara(SysPara *p){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x03);Sendcmd(0x0F);temp = 0x01+0x03+0x0F;SendCheck(temp);data=JudgeStr(1000);if(data){ensure = data[9];p->PS_max = (data[14]<PS_level = data[17];p->PS_addr=(data[18]<<24)+(data[19]<<16)+(data[20]<PS_size = data[23];p->PS_N = data[25];}elseensure=0xff;if(ensure==0x00){printf("\r\n模块最大指纹容量=%d",p->PS_max);printf("\r\n对比等级=%d",p->PS_level);printf("\r\n地址=%x",p->PS_addr);printf("\r\n波特率=%d",p->PS_N*9600);}else printf("\r\n%s",EnsureMessage(ensure));return ensure;}//设置模块地址 PS_SetAddr//功能:  设置模块地址//参数:  PS_addr//说明:  模块返回确认字u8 PS_SetAddr(u32 PS_addr){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x07);Sendcmd(0x15);MYUSART_SendData(PS_addr>>24);MYUSART_SendData(PS_addr>>16);MYUSART_SendData(PS_addr>>8);MYUSART_SendData(PS_addr);temp = 0x01+0x07+0x15+(u8)(PS_addr>>24)+(u8)(PS_addr>>16)+(u8)(PS_addr>>8) +(u8)PS_addr;SendCheck(temp);AS608Addr=PS_addr;//发送完指令,更换地址  data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;AS608Addr = PS_addr;if(ensure==0x00)printf("\r\n设置地址成功!");elseprintf("\r\n%s",EnsureMessage(ensure));return ensure;}//功能: 模块内部为用户开辟了256bytes的FLASH空间用于存用户记事本,//该记事本逻辑上被分成 16 个页。//参数:  NotePageNum(0~15),Byte32(要写入内容,32个字节)//说明:  模块返回确认字u8 PS_WriteNotepad(u8 NotePageNum,u8 *Byte32){u16 temp;  u8  ensure,i;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(36);Sendcmd(0x18);MYUSART_SendData(NotePageNum);for(i=0;i<32;i++) { MYUSART_SendData(Byte32[i]); temp += Byte32[i]; }  temp =0x01+36+0x18+NotePageNum+temp;SendCheck(temp);  data=JudgeStr(2000);if(data)ensure=data[9];elseensure=0xff;return ensure;}//读记事PS_ReadNotepad//功能:  读取FLASH用户区的128bytes数据//参数:  NotePageNum(0~15)//说明:  模块返回确认字+用户信息u8 PS_ReadNotepad(u8 NotePageNum,u8 *Byte32){u16 temp;  u8  ensure,i;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x04);Sendcmd(0x19);MYUSART_SendData(NotePageNum);temp = 0x01+0x04+0x19+NotePageNum;SendCheck(temp);  data=JudgeStr(2000);if(data){ensure=data[9];for(i=0;i>8);MYUSART_SendData(StartPage);MYUSART_SendData(PageNum>>8);MYUSART_SendData(PageNum);temp = 0x01+0x08+0x1b+BufferID+(StartPage>>8)+(u8)StartPage+(PageNum>>8)+(u8)PageNum;SendCheck(temp);data=JudgeStr(2000); if(data){ensure=data[9];p->pageID =(data[10]<mathscore=(data[12]<<8) +data[13];}elseensure=0xff;return ensure;}//读有效模板个数 PS_ValidTempleteNum//功能:读有效模板个数//参数: 无//说明: 模块返回确认字+有效模板个数ValidNu8 PS_ValidTempleteNum(u16 *ValidN){u16 temp;  u8  ensure;u8  *data;SendHead();SendAddr();SendFlag(0x01);//命令包标识SendLength(0x03);Sendcmd(0x1d);temp = 0x01+0x03+0x1d;SendCheck(temp);  data=JudgeStr(2000);if(data){ensure=data[9];*ValidN = (data[10]<<8) +data[11];}elseensure=0xff;if(ensure==0x00){printf("\r\n有效指纹个数=%d",(data[10]<<8)+data[11]);}elseprintf("\r\n%s",EnsureMessage(ensure));return ensure;}//与AS608握手 PS_HandShake//参数: PS_Addr地址指针//说明: 模块返新地址(正确地址)u8 PS_HandShake(u32 *PS_Addr){SendHead();SendAddr();MYUSART_SendData(0X01);MYUSART_SendData(0X00);MYUSART_SendData(0X00);Delay_ms(200);if(USART2_RX_STA&0X8000)//接收到数据{if(//判断是不是模块返回的应答包USART2_RX_BUF[0]==0XEF&&USART2_RX_BUF[1]==0X01&&USART2_RX_BUF[6]==0X07){*PS_Addr=(USART2_RX_BUF[2]<<24) + (USART2_RX_BUF[3]<<16)+(USART2_RX_BUF[4]<<8) + (USART2_RX_BUF[5]);USART2_RX_STA=0;return 0;}USART2_RX_STA=0;}return 1;}//模块应答包确认码信息解析//功能:解析确认码错误信息返回信息//参数: ensureconst char *EnsureMessage(u8 ensure) {const char *p;switch(ensure){case  0x00:p="OK";break;case  0x01:p="数据包接收错误";break;case  0x02:p="传感器上没有手指";break;case  0x03:p="录入指纹图像失败";break;case  0x04:p="指纹图像太干、太淡而生不成特征";break;case  0x05:p="指纹图像太湿、太糊而生不成特征";break;case  0x06:p="指纹图像太乱而生不成特征";break;case  0x07:p="指纹图像正常,但特征点太少(或面积太小)而生不成特征";break;case  0x08:p="指纹不匹配!";break;//case  0x09://p="没搜索到指纹!";break;case  0x09:p="指纹不匹配!";break;case  0x0a:p="特征合并失败";break;case  0x0b:p="访问指纹库时地址序号超出指纹库范围";case  0x10:p="删除模板失败";break;case  0x11:p="清空指纹库失败";break;case  0x15:p="缓冲区内没有有效原始图而生不成图像";break;case  0x18:p="读写 FLASH 出错";break;case  0x19:p="未定义错误";break;case  0x1a:p="无效寄存器号";break;case  0x1b:p="寄存器设定内容错误";break;case  0x1c:p="记事本页码指定错误";break;case  0x1f:p="指纹库满";break;case  0x20:p="地址错误";break;default :p="模块返回确认码有误";break;} return p;}/////正点原子版权所属//AS608.h#ifndef __AS608_H#define __AS608_H#include "stdio.h"#include "stm32f10x.h" #define PS_Sta   PAin(8)//读指纹模块状态引脚#define CharBuffer1 0x01#define CharBuffer2 0x02extern u32 AS608Addr;//模块地址typedef struct  {uint16_t pageID;//指纹IDuint16_t mathscore;//匹配得分}SearchResult;typedef struct{uint16_t PS_max;//指纹最大容量uint8_t  PS_level;//安全等级uint32_t PS_addr;uint8_t  PS_size;//通讯数据包大小uint8_t  PS_N;//波特率基数N}SysPara;void PS_StaGPIO_Init(void);//初始化PA6读状态引脚u8 PS_GetImage(void); //录入图像  u8 PS_GenChar(u8 BufferID);//生成特征 u8 PS_Match(void);//精确比对两枚指纹特征 u8 PS_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p);//搜索指纹  u8 PS_RegModel(void);//合并特征(生成模板)  u8 PS_StoreChar(u8 BufferID,u16 PageID);//储存模板 u8 PS_DeletChar(u16 PageID,u16 N);//删除模板 u8 PS_Empty(void);//清空指纹库 u8 PS_WriteReg(u8 RegNum,u8 DATA);//写系统寄存器  u8 PS_ReadSysPara(SysPara *p); //读系统基本参数 u8 PS_SetAddr(u32 addr);  //设置模块地址 u8 PS_WriteNotepad(u8 NotePageNum,u8 *content);//写记事本 u8 PS_ReadNotepad(u8 NotePageNum,u8 *note);//读记事 u8 PS_HighSpeedSearch(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p);//高速搜索   u8 PS_ValidTempleteNum(u16 *ValidN);//读有效模板个数 u8 PS_HandShake(u32 *PS_Addr); //与AS608模块握手const char *EnsureMessage(u8 ensure);//确认码错误信息解析#endif

stm32f103c8t6最小系统板以及其他外设

引脚连接说明:

1.指纹模块

PA3:USART2_RX——指纹模块P4

PA2:USART2_TX——指纹模块P5

PA8:IO口——指纹模块P2

2.OLED屏幕

PB8(IIC_SCL)—OLED_SCL

PB9(IIC_SDA)—OLED_SDA

3.矩阵按键

矩阵按键1—8:PA12,PA11,PA1,AP0,PA4,PA5,PA6,PA7

4.继电器

IN—PB12

5.蜂鸣器

I/O—PB13

还有就是手工活了,硬纸板外加热熔胶枪制作的一个简易的门。

工程资料

链接:https://pan.baidu.com/s/1-zXsgLA0SEXv4uc5wmANMg
提取码:asdf

遇到的问题

1.电容式指纹模块和光学指纹模块的选择,光学指纹模块AS608更佳一点

2.继电器驱动电压有要求且不一样。注意看自己买的继电器的参数,stm32的io口最大提供3.3V电压,对于个别继电器无法驱动导致电磁锁无法正常工作

3.电磁锁的选择。有的个别的5V电压驱动的小电磁锁,无法使用继电器,用线直连可以驱动,一旦连接继电器就无法驱动了,我也不大明白为什么,所以可以买上图那种电磁锁,也更方便点

4.oled汉字中文显示

同时感谢其他博主的博客,基本上是总结了其他博主的内容,总结出了针对stm32F103

的指纹识别。

帮助最大的就是下面博主的博客。资料也是在它的基础上改的。

STM32项目设计:基于stm32f4的智能门锁(附项目视频全套教程、源码资料)_化作尘的博客-CSDN博客_基于stm32的智能门锁

小白一枚,有问题欢迎交流指正,谢谢