这星期基于STM32F103ZET6做了一个指纹识别系统,主要有:12864进行屏幕内容显示,动手做了一个4X3的独立按键板用来按键输入,指纹模块与32单片机进行串口通信,环境为Keil uVision5。其中涉及有串口通信,中断操作,eeprom存储,12864显示,以及IO口的使能初始化知识内容。
主要步骤:
(1)首先在12864上显示主界面,根据指纹模块的手册编写验证函数,输入自动验证指令,指令包校验和要算对不然不能正常工作,调用该验证函数后,若检测到所要的返回值便进入下一个界面(即成功验证),在编写验证指纹函数时,由于串口函数每次只能发送一串指令(该指令必须包含一个指纹的ID号,而每个指纹的ID都不同),所以需要对指纹模块内存储的所有指纹进行遍历,进行匹配。
UINT8 YZ()//验证指纹
{
UINT8 cRerr;
UINT8 Buf[128];
UINT16 nBufLen = 0;
UINT16 nOutTimeMS = 500;
unsigned char FingerId ;
W25QXX_Read(&FingerId,0,sizeof(FingerId)); //将eeprom内的id值(即最后一个id)读出来
for(i=1;i<=FingerId;i++)
{
iol = CommSingleInstruction(MASK_INS, 0x32, Buf, &nBufLen, Buf, &cRerr, nOutTimeMS);
if((UartRxBuff[9]==0X00)&&(UartRxBuff[10]==0X05))
{
return CMD_OK;
}
else if(i==FingerId)
{
return 0x01;
}
}
}
(2)接着按下中断按钮,进入管理员模式,在管理员模式中有四个功能选项,注册指纹,删除指纹,返回主界面和清空所有指纹,每一项功能对应手册都有各自的命令包格式和数据包格式,所以在编写函数时需要细心一些,不能输错命令和校验码。
(3)注册指纹时,指纹模块能存储该指纹的信息以及对应的指纹编号,为了使每次注册指纹编号都能有序的进行对应存储,便选择将指纹编号存入eeprom中(进行掉电保存最后一个注册的指纹ID),一有注册指纹命令便从eeprom中读出ID号(自加一)与当前指纹进行配对存入指纹模块中,并将此时的指纹编号再存入eeprom中为下一次的注册做准备。代码如下:
UINT8 CMD_Send1(UINT8 Type, UINT8 INS, UINT8 *pData, UINT16 Datalen) //注册指纹 发送命令函数
{
UINT8 cRet;
UINT16 len, nCRC;
W25QXX_Read(&FingerId,0,sizeof(FingerId)); //从第0个地址处开始读sizeof(FingerId)的长度
DelayMs(10);
MakePackageHead(UartTxBuff, Type, Datalen+1);//包头 ???DataLen + 1[INS take 1 byte length]
len = COMM_PAKGE_LEN;
UartTxBuff[COMM_PAKGE_LEN] = INS;
len += 1;
FingerId++;
UartTxBuff[COMM_PAKGE_LEN+1] = 0x00;
UartTxBuff[COMM_PAKGE_LEN+2] = FingerId; //id号
UartTxBuff[COMM_PAKGE_LEN+3] = 0x02; //录入次数
UartTxBuff[COMM_PAKGE_LEN+4] = 0x00;
UartTxBuff[COMM_PAKGE_LEN+5] = 0x20; //参数
UartTxBuff[COMM_PAKGE_LEN+6] = 0x00;
UartTxBuff[COMM_PAKGE_LEN+7] = 92+FingerId; //校验和
len += 7;
W25QXX_Write(&FingerId,0,sizeof(FingerId)); //从第0个地址处开始,写入sizeof(FingerId)长度的数据
DelayMs(10);
cRet = UartDataSend(UartTxBuff, len);
DelayMs(500);
if (cRet != 0)
{
return CMD_ERR;
}
return CMD_OK;
}
(4)删除指纹时需要自己手动按键输入想要删除的指纹编号,并将输入的数字编号经过一些算法后得到的具体值输入指令包的id号中,清空所有指纹需要按照手册上固定的命令包,数据包和结束包的格式编写串口函数,实现32和指纹模块的通信。
(5)编写main函数时,要先将时间延迟,12864的字库,中断等进行初始化,代码如下:
int main()
{
unsigned char k=0x89;
delay_init(); //时间延迟初始化
_Init(); //12864串口初始化
initinal() ; //字库初始化
W25QXX_Init(); //eeprom初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
KEY_Init(); //初始化与按键连接的硬件接口
EXTIX_Init(); //外部中断初始化
DelayMs(500);
uart_init(57600);
DelayMs(10);
while(1)
{
lcd_mesg(" 欢迎来到",0x80,12) ;
lcd_mesg(" 指纹门禁系统",0x90,14) ;
lcd_mesg(" 请按指纹开锁",0x98,14) ;
read_char=GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_15); //有指纹的时候输出高电平
if(read_char)
{
DelayMs(10);
if(read_char)
{
pp=YZ(); //验证指纹,对返回0,错误返回1
}
}
if(pp==0)
{
TransferData (0x01,0) ; //清屏
while(1)
{
lcd_mesg(" 欢迎进入",0x90,12) ;
lcd_mesg(" 我的智能家居",0x88,14) ;
}
}
}
}